Skip to main content

Troubleshooting: JavaScript – Not a Valid XSLT or XPath Function

If you have run into the “… is not a valid XSLT or XPath function” error, then chances are that you are messing with the Before Save or After Save properties on a form.

myEvolv uses XML to define forms and XSLT to transform the XML into HTML when displaying the form in the browser. When you export a form from myEvolv, you are downloading an XML document that defines the properties for all of the fields on the form and the form itself that you configured in the form designer. You can then upload that same file to another instance if myEvolv and the system will know how to create that form, generating all of the same fields and properties.

When you go to open a form to enter data, XSLT is used to take the XML ‘recipe’ for the form and convert it into HTML to display in the browser. This presents an issue when you try to store JavaScript code in the Before Save and After Save properties for a form because XSLT has some overlap with special characters in JavaScript and so unless you escape those in your JavaScript code, you XSLT will try to evaluate the code as an XSLT command rather than treat it as JavaScript code to pass along into the HTML.

When I got the error shown below, I was working on a snippet of JavaScript code for the Before Save property that would evaluate whether the start date of the service was before today’s date and if so, update the start date to be today’s date so that no service could be backdated. Part of my code included an if/then statement to check if start date was earlier than today’s date.

not-valid-xslt-function-error

Following JavaScript syntax, I wrote my conditional
if(start< today){setFormElement('udf_rx_4_svc_start', todaysDate())};
which caused the above error.

Turns out the problem was the curly brackets { and } because XSLT attempts to evaluate statements inside curly brackets and the XSLT did not contain a todaysDate() function. Luckily, there is a way to escape curly brackets in XML so that XSLT does not try to evaluate them and that is by using double curly brackets. So changing my code to
if(start< today){{setFormElement('udf_rx_4_svc_start', todaysDate())}};
did the trick. Error is gone and the form works as expected Before Save.

How To: Override a Field Value at Save

Besides the ‘On Load’, ‘On Click’, and ‘On Change’ events that myEvolv allows you to use as triggers for user defined scripts, each form itself has ‘Before Save Code’ and ‘After Save Code’ properties that also can be used to trigger scripts.  These can be useful if you want to apply some business logic to your forms in a way that is safe from modification by clinicians.  Take for example, this simple scenario:

You have a funder that wants no-show services submitted with a duration of 0 minutes.

Beyond simply instructing your clinicians to enter a ‘0’ for duration when the “No Show” checkbox is checked and crossing your fingers, you might approach the problem using the ‘On Click Script’ property for the is_noshow field.  You can write a simple script that checks if the checkbox is checked and if it is, it will put “0” in the duration field.  However, the clinicians are still able to go ahead and change that duration value to something else or even clear it out before they save the form, essentially overriding your business logic.  What would be better is for you to override their logic.  That is where the ‘Before Save Code’ and ‘After Save Code’ properties become useful.

before-save-after-save

‘Before Save Code’ fires after saving?!?

One thing that might be confusing when using these properties on your forms is understanding when the code that is associated with each property is executed.  The confusion stems from the conflation of clicking the ‘Save’ button on the form and actually executing its save algorithm.  The ‘Before Save Code’ fires after the Save button is clicked on the form but before myEvolv runs through its routines that takes the form data from your browser and enters it into the database.  ‘After Save Code’ fires after the save algorithm.  The ‘Before Save Code’ is the key to a solution to our scenario because we want to override some data on the form before myEvolv reads it into the database.

The code

if(document.getElementById('is_noshow').checked) setFormElement('duration', '00:00')

Some notes about the code

JavaScript usually likes the function body to be wrapped in curly brackets { and } but using them in ‘Before Save Code’ and ‘After Save Code’ properties throws an error related to XPath and XSLT. Leaving the brackets off does not.

Also, the second argument in the setFormElement call needs to be formatted precisely for myEvolv. When using the Duration(hh:mm) field on the form itself, if you enter a plain ‘0’, once you click out of the field, the form would resolve the value to ’00:00′. When using the ‘Before Save Code’ property, the form will not have the chance to perform that transformation so the value must be formatted properly in the code itself.

How the code works

The first part of the code is a simple if-statement to check if the is_noshow checkbox is checked. If it is, then a call is made to a Netsmart created setFormElement function that changes the duration field’s value to ’00:00′. The setFormElement function takes only two arguments: the name of the element and a value to set and can be used on any field on the form.

form-before-after

When the clinician opens the form, there will be no difference in the way that the form behaves and the clinician will be able to enter any duration he or she would like in the ‘Duration (hh:mm)’ field. Once the clinician hits the ‘Save’ button, the code will execute. If the clinician checked the “Session Not Provided” checkbox on the form (this is the label used on the is_noshow field in my example), then the value of ‘Duration (hh:mm)’ will be changed to ’00:00′ just before myEvolv runs its save routines. The clinician still will not see any difference until after the event is entered into the system. Re-opening the saved form will show that the ‘Duration (hh:mm)’ has been changed to ’00:00′ despite whatever duration had been entered by the clinician.

We are using cookies on our website

Please confirm, if you accept our tracking cookies. You can also decline the tracking, so you can continue to visit our website without any data sent to third party services.