This Sample shows how one can create a FormPart that contains a table that displays a list of those items that currently fail validation in any form.
The sample FormPart was designed to be able to be added to any XFDL 8.0+ form (IBM Forms 4.0). There is only one requirement. Each item that has validation on it, must have a unique xforms:id specified. This is different than the items sid. The xforms:id is needed so that the "Goto Item" button can function. The button uses the xforms:setfocus action to be able to give focus to the item in error. the xforms:setfocus action is fully supported in Webform Server and Viewer, so it's a best practice to use this action over any XFDL way of changing focus. If the item in error exists on another page, the xforms:setfocus action will automatically navigate to that page as well.
There is a new function in IBM Forms 4.0 called checkValidity that is better at checking all aspects of an IBM Form for validation. It checks XFDL validation rules as well as XForms based validation rules, and it provides a greater set of functionality than the old checkValidFormats function.
The checkValidity fucntion is documented here: http://www-10.lotus.com/ldd/lfwiki.nsf/dx/checkValidity_XFDL_8
The sample FormPart has a Validate button that calls checkValidity as follows:
The result of the above checkValidity call is a space delimited list of XFDL references to the items in the form that fail validation such as: "PAGE1.FIELD7 PAGE2.myCombo".
The compute takes the result of the checkValidity call and stores it into a ERROR_LOGIC instance as follows:
set('instance("ERROR_LOGIC")/Errors', checkValidity("UI-validation report-all"), '', 'xforms') : ''
There's a hidden ERRORS1 field bound to the /Errors element that has a xforms:value-change-event that parses the space delimited list of XFDL references and for every reference, it creates a new row in the ERROR_LIST instance. It then stores the XFDL reference in the new row. So if checkValidity returns 8 references, the ERROR_LIST table should contain 8 rows.
So now we have a table where each row has an XFDL reference to an item in error. This reference is stored in a hidden field called ITEMREF. Since we have the XFDL reference we can query the items in question for further information. There's 2 more pieces of information we need. First, an error message to display in the table, and secondly, the xforms:id of the item (so that our "Goto Item" button can work).
Error messages are stored in many different places. The sample FormPart looks at the xforms:help and the XFDL format[constraint][message] - if it finds text in either of those locations it adds it to the table.
Here's a portion of the compute that does this. It uses the XFDL get() function as follows:
get(ITEMREF.value +. '.format[constraints][message]')
The xforms:id is always found as an attribute inside the xforms control (xforms:input, xforms:textarea, xforms:select, etc). The FormPart is designed to work with any xforms based item that can fail validation. It uses the getAttr() function to retrieve the xforms:id of the item in error:
getAttr(ITEMREF.value +. '.xforms:input', 'array', 'xforms:id')
The xforms:id is then stored inside the ERROR_LIST table in the XFormsID element. The "Goto Item" button then uses the xforms:setfocus action but it uses the XFormsID to figure out which xforms:id to give focus to. It does this as follows:
The sample form that uses the FormPart is attached and called: ErrorTableSample.xfdl
The FormPart itself is two files (the .xfr and .properties files)- simply place these two files in your FormParts directory if you wish to make modifications to it: