PDA

View Full Version : Simple Form Validation


antun
09-17-2003, 10:22 AM
Here's an easy way of validating a form on the client in Laszlo. First we create a custom text field component with a gray background, that has the ability to turn red on command. We also give it a required attribute, based on which it registers itself with an instance of a formvalidator class (that we also need to write). The formvalidator class is just an abstract object that adds fields to a list of fields to check. Then when its validate() method is called, it loops through them and calls their color-changing method if they are empty (as well as returning false).


<canvas debug="true">
<debug x="150" />

<!-- Text field with a black border -->
<class name="mytextfield" width="140" height="16" bgcolor="0x7E7E7E">
<attribute name="required" value="false" />
<attribute name="errorColor" type="number" value="0xff0000" />
<attribute name="validator" value="null" />
<inputtext name="textField" width="${parent.width-2}" align="center"
height="${parent.height-2}" valign="middle"
bgcolor="white" />

<method event="oninit">
if ( this.required ) {
this.validator.addField( this );
}
this.originalBackgroundColor = this.bgcolor;
</method>

<method name="getText">
return this.textField.getText();
</method>

<!-- Highlight the border of the field the specified error color -->
<method name="showError">
this.setAttribute( 'bgcolor', this.errorColor );
</method>

<!-- Return the background color of the field to show it's
filled out -->
<method name="showOK">
this.setAttribute( 'bgcolor', this.originalBackgroundColor );
</method>
</class>

<!-- Abstract validator that checks required fields -->
<class name="formvalidator" extends="node">
<method event="oninit">
this.fieldsToCheck = new array();
</method>

<!-- Register a field to be checked by this at a later time -->
<method name="addField" args="f">
this.fieldsToCheck.push( f );
</method>

<!-- Check all registered fields -->
<method name="validate">
<![CDATA[
var isValid = true;
for ( var i=0; i<;this.fieldsToCheck.length; i++ ) {
var field = this.fieldsToCheck[i];
if ( field.getText() == '' ) {
isValid = false;
field.showError();
} else {
field.showOK();
}
}
return isValid;
]]>
</method>
</class>

<formvalidator name="myValidator" />


<simplelayout axis="y" spacing="4" />

<!-- This field will be required: -->
<mytextfield name="foo" required="true"
validator="$once{canvas.myValidator}" />

<!-- This field is not required -->
<mytextfield name="bar" />

<button>Check form
<method event="onclick">
if ( myValidator.validate() ) {
debug.write( 'Everything OK - the user filled out fields' );
} else {
debug.write( 'Required field empty' );
}
</method>
</button>
</canvas>


Enjoy!

chrislyman
01-21-2005, 10:02 AM
Hi All,

I had to come up with a combobox version of this and I thought it might be useful to post it here. Use the same myValidator and button code.

Here's the class:


<class name="mycombobox" bgcolor="0x7E7E7E">
<attribute name="required" value="false" />
<attribute name="errorColor" type="number" value="0xff0000" />
<attribute name="validator" value="null" />
<attribute name="width" value="200" />
<attribute name="height" value="22" />
<attribute name="editable" value="false" />
<attribute name="myDataPath" value="''" />
<combobox name="dropBox" width="${parent.width-3}" align="center" yoffset="-.5"
valign="middle" bgcolor="white" editable="${parent.editable}">
<textlistitem datapath="${parent.parent.myDataPath}" text="$path{'@value'}" value="$path{'@value'}" />
</combobox>

<method event="oninit">
if ( this.required ) {
this.validator.addField( this );
}
this.originalBackgroundColor = this.bgcolor;
</method>

<method name="getText">
return this.dropBox.getText();
</method>

<method name="showError">
this.setAttribute( 'bgcolor', this.errorColor );
</method>

<method name="showOK">
this.setAttribute( 'bgcolor', this.originalBackgroundColor );
</method>
</class>


You can invoke it with:


<mycombobox id="contactState" width="50" editable="false" myDataPath="'states:/state/'" required="true" validator="$once{canvas.myValidator}" />


