1. #1
    Sencha - Ext JS Dev Team Animal's Avatar
    Join Date
    Mar 2007
    Location
    Notts/Redwood City
    Posts
    30,508
    Vote Rating
    58
    Animal has a spectacular aura about Animal has a spectacular aura about Animal has a spectacular aura about

      0  

    Default Form.isValid() when Field.validateValue() is asynchronous

    Form.isValid() when Field.validateValue() is asynchronous


    I'm running up against a problem. I'm sure there are ways round it, but I have noone here to discuss it with.

    Basically, some of my subclasses of Ext.form.Field implement "Ajax" validation. ie, they submit their value for validation on the server, and the response callback function then calls either this.clearInvalid() or this.markInvalid(result.errorMessage)

    This means that validateValue cannot return an immediate true/false response. It returns void.

    This is fine for validating a field on user input.

    But on form submit, I make a call to BasicForm.isValid, and abort submission if the Form finds itself to be invalid. This fails because my validateValue returns void.

    In fact, each field maintains it's valid state doesn't it? So what if I added a function to BasicForm:

    Code:
    Ext.override(Ext.form.BasicForm, {
        areFieldsValid: function() {
            var valid = true;
            this.items.each(function(f){
                if(f.el.hasClass(f.invalidClass)){
                    valid = false;
                }
                return valid; // Abort iteration at first invalid Field! 
            });
            return valid;
        }
    });
    Would that do it?

    BTW, Shouldn't Form.isValid() abort the each iteration at the first invalid Field by returning the valid flag? Once one Field has been found invalid, the form is definitely invalid.

  2. #2
    Ext User
    Join Date
    May 2007
    Posts
    35
    Vote Rating
    0
    Magicbob is on a distinguished road

      0  

    Default Same problem for me

    Same problem for me


    Hello

    I have the same problem. Have you find a better solution?

    Thanks

    Magicbob

  3. #3
    Ext User
    Join Date
    May 2007
    Posts
    35
    Vote Rating
    0
    Magicbob is on a distinguished road

      0  

    Default Some mistake to not do

    Some mistake to not do


    Hello

    I guess it is something simple for most of you but i have lost lot of time to find what was wrong so i explain here. Maybe it will save some time to someone

    I have a form generated from a template :

    [CODE]
    <div class="fondBlanc" id="inscription-conteneur">
    <form id="frmInscription" name="frmInscription" class="x-form">
    <div id="inscription-message-err"></div>

    <div class="x-form-ct x-form-label-right">

    <div class="x-form-ct x-form-column x-form-label-right" style="width: 350px;">

    <fieldset class="x-form-label-right">
    <legend>Mon compte</legend>
    <div class="x-form-item">
    <label for="inscription-internaute_pseudo">{inscription-label-internaute_pseudo}</label>
    <div class="x-form-element"><input type="text" class="x-form-text x-form-field" id="inscription-internaute_pseudo" name="inscription-internaute_pseudo" /></div>
    </div>
    <div class="x-form-item">
    <label for="inscription-internaute_email">{inscription-label-internaute_email}</label>
    <div class="x-form-element"><input type="text" class="x-form-text x-form-field" id="inscription-internaute_email" name="inscription-internaute_email" /></div>
    </div>
    <div class="x-form-item">
    <label for="inscription-internaute_password">{inscription-label-internaute_password}</label>
    <div class="x-form-element"><input type="password" class="x-form-text x-form-field" id="inscription-internaute_password" name="inscription-internaute_password" /></div>
    </div>
    <div class="x-form-item">
    <label for="inscription-internaute_password2">{inscription-label-internaute_password2}</label>
    <div class="x-form-element"><input type="password" class="x-form-text x-form-field" id="inscription-internaute_password2" name="inscription-internaute_password2" /></div>
    </div>
    </fieldset>

    <fieldset class="x-form-label-right">
    <legend>Identit

  4. #4
    Ext User
    Join Date
    Mar 2007
    Location
    Boston
    Posts
    349
    Vote Rating
    0
    sjivan is on a distinguished road

      0  

    Default


    Quote Originally Posted by Animal View Post
    I'm running up against a problem. I'm sure there are ways round it, but I have noone here to discuss it with.

    Basically, some of my subclasses of Ext.form.Field implement "Ajax" validation. ie, they submit their value for validation on the server, and the response callback function then calls either this.clearInvalid() or this.markInvalid(result.errorMessage)

    This means that validateValue cannot return an immediate true/false response. It returns void.

    This is fine for validating a field on user input.

    But on form submit, I make a call to BasicForm.isValid, and abort submission if the Form finds itself to be invalid. This fails because my validateValue returns void.

    The key here is to have your ajax validation fields to always return 'true' for validateValue (even if you display an error message in the UI when they type in an invalid value) and have the form submit to the server when all the locally validated fields are valid (ie form.isValid() returns true) . The server then carries out its server side validation and if it determines that any of the ajax validaiton fields have an invalid value, it should then return data in the format

    Code:
    <response success="false">
    <errors>
        <field>
            <id>first</id>
            <msg><![CDATA[
                Invalid name. <br /><i>This is a test validation message from the server </i>
             ]]></msg>
        </field>
        <field>
            <id>dob</id>
            <msg><![CDATA[
                Invalid Date of Birth. <br /><i>This is a test validation message from the server </i>
             ]]></msg>
        </field>
    </errors>
    </response>
    and the Ext form will mark those fields as invalid. take a look at the xml-form sample.

    BTW, Shouldn't Form.isValid() abort the each iteration at the first invalid Field by returning the valid flag? Once one Field has been found invalid, the form is definitely invalid.
    Say a form has several required fields and the user clicks the Submit button without entering any value, you would want an errror message besides all invalid fields so iterating over all fields causes this to happen. If it aborted on encountering the first invalid field, jsut one of possibly many invalid fields will be marked as invalid.

    This thread has some discussion about the matter : http://extjs.com/forum/showthread.php?t=1602

    Sanjiv

  5. #5
    Ext User
    Join Date
    Mar 2007
    Location
    Boston
    Posts
    349
    Vote Rating
    0
    sjivan is on a distinguished road

      0  

    Default


    I found an ideal solution to this problem. Moo Tools has a cool feature where it allows you to group mulitple ajax requests and have the group's onComplete be called after all the ajax requests complete.

    http://demos.mootools.net/Group

    So you can group all server side asynchronous validation calls and in the Group's onComplete check for the valid state and submit the form only if valid.

    It would be nice if Ext added such a feature to its Ajax class.

    Sanjiv

  6. #6
    Ext User dotnetCarpenter's Avatar
    Join Date
    Mar 2007
    Location
    Copenhagen, Denmark
    Posts
    271
    Vote Rating
    0
    dotnetCarpenter is on a distinguished road

      0  

    Default


    BTW, Shouldn't Form.isValid() abort the each iteration at the first invalid Field by returning the valid flag? Once one Field has been found invalid, the form is definitely invalid.
    [strike]I'm not sure but if the validation iteration stops then it would only display one field as invalid, namely the first, no? If the next field is invalid then the user wouldn't know until the form reevaluates.[/strike]
    Last edited by dotnetCarpenter; 22 Jun 2007 at 10:57 AM. Reason: This post is not relevant as sjivan already made the same comment