[ 
https://issues.apache.org/struts/browse/SHALE-490?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Jeff Tsay updated SHALE-490:
----------------------------

    Attachment: validateUtilities.js
                taglib.tld
                ValidatorTag.java

> Want alternative ways of informing user of validation failure
> -------------------------------------------------------------
>
>                 Key: SHALE-490
>                 URL: https://issues.apache.org/struts/browse/SHALE-490
>             Project: Shale
>          Issue Type: Improvement
>          Components: Validator
>    Affects Versions: 1.0.4
>         Environment: Any
>            Reporter: Jeff Tsay
>         Attachments: CommonsValidator.java, taglib.tld, validateUtilities.js, 
> ValidatorScript.java, ValidatorTag.java, ValidatorVarTag.java
>
>
> I'd like to see the ability to override the validation error 
> handler. Currently, with the default validatorUtilities.js, whenever a 
> validation error occurs, an alert is displayed. To me that is a bit 
> unpolished; I'd rather see some message below the input field that has 
> an error. Although it's easy enough to replace validatorUtilities.js, 
> jcv_handleError() simply doesn't get enough information in its arguments 
> to do much with the DOM tree, unless the ID's of the elements to replace 
> are hardcoded. It would be good also to let the user supply his own 
> error handling script in the JSF tags, instead of messing with replacing 
> validatorUtilities (which would be apply across the entire web app 
> anyway). Any ideas on how to do this? Is anyone else interested in 
> getting rid of alert()?
> ---
> April 21, 2008
> I have a solution that works. I add two properties, clientErrorHandler and 
> clientErrorHandlerData to the ValidatorScript tag and the ValidatorTag. In 
> the Javascript validation routines in Commons Validator, jcv_handleError() is 
> always called with 2nd element of 
> 2nd element of the 3 element array representing a field to be validated.  To 
> avoid changing the Common Validator code, I added the clientErrorHandler and 
> clientErrorHandlerData properties to the 2nd element. The 2nd element is 
> usually the error message, so I moved that into a property of a hash becomes 
> the new 2nd element. So the relevant code in ValidatorScript is:
> BEFORE
>      writer.write("new Array(\"");
>       writer.write(id);
>       writer.write("\", \"");
>       writer.write(v.getErrorMessage(context, validatorAction, localVars));
>       writer.write("\", new Function(\"x\", \"return {");
> AFTER
>      writer.write("new Array(\"");
>       writer.write(id);
>       writer.write("\", {\"msg\":\"");
>       writer.write(v.getErrorMessage(context, validatorAction, localVars));
>       writer.write("\"");
>       
>       String clientErrorHandler = v.getClientErrorHandler();
>       
>       if (clientErrorHandler != null) {
>           writer.write(",\"errorHandler\":\"");
>           writer.write(clientErrorHandler);
>           writer.write("\"");
>       }
>       
>       String clientErrorHandlerData = v.getClientErrorHandlerData();
>         
>       if (clientErrorHandlerData != null) {
>          writer.write(",\"errorHandlerData\":\"");
>          writer.write(escapeJavascript(clientErrorHandlerData));
>          writer.write("\"");
>       }
>        writer.write("}, new Function(\"x\", \"return {");
> Then I needed to change validatorUtilities.js so that the error handler can 
> get the old message and also call the client error handler routines if 
> defined:
> BEFORE:
>  /**
>    * Handle error messages.
>    * @param messages Array of error messages.
>    * @param focusField Field to set focus on.
>    */
>   function jcv_handleErrors(messages, focusField) {
>       if (focusField && focusField != null) {
>           var doFocus = true;
>           if (focusField.disabled || focusField.type == 'hidden') {
>               doFocus = false;
>           }
>           if (doFocus && 
>               focusField.style && 
>               focusField.style.visibility &&
>               focusField.style.visibility == 'hidden') {
>               doFocus = false;
>           }
>           if (doFocus) {
>               focusField.focus();
>           }
>       }
>       alert(messages.join('\n'));
>   }
> AFTER:
> /**
>    * Handle error messages.
>    * @param instructions Array of instructions on how to handle
>      validation errors.
>    * @param focusField Field to set focus on.
>    */
>   function jcv_handleErrors(instructions, focusField) {
>       if (focusField && focusField != null) {
>           var doFocus = true;
>           if (focusField.disabled || focusField.type == 'hidden') {
>               doFocus = false;
>           }
>           if (doFocus && 
>               focusField.style && 
>               focusField.style.visibility &&
>               focusField.style.visibility == 'hidden') {
>               doFocus = false;
>           }
>           if (doFocus) {
>               focusField.focus();
>           }
>       }
>       
>       var anyHandlersCalled = false;
>       var messages = [];
>       
>       for (var i = 0; i < instructions.length; i++) {
>         var instruction = instructions[i];
>         
>         var msg = instruction['msg'];
>         messages.push(msg);
>         
>         var handlerName = instruction['errorHandler'];
>       
>         if (handlerName) {
>             var handlerDataString = instruction['errorHandlerData'];
>           
>             if (!handlerDataString) {
>                handlerDataString = "{}";
>             }
>           
>             eval(handlerName + '(' + handlerDataString + ', focusField, 
> msg);'); 
>           
>             anyHandlersCalled = true;
>         }      
>       }
>       
>       if (!anyHandlersCalled)
>       {
>           alert(messages.join('\n'));
>       }
>   }
> So the alert is only triggered if no error handler for any of the error 
> fields was defined (so old pages will continue to work as usual).
> The errorHandlerData property is meant to be flexible, in that it can 
> represent a variable reference, a JSON expression, or a list of expressions. 
> Examples could be "'emailerrormsgid'" or "{'id' : 'someid'}" or 
> "'emailmsgid', foo" (where foo would be variable defined in the Javascript 
> for the page.
> The error handler function gets the errorHandlerData as the first 
> argument(s), the field to focus on (from which it can pull out the value that 
> caused the error), and the error message. I think that should be enough 
> information to handle the error.
> An example usage would be:
> <val:commonsValidator type="required" 
>    arg="#{commonBundle.username}" server="true" client="true"
>    clientErrorHandler="handleValidationError"  
> clientErrorHandlerData="'usererrorid'" /> 
> <div id="usererrorid" />
> <script>
> function handleValidationError(id, field, msg)
> {
>   var d =  document.getElementById(id);
>   d.innerHTML = '<p>' + msg + '</p>';
> }
> I will attached the changed files (based on Shale 1.0.4). Please review.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to