[
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.