buttle
(Christopher Fanning)
April 22, 2010, 3:17pm
1
Hi,
I’m new so hopefully this is easy to solve.
I’m trying to use ajax to get an error or success back from a create action.
The Model
public function rules()
{
return array(
array('content', 'required')
The view
<?php $options=array(
'success'=>'function(){
alert("Success");
}',
'error'=>'function(){
alert("Error");
}',
)
;?>
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'service-order-question-form',
'enableAjaxValidation'=>false,
)); ?>
<?php echo $form->textArea($model,'content',array('rows'=>6, 'cols'=>50)); ?>
<?php echo CHtml::ajaxSubmitButton('Post', '/index.php/question/create' , $options); ?>
<?php $this->endWidget(); ?>
It submits ok. If the ‘content’ feild is empty then the creation fails (as expected) but the alert popup says ‘Success’
I’ve added a bogus field to the rule as so:
array('content, bogus', 'required')
And this causes the alert to read ‘Error’
That makes me think it’s not validating propery. I added:
array('content','length','allowEmpty'=>false)
but that hasn’t helped.
Am I overlooking something terribly obvious?
Thanks.
Vince
(Vadimg88)
April 23, 2010, 6:40am
2
That’s because you added the ajax submit button options to the ajax button not to the CActiveForm which holds the model and the validation rules. I have tested your setup and it didn’t work for me because of the ajaxSubmitButton but this one did:
view:
<?php $options=array(
'success'=>'function(){
alert("Success");
}',
'error'=>'function(){
alert("Error");
}',
)
;?>
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'service-order-question-form',
'enableAjaxValidation'=>true,
'clientOptions' => array('validateOnSubmit' => true),
)); ?>
<?php echo $form->errorSummary($model); ?>
<?php echo $form->textArea($model,'content',array('rows'=>6, 'cols'=>50)); ?>
<?php echo $form->error($model, 'content'); ?>
<?php echo CHtml::submitButton('Post'); ?>
<?php $this->endWidget(); ?>
Model:
<?php
class TestModel extends CFormModel
{
public $content = '';
/**
* table data rules
*
* @return array
*/
public function rules()
{
return array(
//array('content', 'length', 'allowEmpty'=>false, 'min'=>1),
array('content', 'required'),
);
}
}
?>
Controller:
public function actiontestq()
{
$model = new TestModel;
$this->performAjaxValidation($model);
if(isset($_POST['TestModel']))
{
$model->attributes=$_POST['TestModel'];
if( $model->validate() )
{
$this->redirect('index');
}
}
$this->render('testq', array('model'=>$model));
}
protected function performAjaxValidation($model)
{
if(isset($_POST['ajax']) && $_POST['ajax']=='service-order-question-form')
{
echo CActiveForm::validate($model);
Yii::app()->end();
}
}
Notice i tested this with both required validator and the length validator.
The above code tested to be working.
buttle
(Christopher Fanning)
April 23, 2010, 8:49am
3
That’s because you added the ajax submit button options to the ajax button not to the CActiveForm which holds the model and the validation rules. I have tested your setup and it didn’t work for me because of the ajaxSubmitButton but this one did:
view:
<?php $options=array(
'success'=>'function(){
alert("Success");
}',
'error'=>'function(){
alert("Error");
}',
)
;?>
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'service-order-question-form',
'enableAjaxValidation'=>true,
'clientOptions' => array('validateOnSubmit' => true),
)); ?>
<?php echo $form->errorSummary($model); ?>
<?php echo $form->textArea($model,'content',array('rows'=>6, 'cols'=>50)); ?>
<?php echo $form->error($model, 'content'); ?>
<?php echo CHtml::submitButton('Post'); ?>
<?php $this->endWidget(); ?>
Model:
<?php
class TestModel extends CFormModel
{
public $content = '';
/**
* table data rules
*
* @return array
*/
public function rules()
{
return array(
//array('content', 'length', 'allowEmpty'=>false, 'min'=>1),
array('content', 'required'),
);
}
}
?>
Controller:
public function actiontestq()
{
$model = new TestModel;
$this->performAjaxValidation($model);
if(isset($_POST['TestModel']))
{
$model->attributes=$_POST['TestModel'];
if( $model->validate() )
{
$this->redirect('index');
}
}
$this->render('testq', array('model'=>$model));
}
protected function performAjaxValidation($model)
{
if(isset($_POST['ajax']) && $_POST['ajax']=='service-order-question-form')
{
echo CActiveForm::validate($model);
Yii::app()->end();
}
}
Notice i tested this with both required validator and the length validator.
The above code tested to be working.
Thanks for replying.
Let me explain what I’m trying to do.
When the form submits and validates correctly I would like to do some javascript DOM updates on the page. That’s why I thought I need:
$options=array(
'success'=>'function(){
alert("Success");
}',
'error'=>'function(){
alert("Error");
}',
)
These are the hooks I should use, aren’t they?
I’ve tried you code and yes it works but it doesn’t employ $options, does it?
Thanks.
Vince
(Vadimg88)
April 23, 2010, 9:15am
4
By default no, CActiveForm does not implement the option to call a JS function on success or failure of the validation. Actually it has it’s own SuccessCallback inside the validation function in the js file.
FYI, You can submit a ticket requesting this feature to be implemented.
qiang
(Qiang Xue)
May 2, 2010, 6:59pm
5
I just added beforeValidate, afterValidate, beforeValidateAttribute and afterValidateAttribute options. Please let me know if they work for you. Thanks.
hefi
(Kgviktor)
October 7, 2010, 1:17pm
6
Here’s a code snippet that works for me:
$ajaxUrl=CController::createUrl('report/ajaxCreate');
$formId='report-form';
$js=<<<EOD
js:function(form, data, hasError) {
if (!hasError) {
jQuery.ajax({'type':'POST','url':'$ajaxUrl','cache':false,'data':$("#$formId").serialize(),'success':function(html){jQuery("#reportform").html(html)}});
return false;
}
}
EOD;
$form=$this->beginWidget('CActiveForm', array(
'id'=>$formId,
'enableAjaxValidation'=>true,
'clientOptions'=>array('validateOnSubmit'=>true,
'afterValidate'=>$js))); ?>
<p class="note">Fields with <span class="required">*</span> are required.</p>
<?php echo $form->errorSummary($model); ?>
<div class="row">
<?php echo $form->labelEx($model,'email'); ?>
<?php echo $form->textField($model,'email'); ?>
<?php echo $form->error($model,'email'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'content'); ?>
<?php echo $form->textField($model,'content',array('size'=>60,'maxlength'=>16384)); ?>
<?php echo $form->error($model,'content'); ?>
</div>
<div class="row buttons">
<?php echo CHtml::submitButton('Submit'); ?>
</div>
<?php $this->endWidget(); ?>
Basically I copied the jquery part of this ajaxSubmitButton:
<?php echo CHtml::ajaxSubmitButton("Update data",
CController::createUrl('report/ajaxCreate'),
array('type' =>'POST',
'update' => '#reportform'),
array('id' => 'ajaxButton'));
?>
Maybe this post helps to somebody.
formoda
(Rich)
January 10, 2011, 1:36pm
7
Hello,
Im using hefi’s solution but there’s a small issue when combining it validateOnChange. Since $_POST[‘ajax’] is always present my form is being SAVED on change if validation succeeds. I need a better way of differentiating between ‘ajax validation’ and ‘ajax submit’ than just checking $_POST[‘ajax’].
A quick fix would be to ony use validateOnSubmit (as in hefi’s example) but I like the interactivity of the latter, especially since my form is quite small.
Any thoughts?
Thanks,
Rich
silintzir
(Psilintziris)
February 4, 2011, 3:17pm
8
formoda:
Hello,
Im using hefi’s solution but there’s a small issue when combining it validateOnChange. Since $_POST[‘ajax’] is always present my form is being SAVED on change if validation succeeds. I need a better way of differentiating between ‘ajax validation’ and ‘ajax submit’ than just checking $_POST[‘ajax’].
A quick fix would be to ony use validateOnSubmit (as in hefi’s example) but I like the interactivity of the latter, especially since my form is quite small.
Any thoughts?
Thanks,
Rich
You could pass parameters with the submit button
echo CHtml::submitButton(
Yii::t('address', 'Add New Address'),
array(
'id' => 'new-submit-button',
'submit' => 'ajax/ajax',
'params' => array('submit' => true),
)
);
and then check for $_POST[‘submit’] value in the controller
hefi:
Here’s a code snippet that works for me:
$ajaxUrl=CController::createUrl('report/ajaxCreate');
$formId='report-form';
$js=<<<EOD
js:function(form, data, hasError) {
if (!hasError) {
jQuery.ajax({'type':'POST','url':'$ajaxUrl','cache':false,'data':$("#$formId").serialize(),'success':function(html){jQuery("#reportform").html(html)}});
return false;
}
}
EOD;
$form=$this->beginWidget('CActiveForm', array(
'id'=>$formId,
'enableAjaxValidation'=>true,
'clientOptions'=>array('validateOnSubmit'=>true,
'afterValidate'=>$js))); ?>
<p class="note">Fields with <span class="required">*</span> are required.</p>
<?php echo $form->errorSummary($model); ?>
<div class="row">
<?php echo $form->labelEx($model,'email'); ?>
<?php echo $form->textField($model,'email'); ?>
<?php echo $form->error($model,'email'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'content'); ?>
<?php echo $form->textField($model,'content',array('size'=>60,'maxlength'=>16384)); ?>
<?php echo $form->error($model,'content'); ?>
</div>
<div class="row buttons">
<?php echo CHtml::submitButton('Submit'); ?>
</div>
<?php $this->endWidget(); ?>
Basically I copied the jquery part of this ajaxSubmitButton:
<?php echo CHtml::ajaxSubmitButton("Update data",
CController::createUrl('report/ajaxCreate'),
array('type' =>'POST',
'update' => '#reportform'),
array('id' => 'ajaxButton'));
?>
Maybe this post helps to somebody.
[color=#1C2837][size=2] I am cheerful here,This snippets works!I tested with clientvalidation set to true.The form is submitted with ajax,ONLY if it validates on client side,no POST request is ever made to the server apart from the actual submission.Ofcourse it also works with javascript turned off,a regular POST request to the server happens on this occasion.
Thumbs up for Yii,because there is a ton of core Yii javascript required to make this happen.[/size][/color]
[color=#1C2837][size=2]Powerful stuff!
Thank you so much.
There should be a little wiki tutorial for this,I think it’s very useful info.[/size][/color]