return javascript snippet from controller

Hey Guys!

What I want to do, is the following:

  • I have a form with an ajax button to post the content

  • after a post with valid data, I simply want to *.hide() the form div and *.show() another div.

I thought of solving this by returning something like this from the controller:


echo CHtml::script('newsletter_post();');

But it just doesn’t want to work.:frowning:

I also remember something from (i guess it has been the blog example) returning something like this (flash):


Yii::app()->user->setFlash...

I don’t really want to use a flash message, but doesn’t there exist something like that for my problem?

Or maybe anyone has an idea for any other solution?

Thanks a lot in advance,

Mayjestic

How are you fireing off your ajax requests? jQuery.ajax objects have got a success callback which might be suitable for your needs.

Ahh thanks, I totally forgot about that :-D.

Well, now it works, but the problem is, that even in an error case it acts like the action was successful (maybe, because I dont return anything at the moment from the server (controller)).

How do I "catch" the return value and decide in the view / ajaxSubmitButton if the post has been successful or not? … and what kind of return value would do it? I guess a bool value would be enough for this …

jQuery.ajax decides if a request was successful or not by the returned http status code. Just throw a CHttpException if something went wrong.

Thanks a lot Sourcerer!

The only problem, that is left now is:

For the case, the edit fields arent even touched, there is no ajax / client validation messages shown. So if the user now directly clicks on the submit button, I want to "validate" the user inputs and return the error messages.

I’ve seen this working with the ORM generated yii code. But it’s not working for me and I just cant figure out why the hell…?? :stuck_out_tongue:

Maybe someone could explain to me, how the validation works in this stage?

So far I know its like that:

  • in the controller I "echo CActiveForm::validate($model);"

  • this returns a json string to the client pc

  • but there also must be a js file from yii, which sets the classes / ids to "validating", "error" "success" or whatever …

Well … some help / ideas on this would be awesome!

Thanks a lot guys,

Mayjestic

You need to enable CActiveForm.enableAjaxValidation for that. However, I’m not entirely sure how you are going to determine whether an ajax call is intended for validation or for saving the model. You might try to send the data to different actions: One for ajax validation and one for model saving.

What I’m doing is, I use ClientSideValidation for leaving the focus of the singe edit fields. And on post I want to use a validation from the server, but I cant get it to work …

My Code looks as follows:

_form.php


<div class="form">

    <?php

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

                'id' => 'newsletter-form',

                'enableClientValidation' => true,

                'focus' => array($model, 'name'),

            ));

    ?>


    <div class="row">

        <?php echo $form->label($model, 'name'); ?>

        <?php echo $form->textField($model, 'name', array('size' => 36, 'maxlength' => 128, 'class' => 'input_focus', 'style' => 'width: 235px')); ?>

        <div style="clear:both;"></div>

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

    </div>


    <div class="row">

        <?php echo $form->label($model, 'email'); ?>

        <?php echo $form->textField($model, 'email', array('size' => 36, 'maxlength' => 255, 'class' => 'input_focus', 'style' => 'width: 235px')); ?>

        <div style="clear:both;"></div>

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

    </div>


        <p style="float:left; color:#999999; font-size:11px; margin:5px 0 20px; width: 240px;">Je nach Projektphase werden wir ausgewählte Personen über weitere Schritte informieren.</p>

        <div class="row buttons">

        <?php echo CHtml::ajaxSubmitButton('ok', $this->createUrl('newsletter/create'), array('success'=>'js:function(data){$("#newsletter .form").hide();

        $("#newsletter-confirm").show();}', array('class' => 'dialog_input_button, green_button')); ?>

    </div>




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


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

actionCreate:


  public function actionCreate()

    {

        $model = new Newsletter;


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

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


            if ($model->save()) {

             // do nothing

            } else {

                echo CActiveForm::validate($model);

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

            }

        } else {

            $this->render('create', array(

                'model' => $model,

            ));

        }

    }

At:

echo CActiveForm::validate($model);

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

it validates the model, if the save($model) fails … and it returns the json object correctly (firebug console) … but it hasnt the effect it should have … switching the id’s/classes to “error” and show the error messages.

Any suggestion?

I think the CActiveForm.validate()-call is bogus. If you call CActiveRecord.save(true), validation will be performed within the model. CActiveForm.validate() is only useful in conjunction with ajax validation.

Hmm… yeh, you might be right, but how could I solve this then? Any idea?

With CActiveForm::validate I at least get the expected json object back to the client…

The problem is that you’d like to pass your data via ajax. It would be much easier without that :rolleyes:

So here’s what you need to do:

[list=1]

[*]Set CActiveForm.enableAjaxValidation to true

[*] Set CActiveForm.action to array(‘newsletter/validate’) (I’m assuming your controller is being called NewsletterController)

[*] Add a new action to your NewsletterController like this:




public function actionValidate()

{

  if(Yii::app()->request->isAjaxRequest && isset($_POST['Newsletter]))

  {

    $model=new Newsletter;

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

    echo CActiveForm::validate($model);

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

  }

  else

    throw new CHttpException(404,'Please do not do that again.');

}



[*] Check if your ACLs allow users to actually reach newsletter/validate

[/list]

Thanks a lot for your help again, Sourcerer.

The problem is, that my aim was:

  • validate the single edit fields (onFocus/blur) with clientValidation

  • submit button = ajaxSubmitButton

  • after clicking on submit, the fields should of course be validated as well, using the same error messages like the client validation

My problem is now:

  • the client validation works perfectly

  • after clicking on submit (with wrong / no data in the edit fields --> validation fails), I am able to send the correct JSON Object back to the client. But he just doesn’t show the relevant error messages. And this is the point, I really don’t understand at the moment … how could this be, that if I’m using the ajaxValidation for the single edit fields I get the same JSON string returned. But in this case the error messages show up and in the other it doesn’t?

Thanks for your endurance by the way :wink:

bump

I didn’t follow all the messages, but this is the way to do it


$this->widget('CActiveForm',array(

  'clientOptions'=>array(

	'validateOnSubmit'=>true,//ajax validation on submit

 	'validationUrl'=>array('validate'),//only if you want to use a separeted action to do the validation, like you posted above, you can use the normal ajax validation code if you want

  ),

  'enableAjaxValidation'=>false,//defaults to false, no need to set

  'enableClientValidation'=>true//defaults to true, no need to set

)); 

Thanks a lot for your answer Gustavo!

I guess I must have a bug somewhere else … with your way it actually does the same like before. It returns the JSON Object as expected to the client and everything works fine, except that the messages don’t “pop up” … maybe there’s something wrong with the jquery.yiiactiveform.js? Would this be a possibility? … i mean the file is loaded and all, … damned it … how can so little things be so frustrating? :angry:

jquery.yiiactiveform.js

line 306


if (!this.enableAjaxValidation)

     delete data[this.id];

You need ajax validation set to true, but as it is set to validateOnSubmit, it will work as you expect