Wednesday, August 7, 2013

The Benefits of Using a Validator in XPages over using the rigid Validators

I know the Post Title might be a bit confusing, but so is the subject I am going to talk about.   The reason I am making this post is really for me, so that I don't forget how to do this.  I hope that it also might benefit others as well.   The reason that this is a confusing subject is that there is a "validator" property, and "validators" with the S that also do similar things.

Two months ago, I posted a question on Stack Overflow about trouble getting the xp:customValidator to work.   The answer that worked for me was by Paul Withers, thank you Paul if you ever read this. (My code below is a derivative of Paul's.)

Yesterday, I trying again to use one of the validators and getting frustrated with the result.  It was then that I remembered the better way of using "validator".  I have found that when I blog about something, then I own it, and am far less likely to forget how to do it.  In this post I am going to explain why I think using the validator is the best way to validate user input.

My issue started because I did not like the fact that my input fields would default to zero when bound to a managed java bean field of type double or int.   I decided that I would change the type in the bean to String, and then change my methods to use Double.parseDouble() to first convert the value to something that I can perform math on.   (If there was a better way to avoid the zero then I would like to know, please comment below)

To make this work, I first needed a xp:converter that converts the user input to String.

Without this converter you would get an exception when entering a numeric value.
I then needed to make sure that the user actually entered a number, and in my case that that number was not negative or a fraction.  This is the code I used in the validator property.

Validator code

Code Explanation

  • 'value' is something you get for free.  It is value the user entered.  I found this poorly documented.
  • The order matters, you will want to arrange the validators from general to more specific.
  • You have total control over the error message that you present to the user
  • Number() is a built in javascript function that converts a string to a number, it returns NaN if it cannot be converted.
  • The line that begins 'var msgObj' is long and includes the following line.
  • The line: this.setValid(false) prevents the submit.
  • I could combine these three statements into one message if I choose, but I prefer to give the user a message that tells them exactly what they are doing wrong.


So why use the Validator over the preset Validators

  • More Control:  You can make them fire in the order that makes sense to you.
  • You can show whatever error message you want.   The preset Validators sometimes decide for you.  In one case, it ignored the 'message' I put in, and still gave it's own.
  • You have unlimited flexibility in the conditions you want to validate.
  • The customValidator under the validators in unreliable and shouldn't be used IMO
NOTE:  For some reason you cannot recreate a validator that does the same thing as validateRequired.  You will have to use the global function.  They work together just fine.




UPDATE:

I didn't mention that with my examples, but I was also using a xp:validateRequired.  I didn't think to mention it.  I have discovered that when I remove that, the validator never fires when using Chrome.  It works fine on Firefox and IE, but not in Chrome.  If anyone has any clues why, then please comment or contact me directly at zavocki@hotmail.com.

The fix for this was to remove type="number".  It has something to do with the nice helper arrows that Chrome presents.  I would like to figure out how to use this attribute so mobile users see the right keyboard, perhaps some jQuery is in order.

2 comments:

  1. Steve, not sure if you have tried the validateExpression validator. That allows both CSJS and SSJS code to validate. Might work better than the custom validator.

    Howard

    ReplyDelete
  2. Howard, I haven't played with that type, I will have to check it out.

    ReplyDelete