Ajaxsubmitbutton

Hello,

I have an ajaxSubmitButton on a form view, itself called by ajax, that call an action to save the values of the form. The first problem is that the action save the datas twice (I have 2 same records recorded at the same time). The second problem is that the success function is not executed (the spinner is never ending). I have no log anywhere so I’m lost.

here is the view that call the form by ajax :




<div class="view">

    <div class="threads">

        <b><?php echo CHtml::encode($data->thread_title); ?>:</b>

        <?php echo Yii::t('app',' From '); ?>

        <b><?php echo CHtml::link($data->author->username,array('/users/index','user_id'=>$data->user_id)); ?></b>

        <?php echo Yii::t('app',' The '); ?>

        <b><?php echo CHtml::encode($data->thread_date); ?></b>

        &nbsp;(<?php echo CHtml::encode($data->thread_views).Yii::t('app',' View(s)'); ?>)</b>

        <br /><br />

        <i><?php echo CHtml::encode($data->thread_desc); ?></i>

        <br /><br />

        <?php echo CHtml::ajaxButton(

            CHtml::encode(Yii::t('app','Show Posts')),

            CController::createUrl('/site/ajaxGetPosts', array('thread_id'=>$data->thread_id)),

            array('update'=>'#posts-'.$data->thread_id),

            array('class'=>'show_post','id'=>'posts_button-'.$data->thread_id)

            );  

        ?>  


        <?php echo CHtml::ajaxButton(

            CHtml::encode(Yii::t('app','Show Comments')),

            CController::createUrl('ajaxGetComments', array('thread_id'=>$data->thread_id)),

            array('success'=>'js:function(data){

                        $("#comments-'.$data->thread_id.'").html(data);

                        $("#hide_button-'.$data->thread_id.'").click( function() {

                            $("#comments-'.$data->thread_id.'").hide();

                            $("#comments_button-'.$data->thread_id.'").show();

                        });

                    }

                ',

                'beforeSend'=>'js:function(){     

                        $("#AjaxLoader-up-'.$data->thread_id.'").show();

                    }

                ',

                'complete'=>'js:function(){     

                        $("#comments_button-'.$data->thread_id.'").hide();

                        $("#AjaxLoader-up-'.$data->thread_id.'").hide();

                        $("#comments-'.$data->thread_id.'").show();

                    }

                ',

            ),  

            array('class'=>'show_comments','id'=>'comments_button-'.$data->thread_id)

            );  

        ?>

        <br />

    </div>


    <div id="AjaxLoader-up-<?php echo $data->thread_id; ?>" style="display: none"><img src="<?php echo Yii::app()->request->baseUrl; ?>/images/spinner.gif"></img></div>

    <div class="postspopup" id="posts-<?php echo $data->thread_id; ?>" style="display:none;"></div>

    <div class="comments" id="comments-<?php echo $data->thread_id; ?>" style="display:none;"></div>


</div>




here is the form view code :




    public function actionAjaxSaveComment()

    {   

        $model = new Comments;

        $this->performAjaxValidation($model);

        if(isset($_POST['Comments'])) {

            $threads = Threads::model()->findByPk($_REQUEST['thread_id']);

            if (Yii::app()->functions->getPrivacy($threads->user_id, $threads->thread_privacy)) {

                $model->attributes=$_POST['Comments'];

                $model->save();

$valid=$model->validate();                                                                                                                    if ($valid) {

                    $dataProvider=new CActiveDataProvider(

                        'Comments', array(

                            'criteria'=>array(

                                'condition'=>'t.thread_id='.$threads->thread_id,

                                'order'=>'comment_date DESC',

                                'with'=>array('thread','user'),  

                            ),  

                        )); 

                    echo json_encode($this->widget('zii.widgets.CListView',array(

                        'dataProvider'=>$dataProvider,

                        'itemView'=>'_comments',

                        'summaryText'=>'',

                        'id'=>'list_comments-'.$_REQUEST['thread_id']

                    )));

                    //echo CJSON::encode(array('status'=>'success'));

                    Yii::app()->end();

                } else {

                    echo Yii::t('app','Permission denied');

                    Yii::app()->end();

                }   

            }   

        }        

    }   



here is the create controller code :




