Expand my Community achievements bar.

Guidelines for the Responsible Use of Generative AI in the Experience Cloud Community.

How to dynamically get the SOM expression of a field?

Avatar

Former Community Member

As a follow up to the note below, I would really appreciate any help as of how to get the SOM expression of a field dynamically, by this, I mean how to get the SOM expression of a field at running time using JavaScript.

Thanks,

Isis

-----------

That does make things clearer.  You will have to save the change  information in the XML.  I realize that you don't want to save an xml  node for every field, but there is a better way.  You can use scripting  to add data nodes to the XML data in the form.  I'm thinking of the  following:

Include an empty container node in your XML schema: <HighlightedFields></HighlightedFields>

When  a field is changed, in the field's change event call a common script:  HighlightChangedField, passing in the object.  The script will highlight  the field (set the border a certain color or whatever).  It will also  add node underneath the HighlightedFields data node with the SOM  expression of the field.  The SOM expression is the "path" of the object  in the form heirarchy, sort of like an xpath.  So if you have a subform  named Subform1 and you change the Name and Address textfields, you  might end up with something like:

<HighlightedFields>

    <HighlightedField>

        <SOMExpression>xfa[0].form[0].myform[0].Subform1[0].Name[0]</SOMExpre ssion>

     </HighlightedField>

    <HighlightedField>

        <SOMExpression>xfa[0].form[0].myform[0].Subform1[0].Address[0]</SOMEx pression>

     </HighlightedField>

</HighlighedFields>

The  upside of this is that you only store XML nodes for what is changed  instead of needing a specific XML node for each field.  The downside is  that you will need a call to the common script in every field's change  event: HighlightChangedField(this);

Now, to make this work  when a form is loaded the next time, in the initialize event at the  topmost subform in the hierarchy you add a script that walks the  HighlightedFields data node, and for each HighlighedField entry you  highlight the contained object.  You can get a reference to an object  using its SOM expression, so just take the SOM expression from each  entry and do an xfa.resolveNode(SOMExpression) to get the object, then set whatever attributes you want to highlight the field.

The  big issue I see with this would be if you have dynamically added  objects on your form.  In that case you would probably need to store the  instance index along with the SOM expression for each changed object,  then use that instance number when highlighting on form load.

3 Replies

Avatar

Level 6

Objects have a "somExpression" property on them.  For example, in javascript you can use:

    var exp = this.somExpression;

Avatar

Level 10

You can use the command "this.somExpression" to get the SOM Expression of the current field at run time..

For example if you want to pass the somExpression of the current field to your function, 

     Place this in the change event of your field.

     HighlightChangedField(this.somExpression);

Thanks

Srini

Avatar

Level 6

As a follow-up, I had said I would try to put together an example for you.  The setting of the change indications and the highlighting of the fields is not a problem, but I did have an issue that perhaps one of the experts on the forum can help with:

The problem is how to detect a change in a text field without a lot of overhead.  You can't just place a call to the highlight method in the Exit event without checking for a change, since the user can just tab from field to field without changing anything. Unfortunately the properties that show the old text and new text of a field are not valid on the Exit event.  An alternative is to use the Change event, but with a text field the event fires for every character typed.  This seems like a lot of extra processing..

Anyone know a better way?  I went as far as using the extras collection on fields to hold the last value, but that adds a lot of complexity since it needs to be set to the initial raw value when the form is first loaded. I'd like to find a solution that doesn't require a lot of code to be added to every field on the form.