As you can see, it uses a dataset. Mine looks like:


<dataset name="states">
<state value="" text="Blank"/>
<state value="AL" text="Alabama"/>
<state value="AK" text="Alaska"/>
<etc>
</dataset>

dbuchal
11-01-2005, 07:56 AM
What if the user enters a field with nothing but spaces?

Is there any way to perform a trim?
I know that regular expressions are not supported.

This poses a huge problem when it comes to validating form data.

Dan

d~l
11-01-2005, 11:46 AM
I have not tested this .. but could you try passing each form field for validation to an external regexp javascript function located in openlaszlo parent HTML wrapper ..

using LzBrowser.loadJS('regexp_function_name');

See here for regexp in javascript. (http://www.regular-expressions.info/javascript.html)

dbuchal
11-01-2005, 12:04 PM
I had that idea as well, but I have read that IE produces a clicking sound when loadJS is called.

This results in a click for every field you want to check.

I also wasn't quite able to figure out the best method of returning the result. I am guessing you would have to return each fields validation (or trim) to a seperate canvas attribute and then have a delegate waiting for that value. It doen't seem like a very clean way of doing things if I am correct about that.

Due to a tight deadline I chose to go with server side validation for the time being, however client-side would be preferred.

Dan

d~l
11-01-2005, 12:20 PM
I am using LzBrowser.loadJS() in IE 6 for another demo .. and no clicks heard yet.

dbuchal
11-06-2005, 03:12 PM
I did a quick test of using loadJS to call a javascript function which just sets a variable.

I did notice a click. It is the same click in IE that I hear when clicking on a link or button.

It does not appear that multiple clicks are produced so I am willing to overlook the one click the users may possibly hear. If I had to guess, I would say that most of the users will not have speakers installed (or turned on) anyway.

I will investigate this further and post an example of my client-side JS validation as soon as I get it working.

d~l
11-07-2005, 01:25 AM
You are right .. there is a click .. I just had the volume turned down!

jmo
11-11-2005, 01:49 PM
Hello,

I think in the original post we have to replace this line
for ( var i=0; i<;this.fieldsToCheck.length; i++ ) {
by
this one
for ( var i=0; i<this.fieldsToCheck.length; i++ ) {

And when I try this example with LPS3.1 I have this warnings

call to undefined function 'array'
reference to undefined property 'fieldsToCheck'
...

So I can't try this example, Can you explain me ?

JMO

togawa
11-23-2005, 06:39 AM
see also this thred.

[client-side Form Validator]
http://www.laszlosystems.com/developers/community/forums/showthread.php?s=&threadid=4508

jmo
11-23-2005, 09:58 AM
Thanks,

I will read this.

ptw
11-30-2005, 05:03 AM
Originally posted by dbuchal
What if the user enters a field with nothing but spaces?

Is there any way to perform a trim?
I know that regular expressions are not supported.


someString.split(" ").join("") will remove all whitespace. So long as you don't permit multi-word answers, that could suffice.

explorer
06-09-2006, 07:54 PM
This looks like what I have been looking forward, and for a newbie like my self it seems straight forward enough to be a good teaching tool.

Unfortuantely I can not get it to work. I noticed that this was posted over 4 years ago. AUTUN is there anyway you could post an update code snipplet to work with the latest version of Laszlo?

Unless I am doing something wrong, Laszlo does not seems to like the "array()" or ".push()" keywords that are in there.

Thanks.

ptw
06-10-2006, 07:07 AM
When this example was written, LZX code was case-insensitive. It is now case-sensitive. Change `array` to `Array`.

noor
06-20-2006, 02:37 AM
[QUOTE]Originally posted by dbuchal
[B]What if the user enters a field with nothing but spaces?

You may try something like:

<script>
function trimString(stringToTrim){
if(stringToTrim.length>0){
var firstChar = stringToTrim.charAt(0);
if(firstChar==' '){
stringToTrim = stringToTrim.substring(1,stringToTrim.length);
return trimString(stringToTrim);
}else{
return stringToTrim;
}
}else{
return stringToTrim;
}
}
</script>


And call this in the validate method as:

var mytext = field.getText();
mytext = trimString(mytext);

explorer
06-20-2006, 07:41 PM
Thanks "PTW", changing "array" to "Array" and "debug" to "Debug" did the trick!

zalex
07-18-2006, 08:23 AM
HI, i've try this form, but when i click on the check button, nothing happen... The debug window doesn't show up. I tried Debug and debug.

The combobox doesn't work either, i use the same path but the list doesn't display the text.
And finally the validator doesn't chnage the bgcolor !

Can somebody help me please ?

explorer
07-18-2006, 07:38 PM
Zalex,

This is what I put together from the orginal source code and then the changes recommended in proceeding thread. This should work for you, if not let us know.

-Explorer

zalex
07-19-2006, 01:14 AM
Thanks, i 'hve seen why my debug wasn't working but my form still doesn't wrok.

I tried to separate the validator from the textfield, so i have a valid.lz, textfield.lzx and combobox.lzx

And when i try the app, the debug tells me it can found some properties.

Here is the files, can you have a quick,look please ? (when i check he telle me the field is empty but doesn't change the color)
Thank a lot

zalex
07-20-2006, 02:19 AM
I correct the validator so it work, but i still can have the text from the dataset and i really don't know why ...

And the problem with the fact that the textfield is an input texte is that the texte is too big to be seen. And replacing by an edittext the color is wrong.

explorer
07-20-2006, 05:17 AM
Can you post your updated code so that I can take a look?

-Explorer

zalex
07-20-2006, 05:23 AM
This is my app for the moment.
Thanks a lot

( you can see the app here : http://zzzalex.free.fr/lazlo/index2.lzx.html , there is a problem with the "connecter" button too in login there is the combobox under, and when i click on login again the views doesn't come back)

zalex
08-01-2006, 01:20 AM
I ask a lot of help, and now I give a small contribution ^^.
So i burst the formvalidator on subclass classes for more clarity.

I add a checkbox class (for license agrement for example) and a list class.

I tried to set the possibilty to have a password textfield but it doesn't work, so if someone want to have a look on this part...

I add a sample file of a form, with embeded data and online datas.

zalex
08-07-2006, 12:42 AM
Can't anyone give a hand for the password thing ?

I need it, but i doesn't work, i don't think it's really difficult, but all tried was wrong ...

(setPassword(true) , setAttribute(password,'true'))

In fact i want an attribute :
<attribute name="password" value="false" />

to define the type ...

JediUA
10-31-2006, 01:33 PM
Did anyone got a way around to create the password type or to have a password field??

Thanks!

zalex
11-01-2006, 12:52 AM
If you want the same thing for the password you have to create a class, a copy of the text class but with the password attribute to true. There's is a bug with the password is in final in the laszlo definition.

JediUA
11-01-2006, 06:41 AM
Thanks for your reply, I don't understand why can't I just add the password attribute to the existing mytext class...? If I create a copy of it with the password attribute set to true, would'nt that be the same?

<class name="mytextfield" width="140" height="20" bgcolor="0x7E7E7E">
<attribute name="required" value="false" />
<attribute name="password" value="false" />
<attribute name="errorColor" type="number" value="0xff0000" />

Merci.

zalex
11-01-2006, 06:48 AM
I had the same problem, and as i explain it, the password attribute has been defined to "final" in the laszlo conception, it must be corrected in the next version i think.
When you have something declared in final, in laszlo or in Java for example it would say that you can't modify it after the declaration.

So if you put true in the class declaration, you can't change it. the only solution is to copy the class and using a specific class for the pzssword fields !

JediUA
11-01-2006, 07:47 AM
Thanks again, didn't know about the 'final' thing. I'm kind of new to laszlo and still don't know details... If I declare the new class and set the password as an attribute, how can I tell it that its the same as the laszlo password functionality?

<class name="mypasswdfield" width="140" height="20" bgcolor="0x7E7E7E">
<attribute name="password" value="true" />
<attribute name="required" value="false" />
<attribute name="errorColor" type="number" value="0xff0000" />
<attribute name="validator" value="null" />
.
.
.
this way doesn't work, I guess I don't know how to declare it.

Merci encore,

senshi
11-01-2006, 09:15 AM
You have to change the password-attribute of the inner inputtext "textfield".
(I just left out the unimportant stuff of the class)


<class name="mytextfield" width="140" height="16" bgcolor="0x00FF00">
......
<attribute name="password" value="true" /><!-- this won't change anything -->
......

<inputtext name="textField" width="${parent.width-2}" align="center" height="${parent.height-2}"
valign="middle" bgcolor="white" password="true" clickable="true" />
......
</class>

JediUA
11-01-2006, 09:37 AM
I don't understand "of the inner inputtext "textfield". ..." you seem to have that inside your code for the class. Everything in my class is either an attribute or a method.

What I have is the password attribute in the class definition, then in a view inside the canvas I'm using that class and calling the attribute="true" but does nothing at all...

<class name="mypasswdfield" width="140" height="20" bgcolor="0x7E7E7E">
<attribute name="password" value="true" />
<attribute name="required" value="false" />
<attribute name="errorColor" type="number" value="0xff0000" />
<attribute name="validator" value="null" />
<inputtext name="textField" width="${parent.width-2}" align="center"
height="${parent.height-2}" valign="middle"
bgcolor="white" />



--- and in the canvas (different file) ---
.
.
<view>
<simplelayout axis="x" spacing="13"/>
<text fgcolor="blue" multiline="true"> Password: </text>
<mypasswdfield name="foo" required="true" password="true" clickable="true" validator="$once{canvas.myValidator}"/>
.
.
.

Thanks!

senshi
11-01-2006, 09:51 AM
As you see the class "mypasswdfield" wraps an "inputtext"-object. This inputtext is named "textField".
And the class "inputtext" has got an attribute "password". But this attribute is final, just like zalex has explained.
So you have to set the attribute "password" of the inputtext "textField" to "true".
The attribute "password" on the class "mypasswdfield" / "mytextfield" won't change anything, you can delete it or do whatever you want to.

<class name="mypasswdfield" width="140" height="20" bgcolor="0x7E7E7E">
<attribute name="password" value="true" />
<attribute name="required" value="false" />
<attribute name="errorColor" type="number" value="0xff0000" />
<attribute name="validator" value="null" />
<inputtext name="textField" width="${parent.width-2}" align="center"
height="${parent.height-2}" valign="middle"
bgcolor="white" password="true"/>
.....
</class>

JediUA
11-01-2006, 10:11 AM
Yes, of course, clumsy me. It works perfectly, thanks a lot!

mrutyu
11-01-2007, 12:41 PM
I'm totally lost! Does laszlo submit the form as an URL encoded string? I should say, that's that it's doing. I copied this code and was trying out a few things:


<class name="mytextfield" width="140" height="16" bgcolor="0x7E7E7E">
<attribute name="required" value="false" />
<attribute name="errorColor" type="number" value="0xff0000" />
<attribute name="validator" value="null" />
<inputtext name="textField" width="${parent.width-2}" align="center"
height="${parent.height-2}" valign="middle"
bgcolor="white" />

When I do something like:

<formvalidator name="myValidator" />
<form>
<mytextfield name="xyz" required="true" width="120" validator="$once{canvas.myValidator}"/>

<button>Check form
<method event="onclick">
if ( myValidator.validate() ) {
debug.write( 'Everything OK - the user filled out fields' );
} else {
debug.write( 'Required field empty' );
}
</method>
</button>
</form>


When I hit submit the URL goes as:
http://localhost:8080/ga?textField=abc

As you see, the name I give in mytextfield is not sent to the server. I'm sure I'm missing something here. Any help?

Thanks!