How to trigger form validation without submitting the form

Hi,

I have searched for tow days this forum but cannot find a way to solved my problem so here it is.

I want to submit a form through ajax without refreshing the page and I want to trigger validation before that.

I searched and apparently validation is fired up only on form submission.

I do not want to submit the form because this will cause the page to reload and I do not want that.

What I want is to fire up form validation when I click the ajax button and then only if the validation passes to submit the form again through ajax so the record is saved.

I hope I explained clearly, if not I will try to explain again.

Thanks,

Doru.

Maybe it will help to explain what solution I have right now. I am just looking for a better one.

I can post the form through a ajax button. This does not trigger the validation but I can do the validation anyway server side. If the validation fails I can return the error details and I can update the form attributes manually, just like active form does.

If the validation succeeds I can save the record and return something to the browser so I know all is well.

Now the part that bugs me is the part where I have to write again the code that handles validation errors.

This code is already in there in the active form JS, and I want a way to make use of it.

No? :] In default behaviour (look in to fresh Yii demo app) you have AJAX form validation without submitting it. It is fired after user enters something into field. Look into login page example. Enter antything to login field, hit Tab to go to password field and wait for a few seconds. Border of login page should change as the reaction for just fired AJAX-validation.

As mentioned by Trejder, you have AJAX validation which performs while your form is being filled.

If you want you form to be submitted without refreshing the page, CHtml::ajaxSubmitButton:

API is your friend ;)

I know it is also fired up on form change. I am referring to “submit” scenarios. What if a user opens up the form and hits the ajax button? The validation will not be fired, and this is a pretty “normal” scenario with casual users. The validation you two are talking about is the on-change validation. What if that event does not get fired because user doesn’t enter anything just hits submit or save or whatever the ajax button is named. I want to prevent that, I want to fire up the validation even if the user doesn’t enter anything. I want the ajax submit button to “submit” only if the validation passes.

I will try to describe a scenario that I have that will make the on change validation on the form useless.

So I open a sub form in my form and I have some fields and a ajaxSubmitButton.

The ajaxSubmitButton on success updates some master total fields based on the information entered in each subform.

If the user enters just half of the subform, he will see all in red. That’s ok for a normal user, but he’s stupid or doesn’t pay attention and will click submit anyway. The form will submit through ajax, the server side validation will fail but if I return a response like for form validation the ajaxSubmitButton will interpret that as a success and will close the sub form and update the master fields even though the form submission actually failed.

I can prevent this in two ways: fire up the form validation before submitting a ajax submit button or have a way of letting the ajax submit button there has been an error and it should not fire up the success part.

Hey, forgive me, if I misunderstand you or talking some useless bullshit, but after only four hours of sleep I’m like a living zombie! :]

I don’t get it at all. If you can fire-up AJAX action in input box’s onChange or onLeave (I don’t know, never dig that part of Yii out, I don’t use AJAX validation at all), what prevents you from firing the very same validation action in your AJAX onClick? This way you should have validation without form submit, and that is what you want to have, if I’m not mistaken.

That’s the thing, I do not fire the validate event, it gets fired by the yiiactiveform code.

Which I got deep into the last couple of days and understood and now I am firing the validation myself in the ajax button.

But this is javascript-foo, it is not really a Yii way of doing things. The yiiactiveform does not (as far as I know) have support for on demand validation. The form has a validate method but all it does is collect the form’s data and send it via ajax to the controller. It has a callback function and it passes the result of the server-side validation to that callback and you have to highlight yourself the invalid fields a thing that the yiiactiveform does automatically when triggered by the onchange event.

I know now that what I was looking for was a submit button that triggers validation and submits only if validation passes. This at the moment does not exist, and I think it would be really helpful for one of the ajaxSubmitButton to do that.

Im’ stuck with this as well. It is just not possible to run validation when I need to. That’s very inflexible.

I need to run validate on form A when form B is submitted, and only submit B if A also validates.

That would require me to be able to run validate on A without any change or submit on it.

It would also require me to push a callback on the validation call to be able to know when form A has been validated, and the result.

Basically I have to have a single form now instead, and change the form’s submission action on the fly depending on what button the user clicks in the form. (Each button has it’s own action).

The validation method needs to be callable on any yiiactiveform with javascript on the client side, I agree with mongoose76.

I’m bumping this. It would be nice to be able to manually trigger the client-side validation of a form. Any ideas?