<div class="form">


<?php $form=$this->beginWidget('CActiveForm', array(

    'id'=>'comments-comments-form-'.$thread_id,

    'enableAjaxValidation'=>true,

    'enableClientValidation'=>true,

    'action' => Yii::app()->createUrl('/site/ajaxSaveComment',array('thread_id'=>$thread_id)),

    // Please note: When you enable ajax validation, make sure the corresponding

    // controller action is handling ajax validation correctly.

    // See class documentation of CActiveForm for details on this,

    // you need to use the performAjaxValidation()-method described there.

)); ?>


    <p class="note">

        <?php echo Yii::t('app','Fields with'); ?><span class="required">*</span><?php echo Yii::t('app',' are required'); ?>

    </p>

    

    <div class="errorMessage" id="formResult-<?php echo $thread_id; ?>"></div>


    <?php echo $form->errorSummary($model); ?>

    <div id="AjaxLoader-<?php echo $thread_id; ?>" style="display: none"><img src="<?php echo Yii::app()->request->baseUrl; ?>/images/spinner.gif"></img></div>

    <?php


    $model->user_id=Yii::app()->user->id;

    $model->thread_id=$thread_id;

    echo $form->hiddenField($model,'user_id'); 

    echo $form->hiddenField($model,'thread_id'); 


    ?>  


    <div class="row">

        <?php echo $form->labelEx($model,'comment_text'); ?>

        <?php echo $form->textArea($model,'comment_text'); ?>

        <?php echo $form->error($model,'comment_text'); ?>

    </div>


    <div class="row buttons">

        <?php echo CHtml::ajaxSubmitButton('Save',CHtml::normalizeUrl(array('/site/ajaxGetComments','thread_id'=>$thread_id,'render'=>false)),

                 array(

                     'dataType'=>'json',

                     'type'=>'post',

                     'update'=>'#comments-'.$thread_id,

                     'success'=>'js:function(data) {

                        $("#AjaxLoader-'.$thread_id.'").hide();  

                        $("#formResult-'.$thread_id.'").html("form submitted successfully.");

                        $("#list_comments-'.$thread_id.'").html(data);

                        $("#comments-comments-form-'.$thread_id.'")[0].reset();

                     }',

                     'error'=>'js:function(data)  {

                        $.each(data, function(key, val) {

                            $("#formResult-'.$thread_id.'").html(data);

                            $("#comments-comments-form-'.$thread_id.' #"+key+"_em_").text(val);

                            $("#comments-comments-form-'.$thread_id.' #"+key+"_em_").show();

                        });

                     }',

                     'beforeSend'=>'js:function(){                        

                        $("#AjaxLoader-'.$thread_id.'").show();

                     }')); ?>




        <?php //echo CHtml::submitButton('Submit'); ?>

    </div>


<?php $this->endWidget(); ?>


</div><!-- form -->



any idea what I miss ?

Thanks

Philippe

complement :

if I add this to the ajax options of the ajaxSubmitButton :




                     'complete'=>'js:function() {

                        $("#AjaxLoader-'.$thread_id.'").hide();  

                     }',



The function is executed (the spinner stop spinning), but the success or error functions are not executed.

