[ https://issues.apache.org/struts/browse/SHALE-490?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Jeff Tsay updated SHALE-490: ---------------------------- Attachment: ValidatorVarTag.java ValidatorScript.java CommonsValidator.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.