Yii Framework Forum: Avoiding client side validation on secondary submit buttons. - Yii Framework Forum

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

Avoiding client side validation on secondary submit buttons. Prado's CausesValidation="false"-like for client side vali Rate Topic: -----

#1 User is offline   MetaYii 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 393
  • Joined: 07-October 08
  • Location:The Matrix

Posted 25 August 2011 - 09:23 AM

The problem is described here:

http://www.yiiframew...-cancel-button/

Server side validation is no problem since you can check isset($_POST['cancel']); to see if cancel button was pressed, but it seems there's no a reliable way to do this in javascript for client side validation.

My suggestion would be to add some option to the cactiveform's clientOptions to indicate which controls would trigger client validation.
Ah! on-off, simplement!
0

#2 User is offline   MetaYii 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 393
  • Joined: 07-October 08
  • Location:The Matrix

Posted 25 August 2011 - 03:55 PM

Ok, I wrote this quick hack patch to CActiveForm, adding an array property called avoidClientValidationOn which would contain the names of the buttons for which the client validation should be disabled, and a Javascript function for disabling the validation (notice that if you specify avoidClientValidationOn and clientOptions.beforeValidate, your beforeValidate handler will be overwritten. TODO: execute custom beforeValidate handlers and configure the name of the Javascript function.

--- CActiveForm.php 	(revisiĆ³n: 367)
+++ CActiveForm.php 	(copia de trabajo)
@@ -278,6 +278,15 @@
 		*/
    	public $enableClientValidation=false;
 
+   /**
+	* Array containing the names of the buttons for which client validation is
+	* disabled.
+	*
+	* @author MetaYii
+	* @var type
+	*/
+   public $avoidClientValidationOn = array();
+
    	/**
 		* @var mixed form element to get initial input focus on page load.
 		*
@@ -361,10 +370,29 @@
            	if($this->focus!==null)
                    	$options['focus']=$this->focus;
 
+  	if (is_array($this->avoidClientValidationOn) && !empty($this->avoidClientValidationOn)) {
+ 		$options['beforeValidate'] = 'js:beforeValidate';
+ 		$buttons = CJavaScript::encode(array_fill_keys($this->avoidClientValidationOn, ''));
+ 		$js =&lt;&lt;<eop +function="" beforevalidate(form)="" {="" +="" if="" (form.data('submitobject'))="" (form.data('submitobject')[0].name="" in="" {$buttons})="" this.validateonsubmit="false;" this.beforevalidate="function" form.submit();="" };="" return="" false;="" }="" true;="" +}="" +eop;="" $cs-="">registerScript(get_class($this).'#'.$id.'#novalidation', $js);
+
            	$options=CJavaScript::encode($options);
            	$cs-&gt;registerCoreScript('yiiactiveform');
            	$id=$this-&gt;id;
            	$cs-&gt;registerScript(__CLASS__.'#'.$id,"\$('#$id').yiiactiveform($options);");
+  	}
    	}
 
    	/**
<br><br><br>But if you can improve my quick hack, be my guest.<br></eop>
Ah! on-off, simplement!
0

#3 User is offline   MetaYii 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 393
  • Joined: 07-October 08
  • Location:The Matrix

Posted 25 August 2011 - 04:06 PM

Ok, as editing in the forum s*cks :angry: , I'll repost my patch:

--- CActiveForm.php 	(revisiĆ³n: 367)
+++ CActiveForm.php 	(copia de trabajo)
@@ -278,6 +278,15 @@
     	*/
    	public $enableClientValidation=false;
 
+   /**
+	* Array containing the names of the buttons for which client validation is
+	* disabled.
+	*
+	* @author MetaYii
+	* @var type
+	*/
+   public $avoidClientValidationOn = array();
+
    	/**
     	* @var mixed form element to get initial input focus on page load.
     	*
@@ -361,10 +370,29 @@
            	if($this->focus!==null)
                    	$options['focus']=$this->focus;
 
+  	if (is_array($this->avoidClientValidationOn) && !empty($this->avoidClientValidationOn)) {
+     	$options['beforeValidate'] = 'js:beforeValidate';
+     	$buttons = CJavaScript::encode(array_fill_keys($this->avoidClientValidationOn, ''));
+     	$js =<<<EOP
+function beforeValidate(form) {
+   if (form.data('submitObject')) {
+  	if (form.data('submitObject')[0].name in {$buttons}) {
+     	this.validateOnSubmit = false;
+     	this.beforeValidate = function beforeValidate(form) { form.submit(); };
+     	form.submit();
+     	return false;
+  	}
+   }
+   return true;
+}
+EOP;
+  	$cs->registerScript(get_class($this).'#'.$id.'#novalidation', $js);
+
            	$options=CJavaScript::encode($options);
            	$cs->registerCoreScript('yiiactiveform');
            	$id=$this->id;
            	$cs->registerScript(__CLASS__.'#'.$id,"\$('#$id').yiiactiveform($options);");
+  	}
    	}
 
    	/**

Ah! on-off, simplement!
0

#4 User is offline   MetaYii 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 393
  • Joined: 07-October 08
  • Location:The Matrix

Posted 25 August 2011 - 04:25 PM

Opened an issue on this here:

http://code.google.c.../detail?id=2772
Ah! on-off, simplement!
0

#5 User is offline   MetaYii 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 393
  • Joined: 07-October 08
  • Location:The Matrix

Posted 25 August 2011 - 04:47 PM

Note, with my hack, you just need to configure the form like this:

<?php

$form = $this->beginWidget('CActiveForm', array(
	'id'=>'recovery-form',
   'enableClientValidation'=>true,
   'enableAjaxValidation'=>false,
   'focus'=>array($model, 'username'),
   'errorMessageCssClass'=>'clsErrorMessage',
   'htmlOptions'=>array('autocomplete'=>'off'),
   'avoidClientValidationOn'=>array('cancel'), // new option here *****
	'clientOptions'=>array(
		'validateOnSubmit'=>true,
  	'errorCssClass'=>'clsError',
  	'successCssClass'=>'clsSuccess',
  	'validatingCssClass'=>'clsValidating',
	),
));

?>

Ah! on-off, simplement!
0

#6 User is offline   Logan 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 19
  • Joined: 04-March 11

Posted 09 September 2011 - 12:09 AM

This is a great idea. I'm using a wizard style create form. When I click the "next" <button>, yiiactiveform validates the whole form displaying all errors. I didn't get the patch to work. It seems it disabled validateOnSubmit regardless of the setting. Still working on it. This is what I patched:


                if($this->focus!==null)
                        $options['focus']=$this->focus;

//Patch
                if (is_array($this->avoidClientValidationOn) && !empty($this->avoidClientValidationOn)) {
                        $options['beforeValidate'] = 'js:beforeValidate';
                        $buttons = CJavaScript::encode(array_fill_keys($this->avoidClientValidationOn, ''));
                        $js = 'function beforeValidate(form) {
                                if (form.data("submitObject")) {
                                        if (form.data("submitObject")[0].name in {$buttons}) {
                                                this.validateOnSubmit = false;
                                                this.beforeValidate = function beforeValidate(form) { form.submit(); };
                                                form.submit();
                                                return false;
                                        }
                                }
                                return true;
                        }';

                $cs->registerScript(get_class($this).'#'.$id.'#novalidation', $js);
//End Patch
                $options=CJavaScript::encode($options);
                $cs->registerCoreScript('yiiactiveform');
                $id=$this->id;
                $cs->registerScript(__CLASS__.'#'.$id,"\$('#$id').yiiactiveform($options);");
//Patch
                }
//End Patch




View PostMetaYii, on 25 August 2011 - 04:47 PM, said:

Note, with my hack, you just need to configure the form like this:

<?php

$form = $this->beginWidget('CActiveForm', array(
	'id'=>'recovery-form',
   'enableClientValidation'=>true,
   'enableAjaxValidation'=>false,
   'focus'=>array($model, 'username'),
   'errorMessageCssClass'=>'clsErrorMessage',
   'htmlOptions'=>array('autocomplete'=>'off'),
   'avoidClientValidationOn'=>array('cancel'), // new option here *****
	'clientOptions'=>array(
		'validateOnSubmit'=>true,
  	'errorCssClass'=>'clsError',
  	'successCssClass'=>'clsSuccess',
  	'validatingCssClass'=>'clsValidating',
	),
));

?>


0

#7 User is offline   MetaYii 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 393
  • Joined: 07-October 08
  • Location:The Matrix

Posted 09 September 2011 - 12:10 AM

This is a follow up the post by Ken... at the ticket in Google Code. He mentions that my hack didn't work for his use case (a form with a wizard, where the pressing of the Next button triggers validation):

Quote

Comment 3 by klen...@gmail.com, Today (4 minutes ago)

The patch didn't work as-is with the linux patch command. Tried manually editing. Seems to have broken the validateOnSubmit all together. Still working on it. This is what I have so far <attached>.


First: notice that the patch was extracted from svn diff, since I have Yii inside my subversion local copy of my project. So I'm not sure if the patch command will work with it without some manual modification. I'm sorry for not warning about this before.

On your issue, I guess it has to do with the fact of having a wizard. I've just tested on a normal form. Your wizard, is AJAX/JS based or postback-based?
Ah! on-off, simplement!
0

#8 User is offline   MetaYii 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 393
  • Joined: 07-October 08
  • Location:The Matrix

Posted 09 September 2011 - 12:16 AM

View PostLogan, on 09 September 2011 - 12:09 AM, said:

This is a great idea. I'm using a wizard style create form. When I click the "next" <button>, yiiactiveform validates the whole form displaying all errors. I didn't get the patch to work. It seems it disabled validateOnSubmit regardless of the setting. Still working on it. This is what I patched:


                if($this->focus!==null)
                        $options['focus']=$this->focus;

//Patch
                if (is_array($this->avoidClientValidationOn) && !empty($this->avoidClientValidationOn)) {
                        $options['beforeValidate'] = 'js:beforeValidate';
                        $buttons = CJavaScript::encode(array_fill_keys($this->avoidClientValidationOn, ''));
                        $js = 'function beforeValidate(form) {
                                if (form.data("submitObject")) {
                                        if (form.data("submitObject")[0].name in {$buttons}) {
                                                this.validateOnSubmit = false;
                                                this.beforeValidate = function beforeValidate(form) { form.submit(); };
                                                form.submit();
                                                return false;
                                        }
                                }
                                return true;
                        }';

                $cs->registerScript(get_class($this).'#'.$id.'#novalidation', $js);
//End Patch
                $options=CJavaScript::encode($options);
                $cs->registerCoreScript('yiiactiveform');
                $id=$this->id;
                $cs->registerScript(__CLASS__.'#'.$id,"\$('#$id').yiiactiveform($options);");
//Patch
                }
//End Patch







Be careful, you're using single quotes in this assignment:

$js = 'function beforeValidate(form) {


so I guess this won't be interpolated:


                                 		if (form.data("submitObject")[0].name in {$buttons}) {


So I guess that if you check your page source code in the browser, you'll get something like

                                 		if (form.data("submitObject")[0].name in {$buttons}) {


with the {$buttons} textually, instead of being replaced by the value of the $buttons variable. Please use double quotes. I also would suggest using heredoc, but that's just my personal preference.

I assume you're not using Firebug or MSIE with javascript debugging enabled, because I'm pretty sure a javascript error is being thrown.
Ah! on-off, simplement!
0

#9 User is offline   Logan 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 19
  • Joined: 04-March 11

Posted 09 September 2011 - 12:34 AM

Thanks for the reply so quickly! I'm using a standard form, using JQuery to slide back and forth to/from the next section. No AJAX. yiiactiveform is not loading, probably why the validation isn't working. I'm using google devel tools to play with this some more.

Tried replacing the single quote with double quotes a few different ways. It still didn't load yiiactiveform.

Logan
0

#10 User is offline   Logan 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 19
  • Joined: 04-March 11

Posted 09 September 2011 - 12:26 PM

So... I played around with MetaYii's patch for CActiveForm. I couldn't get it working correctly. Perhaps I was doing something wrong. However, I believe I solved my problem with this. Let me know what you think. All I have to do is add the class 'jsNoValidate' to the button.


<?php
$js = <<< EOJ
function beforeValidate(form) {
	if (form.data('submitObject').hasClass('jsNoValidate'))
		return false;
	return true;
}
EOJ;
Yii::app()->clientScript->registerScript('beforeValidate', $js);
?>
<div id="container">
	<?php $form=$this->beginWidget('CActiveForm', array(
		'id'=>'employee-form',
		'enableAjaxValidation'=>true,
		'clientOptions'=>array(
			'validateOnSubmit'=>true,
			'beforeValidate'=>"js:beforeValidate"
		),
	)); ?>

ETC....

0

#11 User is offline   MetaYii 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 393
  • Joined: 07-October 08
  • Location:The Matrix

Posted 09 September 2011 - 05:26 PM

View PostLogan, on 09 September 2011 - 12:34 AM, said:

Thanks for the reply so quickly! I'm using a standard form, using JQuery to slide back and forth to/from the next section. No AJAX. yiiactiveform is not loading, probably why the validation isn't working. I'm using google devel tools to play with this some more.

Tried replacing the single quote with double quotes a few different ways. It still didn't load yiiactiveform.



You really should install Firebug in either Firefox or Chrome. That would save you a few headaches with javascript erros ;-)

Also, remember that you must delete the contents of the published assets directory in order to get the changes to any of the javascript code of the framework.
Ah! on-off, simplement!
0

#12 User is offline   MetaYii 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 393
  • Joined: 07-October 08
  • Location:The Matrix

Posted 09 September 2011 - 05:27 PM

View PostLogan, on 09 September 2011 - 12:26 PM, said:

So... I played around with MetaYii's patch for CActiveForm. I couldn't get it working correctly. Perhaps I was doing something wrong. However, I believe I solved my problem with this. Let me know what you think. All I have to do is add the class 'jsNoValidate' to the button.


Yeap, that's another way to refer to the buttons.
Ah! on-off, simplement!
0

#13 User is offline   jacmoe 

  • Elite Member
  • Yii
  • Group: Moderators
  • Posts: 2,601
  • Joined: 10-October 10
  • Location:Denmark

Posted 09 September 2011 - 05:34 PM

Why don't you try this ? ->
Wizard Behavior ;)

I am using it for an installer and it works perfectly.
"Less noise - more signal"
0

#14 User is offline   Logan 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 19
  • Joined: 04-March 11

Posted 10 September 2011 - 10:30 AM

Yup - I was deleting assets.

I haven't seen a huge advantage in using firebug over the developer tools. Perhaps I'll take another look.

Wizard behavior is nice. The wizard I'm using is one action, with a nice jquery slide effect. Very simple and minimalistic. It's published here: Wizard. Except mine looks a bit different : My Form

View Postjacmoe, on 09 September 2011 - 05:34 PM, said:

Why don't you try this ? ->
Wizard Behavior ;)

I am using it for an installer and it works perfectly.

0

#15 User is offline   yiiihaaa 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 1
  • Joined: 07-October 12

Posted 07 October 2012 - 01:16 PM

hello, anyone got it to work on IE 8, I am getting javascript error "Out of stack space" when i click on the submit button. It seems like the code "form.submit();" is causing this error in IE. It is working fine on Google chrome.

Can you guys help please?
Thanks!
0

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users