how would you do that? I’ve been looking for this but got too tired before finding it

Currently there is no "nice" way of triggering yiiactiveforms validation. But this should do the trick though.


function fnValidateActiveForm(param, parent) {

                var form = $(parent), settings = form.data('settings');

                $.each(settings.attributes, function (i, attribute) {

                    $.fn.yiiactiveform.updateInput(attribute, param, form);

                });

};

I have a few custom widgets with hidden input fields that I want to validate.

Is there a way to trigger validation for one specific form attribute?

*This seems to work :)


$('#fieldId').trigger('change');

This actually won’t work as “param” is not defined, and it contains main information about validation.

The MUCH easier way to achieve it without dirty hacks is simply use "submitting" property of settings. So,

don’t prevent your submitting, just run AJAX submit only when javascript validation has passed:


//e.g. your submit click function 


$('where-to-look-for').find('input[type=submit], button[type=submit]').bind('click',function( e ){

	var form = $(this).parents('form:first'); var settings = form.data('settings');

	if (settings.submitting) { //prevent normal submit only if js validation is OK

		e.preventDefault(); 

		alert('ajax function run'); //run your ajax submission instead of a default submit functionality of a form

	}

});

I found a way to validate the form using Yii’s Active Form jQuery plugin.

It has the function "validate" which states that is for internal invoke only, though it is working very well in my case which does not include Ajax validation, only client, but I beleive it works with Ajax too.


var $form = $('#link-options-form')


$.fn.yiiactiveform.validate($form, function(messages) {

	if($.isEmptyObject(messages)) { // If there are no error messages all data are valid

		// Do something with valid form data


		// And close a dialog maybe

		$('#dlg').dialog('close');

	} else {

		// Fields acquiring invalid data classes and messages show up

		alert('Form has invalid data');

	}

});

I just used this solution for ajax validation, is fantastic, thanks. But when I tried to submit twice, the validation it’s ignored. My solution is to modify the submitting parameter to true, like this:


var $form = $('#link-options-form')

var settings = $form.data('settings') ;

settings.submitting = true ;

$.fn.yiiactiveform.validate($form, function(messages) {

	if($.isEmptyObject(messages)) { // If there are no error messages all data are valid

		// Do something with valid form data


		// And close a dialog maybe

		$('#dlg').dialog('close');

	} else {

		// Fields acquiring invalid data classes and messages show up

		alert('Form has invalid data');

	}

});

It works very well.

Hey, perhaps I’m not understanding correctly, but won’t the clientOptions validateOnSubmit property take care of this? You can set it when using the CActiveform widget. There is some documetation here: http://www.yiiframework.com/doc/api/1.1/CActiveForm#clientOptions-detail and a post http://www.yiiframework.com/forum/index.php/topic/12919-property-cactiveformvalidateonsubmit-is-not-defined/ that helped me figure this out.

For us it worked great as well. However, the error messages were not showing up. We went through the js code and found another function that we could manually trigger when the validation failed. We also re established submitting to false again when the validation failed.




settings = form.data('settings'),

            $.each(settings.attributes, function () {

               $.fn.yiiactiveform.updateInput(this,messages,form); 

            });

            settings.submitting = false ;



With this, all the code to manually trigger validation is…




var form = $("#formId");

    var settings = form.data('settings') ;

    settings.submitting = true ;

    $.fn.yiiactiveform.validate(form, function(messages) {

        if($.isEmptyObject(messages)) { // If there are no error messages all data are valid

            $.each(settings.attributes, function () {

               $.fn.yiiactiveform.updateInput(this,messages,form); 

            });

//We update each attribute again even if there are no messages so that any error messages disappear. Good if your request takes long so the user doesn't see errors 

            successFunction();

        } else {

            // Fields acquiring invalid data classes and messages show up. Update the inputs.

            settings = form.data('settings'),

            $.each(settings.attributes, function () {

               $.fn.yiiactiveform.updateInput(this,messages,form); 

            });

            settings.submitting = false ;

        }

    });



This code works great! It hooked up perfectly to a wizard-like interface for a form I’m working on.

Actually it turns out that users are randomly having errors with this code, where it will say fields are not validating even though they are. If you keep changing things around it eventually disappears. I’ve had it happen to myself once or twice but can not recreate it anymore. Any ideas on why that might be happening?