Expand my Community achievements bar.

Designer datamodel questions

Avatar

Former Community Member
I've got a couple of questions about how to do a few tasks in Designer. First, a little background:<br />I've got a dataconnection called "report_data" that's derived from and xml schema. The structure of the schema is somehing like this: <br /><report><br /> <job_description><br /> <name/><br /> <start_date/><br /> <end_date/><br /> </job_description> <br /> <task><br /> <name/><br /> <description/><br /> <resource> <br /> <name/><br /> <cost/><br /> </resource><br /> <subtask><br /> <name/><br /> <description/><br /> <resource> <br /> <name/><br /> <cost/><br /> </resource><br /> </subtask><br /> <task><br /></report><br /><br />a report has a single jobdescription, and multiple tasks. Each task has a name and decription, multiple resources, and multiple subtasks. Each subtask has a name and description, and multiple resources.<br /><br />I've designed a report entry form, with multiple subforms for job_description, tasks, resources, and subtasks. I've then bound these subforms to the datamodel. This is all good and works. The problems start occuring when I want this form to be dynamic. The Task subform has a button "add_new_task", which adds a new task to the report. It does this by calling a function "add_new_task()" in a script object. The function is as follows:<br />function add_new_task(){<br /> var t_node = xfa.datasets.dataDescription.report.task.clone(1);<br /> t_node.resolveNode("name").value = "task " + (xfa.record.resolveNodes("task[*]").length + 1).toString();<br /> xfa.record.nodes.append(t_node);<br /> xfa.form.remerge();<br />}<br />This function appears to work, new instances of the task subform are appended to the document. <br /><br />The task subform also contains subtask subforms. They are added with a button "add_new_subtask", that calls a function "add_new_subtask(task)". the function is as follows:<br />function add_new_subtask(task){<br /> var st_node = xfa.datasets.dataDescription.report.task.subtask.clone(1);<br /> st_node.resolveNode("name").value = "subtask " + (xfa.record.resolveNodes("subtask[*]").length + 1).toString();<br /> task.nodes.append(s_node);<br /> xfa.form.remerge();<br />}<br /><br />The button click function is:<br />scripts.add_new_subtask(xfa.record.task);<br /><br />Resources work in a similar way.<br /><br />The problem is now that when I try to create subtasks, they are appended to the initial task, not the task associated with the current record. Same thing for Resources.<br /><br />Doesn't xfa.record refer to the current record? If not, how to I determine the current record? xfa.dataWindow.currentRecordNumber is always returning 0. I'm assuming that's because there is only 1 instance of the report. How do I determine the record associated with a given subform? Is there a better way than using the index of the subform and getting the record with the same index?
6 Replies

Avatar

Level 4
I think you're going about this in the wrong way. You should be using the instance manager to add new tasks.



Thom Parker

WindJack Solutions


www.windjack.com

Avatar

Former Community Member
I looked at doing that, but it seemed kinda, unclean? But maybe that's just me coming from a MVC background. The main problem I ran into when using the instance manager was creating the instances. The only way I seemed to be able to create and new instance was by calling _Task.addInstance(0), but what about if there were 0 instances to begin with? How would I create an Task subform without having at least one? In my example (although I didn't mention it), Resources are optional, how do I create the first Resource SubForm with addInstance()?

Avatar

Former Community Member
As Thom suggested, I believe you should be using the Instance Manager to accomplish what you're trying to do. Going into the data sets will get you into trouble because things won't work the way you expect them to. The Instance Manager was designed to do exactly what you're attempting to do.



You don't need to have any existing instances of a dynamic subform in order to use its special underscore-prefixed Instance Manager object: If you have a dynamic subform (a subform set to repeat for each data record and which is located inside a flowed subform) named "Task", you always have access to a "_Task" object for the Task subform's Instance Manager. From there, you can call _Task.addInstance(0) to add an instance. You can also call _Task.count to determine the current number of existing instances.



Note that the parameter you pass to the addInstance method doesn't have anything to do with the instances. It's actually a true/false value (where 0 is implicitly converted into "false") which specifies whether the new instance should be merged with the current data model. This is only useful (i.e. you should only set it to true) if you have more data records merged into your form than the number which you're displaying (which is rare -- it would only happen if you scripted your form only to load part of the data that was merged into it).



Stefan

Adobe Systems

Avatar

Former Community Member
Wow, that was so much easier then what I was trying to do.

But I still wonder how to determine the record associated with a given Subform. While the addInstance method works (thanks), I'd still like to be able to modify the data model directly. I'm certain this is doable, and it seems more in line with the idea of seperating data from presentation.



Another question. How would I create bookmarks for newly created items?

Avatar

Former Community Member
user_u@adobeforums.com wrote:

> Wow, that was so much easier then what I was trying to do.

> But I still wonder how to determine the record associated with a given Subform. While the addInstance method works (thanks), I'd still like to be able to modify the data model directly. I'm certain this is doable, and it seems more in line with the idea of seperating data from presentation.

>

> Another question. How would I create bookmarks for newly created items?



To get the data record associated with the subform (or any form

element), you would use the 'datanode' property.



Justin Klei

Cardinal Solutions Group

www.cardinalsolutions.com

Avatar

Former Community Member
To determine the instance of the record associated with a given subform, you can get the subform's
index property value. Since new instances are created with the same name as siblings of one another, they end-up getting index numbers in order to make them unique.



For example, if you create a new instance of the Task subform, you'll have "Task[0]" and "Task[1]" where
this.index will be 0 or 1. If it's an object parented to the Task subform which needs to know the instance of the Task subform/record in which it occurs, you can use the
parent property to drill up to the Task subform which contains the object in question and then get its index property value.



Creating bookmarks is a little more complicated. Unfortunately, XFA doesn't support bookmarks so you have two options:







  1. Use the xfa.host.setFocus("field name") method to set focus, when the user clicks a button, to a field somewhere on the form to have Acrobat automatically scroll the field in view and set focus to it (see post #6 of the
    Links Within PDF thread for an example); or





  2. Use the
    target property of the event object you get in an XFA event script to access the Acrobat Document object and then programmatically add bookmarks to the form (but
    this will only work if the form is viewed using Acrobat):



    event.target.bookmarkRoot.createChild("Next Page", "this.pageNum++");







I'm not familiar enough with creating bookmarks in Acrobat to elaborate further on the subject but you can read more about it in the
Acrobat JavaScript Scripting Reference.



I hope this helps!



Stefan

Adobe Systems