Ok I have solved the return of the controller action, now success or error functions are executed, but it remains the double call of the action from the ajaxSubmitButton :(

any idea ?

here is the create controller code :




    public function actionAjaxSaveComment()

    {   

        $model = new Comments;

        if(isset($_POST['Comments']) && $_POST['Comments']==='comments-comments-form-'.$_POST['Comments']['thread_id'])

        {   

            echo CActiveForm::validate($model);

            Yii::app()->end();

        }   

        if (isset($_POST['Comments'])) {

            $threads = Threads::model()->findByPk($_REQUEST['thread_id']);

            if (Yii::app()->functions->getPrivacy($threads->user_id, $threads->thread_privacy)) {

                $model->attributes=$_POST['Comments'];

                if ($model->save()) {

                    $dataProvider=new CActiveDataProvider(

                        'Comments', array(

                            'criteria'=>array(

                                'condition'=>'t.thread_id='.$threads->thread_id,

                                'order'=>'comment_date DESC',

                                'with'=>array('thread','user'),

                            ),  

                        )); 

                    echo $this->widget('zii.widgets.CListView',array(

                        'dataProvider'=>$dataProvider,

                        'itemView'=>'_comments',

                        'summaryText'=>'',

                        'id'=>'list_comments-'.$_REQUEST['thread_id']

                    ),true);

                    Yii::app()->end();

                } else {

                    echo Yii::t('app','Permission denied');

                    Yii::app()->end();

                }   

            }   

        }        

    }   



here is the form view code :




<div class="form">


<?php $form=$this->beginWidget('CActiveForm', array(

    'id'=>'comments-comments-form-'.$thread_id,

    'enableAjaxValidation'=>true,

    // Please note: When you enable ajax validation, make sure the corresponding

    // controller action is handling ajax validation correctly.

    // See class documentation of CActiveForm for details on this,

    // you need to use the performAjaxValidation()-method described there.

)); ?>


    <p class="note">

        <?php echo Yii::t('app','Fields with'); ?><span class="required">*</span><?php echo Yii::t('app',' are required'); ?>

    </p>

    

    <div class="errorMessage" id="formResult-<?php echo $thread_id; ?>"></div>


    <?php echo $form->errorSummary($model); ?>

    <div id="AjaxLoader-<?php echo $thread_id; ?>" style="display: none"><img src="<?php echo Yii::app()->request->baseUrl; ?>/images/spinner.gif"></img></div>

    <?php


    $model->user_id=Yii::app()->user->id;

    $model->thread_id=$thread_id;

    echo $form->hiddenField($model,'user_id'); 

    echo $form->hiddenField($model,'thread_id'); 


    ?>  


    <div class="row">

        <?php echo $form->labelEx($model,'comment_text'); ?>

        <?php echo $form->textArea($model,'comment_text'); ?>

        <?php echo $form->error($model,'comment_text'); ?>

    </div>


    <div class="row buttons">

        <?php echo CHtml::ajaxSubmitButton('Save',CHtml::normalizeUrl(array('/site/ajaxGetComments','thread_id'=>$thread_id,'render'=>false)),

                 array(

                     'dataType'=>'json',

                     'type'=>'post',

                     'success'=>'js:function(data) {

                        $("#AjaxLoader-'.$thread_id.'").hide();  

                        $("#formResult-'.$thread_id.'").html("form submitted successfully.");

                        $("#list_comments-'.$thread_id.'").html(data);

                        $("#comments-comments-form-'.$thread_id.'")[0].reset();

                     }',

                     'error'=>'js:function(data)  {

                        $.each(data, function(key, val) {

                            $("#formResult-'.$thread_id.'").html(data);

                            $("#comments-comments-form-'.$thread_id.' #"+key+"_em_").text(val);

                            $("#comments-comments-form-'.$thread_id.' #"+key+"_em_").show();

                        });

                     }',

                    'complete'=>'js:function() {

                        console.log("complete");

                        $("#AjaxLoader-'.$thread_id.'").hide();  

                     'beforeSend'=>'js:function(){                        

                        $("#AjaxLoader-'.$thread_id.'").show();

                     }'),

                     array('id'=>'ajax_submit_button-'.$thread_id)); ?>




        <?php //echo CHtml::submitButton('Submit'); ?>

    </div>


<?php $this->endWidget(); ?>


</div><!-- form -->



Best.

Philippe

same behavior even with this as parameter to the CActiveForm widget in the form view :




     'enableAjaxValidation'=>false,

     'enableClientValidation'=>false,

     'clientOptions'=>array('validateOnSubmit'=>false), 



and this code commented in the action




        //if(isset($_POST['Comments']) && $_POST['Comments']==='comments-comments-form-'.$_POST['Comments']['thread_id'])

        //{

        //  echo CActiveForm::validate($model);

        //  Yii::app()->end();

        //}



I’m very lost, please help !

On the ajaSubmit button save,

Instead of this, array(‘id’=>‘ajax_submit_button-’.$thread_id));

Try this,array(‘id’=>‘ajax_submit_button-’ . uniqid() ));

I dont really know if that’ll solve your problem regarding duplicate ajax request.

I was assuming you are calling that view form also in ajax,

By the way, wasnt able to read the codes, too long to read.