Expand my Community achievements bar.

Don’t miss the AEM Skill Exchange in SF on Nov 14—hear from industry leaders, learn best practices, and enhance your AEM strategy with practical tips.
SOLVED

Trying to import XML into PDF subform

Avatar

Level 2

I have a very large form where the first page is pre-populated with data from a livecycle service, but then the users want to import an xml file to populate the data in the rest of the form.  If I use the xfa.host.importData() it imports the xml but overwrites all the pre-populated data.  If there is a default value specified for a field, it resets it to the default value.

Is there a way to control which part of the form is updated by the import?  Or is there a way to protect the pre-populated data so that it is not overwritten?  I have tried setting the fields as protected, readOnly, nonInteractive, etc. but it doesn't seem to matter.  I also thought about trying to dynamically set the defaultValue properties but this doesn't appear to be supported.

I've looked at the loadXML method as well, but not sure how to implement - or if that is even a feasible option with this use case. 

I'm sure it can be accomplished if we write a script to parse the xml data manually into each field, but there are several hundred fields so I'm hoping there's a better way... Any suggestions?

Thanks!

1 Accepted Solution

Avatar

Correct answer by
Level 8

I remember a client asking me something like this once but being too busy and it having low priority, I decided to shelf it.

Now that I'm not busy, I'm glad I ran into your question and took a couple hours to whip this up. Here's how the script works:

1) The form saves the current xml of the entire form in a global variable

2) It then prompts the user for the xml to import into the form. Overwriting all data in the form

3) Form saves the xml of just the subform for which the newly imported data applies to into another variable

4) Reloads the saved xml from the first variable just before the import occured

5) Then uses the second variable with the subform data and overwrites the subform

The following code also makes a few assumptions:

1) Your form is bound to a schema

2) Only subforms can be used as parameter to the mergeData function not fields

3) The subform used must itself be bound to a data node. Not just the fields it contains.

Put this in the click even of your 'Import' button:

//Save the current state of the form in a global Acrobat variable
global.formXML = sanitizeData(xfa.datasets.data.saveXML('pretty'));
//Show the import XML dialog
xfa.host.importData();

//Removes the xml header
function sanitizeData(xfaData) {
xfaData = xfaData.replace(/<\?xml\sversion="1.0"\sencoding="UTF-8"\?>/,"");
    return xfaData;  
}

Because the form requires time to merge the data before execution is continued, the following must be put in the form:ready event:

if (typeof(global.formXML)!='undefined')
mergeData(YourSubformHere);//Enter the SOM expression of the subform you want to import

function mergeData(oSubform){
//Save the subforms data
var subformXML = sanitizeData(xfa.datasets.data.resolveNode(oSubform.dataNode.somExpression).saveXML('pretty'));
//reload the entire forms data from the xml import in the click event
xfa.datasets.data.loadXML(global.formXML,1,1);
//global variable no longer needed
delete global.formXML;
//Load the new subform data stored in variable subformXML
xfa.datasets.data.resolveNode(oSubform.dataNode.somExpression).loadXML(subformXML,1,1);
xfa.form.remerge();
}

//Removes the xml header
function sanitizeData(xfaData) {
xfaData = xfaData.replace(/<\?xml\sversion="1.0"\sencoding="UTF-8"\?>/,"");
    return xfaData;  
}

A lot to take in but I hope it solves your problem.

Let me know.

Kyle

View solution in original post

4 Replies

Avatar

Correct answer by
Level 8

I remember a client asking me something like this once but being too busy and it having low priority, I decided to shelf it.

Now that I'm not busy, I'm glad I ran into your question and took a couple hours to whip this up. Here's how the script works:

1) The form saves the current xml of the entire form in a global variable

2) It then prompts the user for the xml to import into the form. Overwriting all data in the form

3) Form saves the xml of just the subform for which the newly imported data applies to into another variable

4) Reloads the saved xml from the first variable just before the import occured

5) Then uses the second variable with the subform data and overwrites the subform

The following code also makes a few assumptions:

1) Your form is bound to a schema

2) Only subforms can be used as parameter to the mergeData function not fields

3) The subform used must itself be bound to a data node. Not just the fields it contains.

Put this in the click even of your 'Import' button:

//Save the current state of the form in a global Acrobat variable
global.formXML = sanitizeData(xfa.datasets.data.saveXML('pretty'));
//Show the import XML dialog
xfa.host.importData();

//Removes the xml header
function sanitizeData(xfaData) {
xfaData = xfaData.replace(/<\?xml\sversion="1.0"\sencoding="UTF-8"\?>/,"");
    return xfaData;  
}

Because the form requires time to merge the data before execution is continued, the following must be put in the form:ready event:

if (typeof(global.formXML)!='undefined')
mergeData(YourSubformHere);//Enter the SOM expression of the subform you want to import

function mergeData(oSubform){
//Save the subforms data
var subformXML = sanitizeData(xfa.datasets.data.resolveNode(oSubform.dataNode.somExpression).saveXML('pretty'));
//reload the entire forms data from the xml import in the click event
xfa.datasets.data.loadXML(global.formXML,1,1);
//global variable no longer needed
delete global.formXML;
//Load the new subform data stored in variable subformXML
xfa.datasets.data.resolveNode(oSubform.dataNode.somExpression).loadXML(subformXML,1,1);
xfa.form.remerge();
}

//Removes the xml header
function sanitizeData(xfaData) {
xfaData = xfaData.replace(/<\?xml\sversion="1.0"\sencoding="UTF-8"\?>/,"");
    return xfaData;  
}

A lot to take in but I hope it solves your problem.

Let me know.

Kyle

Avatar

Level 2

That's fantastic - thanks!  Can this be modified to merge more than one subform?  

Avatar

Level 8

Replace what you have in the form:ready event with this:

if (typeof(global.formXML)!='undefined')
mergeData(YourSubformA,YourSubformB);//Enter the SOM expressions of the subforms you want to import separated by commas

function mergeData(/*Subform1, Subform2...*/){
var subformXML=[];
for (var a=0;a<arguments.length;a++){
  //Save the subforms data
  subformXML[a] = sanitizeData(xfa.datasets.data.resolveNode(arguments[a].dataNode.somExpression).saveXML('pretty'));
}
//reload the entire forms data from the xml import in the click event
xfa.datasets.data.loadXML(global.formXML,1,1);
//global variable no longer needed
delete global.formXML;
//Load the new subform data stored in variable array subformXML
for (a=0;a<arguments.length;a++){
  xfa.datasets.data.resolveNode(arguments[a].dataNode.somExpression).loadXML(subformXML[a],1,1);
}
xfa.form.remerge();
}

//Removes the xml header
function sanitizeData(xfaData) {
xfaData = xfaData.replace(/<\?xml\sversion="1.0"\sencoding="UTF-8"\?>/,"");
    return xfaData;  
}

Kyle

Avatar

Level 2

Hi,

I read and tried this solution, but it's not working, but I might doing something wrong.

Question: that form ready event should this to be placed on the button field or on the form root form ready event.

I tried both, but neither was working.

Please let me know.

Regards,

Ed Boon

Visioned.net