Avoiding client side validation on secondary submit buttons. Prado's CausesValidation="false"-like for client side vali
#1
Posted 25 August 2011 - 09:23 AM
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.
#2
Posted 25 August 2011 - 03:55 PM
--- 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'))="" (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->registerCoreScript('yiiactiveform');
$id=$this->id;
$cs->registerScript(__CLASS__.'#'.$id,"\$('#$id').yiiactiveform($options);");
+ }
}
/**
<br><br><br>But if you can improve my quick hack, be my guest.<br></eop>
#3
Posted 25 August 2011 - 04:06 PM
--- 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);");
+ }
}
/**
#5
Posted 25 August 2011 - 04:47 PM
<?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',
),
));
?>
#6
Posted 09 September 2011 - 12:09 AM
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
MetaYii, on 25 August 2011 - 04:47 PM, said:
<?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',
),
));
?>
#7
Posted 09 September 2011 - 12:10 AM
Quote
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?
#8
Posted 09 September 2011 - 12:16 AM
Logan, on 09 September 2011 - 12:09 AM, said:
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.
#9
Posted 09 September 2011 - 12:34 AM
Tried replacing the single quote with double quotes a few different ways. It still didn't load yiiactiveform.
Logan
#10
Posted 09 September 2011 - 12:26 PM
<?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....
#11
Posted 09 September 2011 - 05:26 PM
Logan, on 09 September 2011 - 12:34 AM, said:
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.
#12
Posted 09 September 2011 - 05:27 PM
Logan, on 09 September 2011 - 12:26 PM, said:
Yeap, that's another way to refer to the buttons.
#14
Posted 10 September 2011 - 10:30 AM
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
jacmoe, on 09 September 2011 - 05:34 PM, said:
#15
Posted 07 October 2012 - 01:16 PM
Can you guys help please?
Thanks!

Help














