Skip to Content

In my last Some thoughts on validations for SAP Interactive Forms. To implement validations using scripting it is often very useful to have additional data you can use (e.g. a list of valid codes, a price list, a list of discounts). Using scripts to do validations has the following advantages: you can access other fields and you can even access data. Additional data can be part of the XML data that is part of a form. And it is not necessary that all data nodes are bound to form fields. It is easily possible to define a section in your data that contains additional data that is not visible on the form it is only used by scripts. It is also possible to do nothing at all with a data node. This allows for example to include a form/process identifier in a form. Nobody can see this identifier and this identifier is used to track instances of a form. This is useful in offline scenarios when you have to process a form that is submitted back to the back-end.

Accessing data nodes is also useful when you implement calculations on you form.

Accessing data nodes

Now, I want to discuss the question on how to access a data node in a script. I’m using JavaScript in my examples. This is very easy; you just have to know how it works.

Let’s assume the data structure looks as follows:


1

The form data is part of the XFA DOM (XML Form Architecture Document Object Model) that is built for every form. The data can be found under the node “xfa.datasets.data”. To get the actual value of a node the “value” property has to be accessed. The following if-statement checks if the value of the attribute “an_attribute” is “3”.

if (xfa.datasets.data.my_data.second_node.an_attribute.value == "3") {
// do something
}

A second possibility is to use “$record” or “$data”. $record is a shortcut for “xfa.datasets.data.mydata”. “$data” is a shortcut for “xfa.datasets.data”. A script using “$record” could look like the following example:

if ($record.node.value == "1") {
  this.presence = "invisible";
}

My Access Mode and Presence of Fields on Adobe Interactive Forms of form fields explains what happens in the example above if the value of the data node is “1”. It’s no surprise the field/subform is set to be invisible. 

Let’s take a look at an Web Dynpro application. For a view that contains an Interactive Form there is a mapping defined between the view’s context and the data context for the form. It is important to look at the root node of the data view. So in the example above the my_data node is the name of the node that is the “dataSource” for the InteractiveForm UI element. The “data view” of Designer helps you to putting together the expression to address a node.

Accessing data in table-like structures

Hierarchical structures are built using nested subforms. This is also true if you build them using tables. Each subform knows its index amongst all siblings. A form field can then use a script to ask its parent (a subform) for the index. The code looks like this: “this.parent.index”.

Here’s the complete example of how to get the value for a given row in a table-like structure:

xfa.resolveNode("xfa.data.my_data.tableData[" + this.parent.index  + "].column1").value

resolveNode is a helper function that allows to evaluate SOM expressions (SOM = Scripting Object Model). It takes a SOM expression (string) as input and returns a node object. On this node object you can access the “value” property.

Conclusion

A form can contain data that is not bound to form fields. This additional data can be accessed via scripting. Advantage is that you can include data (not bound to form fields) into forms that can be used for validations and calculations. The disadvantage of accessing data from a script is that the path to the data node is contained in the script expressions or even as a parameter for resolveNode. This means when the data structure changes also the scripts have to be changed.

Remember if you are doing calculations and validations in a form you have to repeat them in the back-end to ensure that the data has not been manipulated between the end user and your back-end.

To report this post you need to login first.

14 Comments

You must be Logged on to comment or reply to a post.

  1. Sandra Rossi
    Hi Juergen,

    I spent a few days to find how we could access directly importing parameters passed by abap. I read almost all blogs, all wikis, all threads, and found the solution indirectly in 1 thread. It’s probably obvious for you and lot of people, but I’d like to share the solution in your weblog for other people like me.

    Let’s say the PDF has importing parameter I_EBELN. From javascript, you’ll get its value with $data.data.I_EBELN.value

    (the difficulty when I read your blog was that I didn’t know what my_data was; it seems that in PDF forms generated from ABAP, it’s always “data”)

    sandra

    (0) 
    1. Juergen Hauser Post author
      Hi Sandra,

      The important thing is to look at the data view in Designer since the data view shows the structure of your data and helps finding the correct expression.

      Juergen

      (0) 
      1. Sandra Rossi
        Thx Juergen. The issue I had is that when I create a form “Z_MY_PDF” via transaction SFP, the “data view” has root named “Z_MY_PDF”, that’s where I had a difficulty to understand. In fact we must ignore Z_MY_PDF name, and always consider the root name is “data”.

        About my comment, now I use $record instead of $data.data, and it works well too.

        (0) 
  2. Hemanth Nandigam
    Hi,
    Nice blog. I am working on a requirement to validate if the user has selected at least 1 check box(this is a table field) before selecting the email submit button in the offline interactive form. Implemented the logic in preSubmit event of the “Email submit button”.

    Can you please have a look at the logic mentioned in the below forum discussion link and let me know if I am missing somewhere?

    http://forums.sdn.sap.com/message.jspa?messageID=8630210#8630210

    Thanks in advance.

    Regards,
    Hemanth

    (0) 
  3. Pooja Gupta
    Hi,

    I have to access the varaible defined as the global in the interface, is the procedure the same?As I am not able to access its value .

    (0) 
    1. Juergen Hauser Post author
      Hi,

      Is the variable also available in the context?

      I suggest posting such questions in the IFbA forum to get answers faster.

      Regards,
      Juergen

      (0) 
  4. surender kumar

    Hi Hauser,

    Am trying to access the data node which is not bounded with Form Field in Print based PDF forms. but i couldn’t able to access  the value instead getting error in Debugging editor and its not working .

    I used the $record.RTEXT.value whereas RTEXT is the data node .

    GeneralError: Operation failed.

    XFAObject.RTEXT:7:XFA:data[0]:PAGE4[0]:Subform10[0]:RDB_TRT_TYP[0]:change

    Invalid property get operation; dataGroup doesn’t have property ‘RTEXT’

    Can you please suggest what is the issue.

    Thanks

    Surender

    (0) 
    1. Juergen Hauser Post author

      Hi Surender,

      You need to check your (XML) data structure. It seems like you are accessing a data node that does not exist. For a better answer you should have also added your data structure.

      Juergen

      (0) 
      1. surender kumar

        Hi Hauser,

        Thanks for suggestion, i think my form interface is an type of Dictionary based not XML Schema Based Interface.

        Below the Field i want to access which is not in depicted in PDF that means i dont want to bind in PDF forms.

        In Data view ZSPF_SERVICE_INJURY_FORM underneath IS_ ZSPF_SERVICE- > RTEXT{Name of Employee SubGroup}.

        There are some fields which is in the above structure are used in the Form Fields and its working fine.

        For ex.

        if ( data.PAGE4.Subform10.RDB_TRT_TYP.rawValue == “1” || data.PAGE4.Subform10.RDB_OFFR_WARD.rawValue == “2” )

        {

                   data.PAGE4.Subform10.TXV_WARD_ELIG.rawValue = “N/A” ;

        }

        I tried in the similar way which Sandra and you mentioned above for RTEXT fields. but its not working

        Thanks

        Surender

        (0) 
  5. surender kumar

    Thanks Hauser . Resolved.

    Below i coded like that but why Property RawValue is not working.?

    var lv_rtext = $record.IS_ZSPF_SERVICE_INJURY.RTEXT.value

    Thanks

    Surender

    (0) 

Leave a Reply