invoke ajax action in another controller action?

Here is what I am trying to do:

There is a user registration form on a page. After the registration is complete, display a message "you are successfully registered" replacing the registration form and without loading the whole page.

I want to invoke the ajax action in a controller action:


public function actionRegister()

	{

		$form=new UserRegForm;


			if(isset($_POST['UserRegForm']))

			{

		    	$form->attributes=$_POST['UserRegForm'];

		    	if($form->validate())

		    	{

                        	$user = new User;

                        	$user->attributes = $form->attributes;

                        	$user->password = md5($user->password);

                        	$user->save();

                        	

                        	$this->actionAjax101(); // registration is successful, let's replace the form with a success msg


					

		        	// form inputs are valid, do something here

		        	return;

		    	}

			}

			$this->render('_RegForm',array('model'=>$form));

		

	}


public function actionAjax101()

    	{

        	$this->renderPartial('ajax101', array(), false, true);

    	}

This is the ajax101.php view file:


<?php

echo 'the user has been successfully registered';

?>

The result is a white screen with only ‘the user has been successfully registered’. Where do I put array(‘update’=>’#forAjaxRefresh’) in a controller action?

I know it may be an wrong approach to solve this problem. Can you help?

Thank you!

You need to make a call to the server using AJAX in the first place. As far as I can understand, you simply submit a form to the server, but this action will lead to full page refresh.

Van,

I think you are right. According to tutorial, there should be sth like this in view file:


<?php echo CHtml::ajaxLink('clickMe', array('ajax'), array('update'=>'#forAjaxRefresh'));?>

so when user click this link, the div with #forAjaxRefresh will be updated. I want to replace the form with a message,

after user clicks the form submit button, and also when user is successfully registered.

What should I do to accomplish this objective?

Thanks!

I am new to ajax and yii. Maybe I am demanding sth that is not possible or not the best practice. Please help~

Can you paste your registration form view?

Sure


<div id="ajax101">

	<div class="form">


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

            	'id'=>'user-reg-form-_RegForm-form',

            	'enableAjaxValidation'=>false,

    	)); ?>


            	<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,'first'); ?>

                    	<?php echo $form->textField($model,'first'); ?>

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

            	</div>


            	<div class="row">

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

                    	<?php echo $form->textField($model,'last'); ?>

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

            	</div>


            	<div class="row">

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

                    	<?php echo $form->passwordField($model,'password'); ?>

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

            	</div>


            	<div class="row">

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

                    	<?php echo $form->passwordField($model,'passwordRepeat'); ?>

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

            	</div>







            	<div class="row buttons">

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

            	</div>


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


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

</div><!-- div id="ajax101" -->

Okay, so where you have:


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

Put something like:


<?php echo CHtml::ajaxSubmitButton('Submit','/path/to/controller/action',array('update'=>'user-reg-form-_RegForm-form')); ?>

Ref:

http://www.yiiframework.com/doc/api/1.1/CHtml/#ajaxSubmitButton-detail

As a side note, any reason why the id is so long? :)

Forgot, if you want to have something like a loading message (sounds like you might), you can try this:


<?php echo CHtml::ajaxSubmitButton('Submit','/path/to/controller/action',array(

    'update'=>'user-reg-form-_RegForm-form',

    'beforeSend'=>'$("#user-reg-form_RegForm-form").html("Loading...")'

    )); ?>

ref:

http://api.jquery.com/jQuery.ajax/

Bsetp,

Thanks a lot! I was really excited about your code.

The long ID for the form is auto generated by gii. I am worrying about changing it may result unpredictive behavior (I am still new).

Here is the code


            	<div class="row buttons">

                    	<?php echo CHtml::ajaxSubmitButton('Register', array('ajax101'),

                            	array('update'=>'#login-form',

                                  	'beforeSend'=>'$("#login-form").html("Sending...")'

                                	)); ?>

            	</div>

But the it stops with “Sending…”. Do you think it’s because


array('ajax101')

is wrong?

Another issue with


 <div class="row buttons">

                        <?php echo CHtml::ajaxSubmitButton('Register', array('ajax101'),

                                array('update'=>'#login-form',

                                        'beforeSend'=>'$("#login-form").html("Sending...")'

                                        )); ?>

                </div>

is it doesn’t show form validation error. The whole form is replaced by “Sending…”. gosh… I feel dizzy~

Use a plugin like Firefox’s FireBug or the built-in dev tools of Chrome or Opera to see what is being sent/received to/from the server when you click your “Register” button. The way your controller is written, if your input has anything invalid, the form will be rendered to the browser again.

I do suspect there’s a problem with your ‘ajax101’ path. Your action is called “actionRegister” in the code you pasted. If actionRegister is in the controller called “user”, your path should be ‘user/register’.

Hi,

Did you read the ajaxSubmitButton api reference?

You need to read two sections there, i think, one and two.

Now,the second argument is the one for the controller action, so you have to pass the action for register, as from there you are calling the actionAjax101();


<?php echo CHtml::ajaxSubmitButton('Register', array('controllername/register'), // instead of array('ajax101')

                                array('update'=>'#login-form',

                                        'beforeSend'=>'$("#login-form").html("Sending...")'

)); ?>



Further the third parameter for ajaxSubmitButton is ‘ajax options’, which is identical to the ajax options of the jQuery ajax function, you can find that reference here.

Also, then what happens is that you have to make sure that the array(‘update’=>’#xyz’), points to a valid <div> id in your form. Currently from what i see, your form doesn’t have any <div id=login-form>, so you will need to change that, if you haven’t already.

Plus, if you will read the jQuery doc, you’ll see that this update parameter, is the html div that is updated once the ajax call returns, hence you actually don’t need the ajax101 view, nor do you need the action ajax101. You can modify the actionRegister in the following way:




actionRegister(){

// ........

// wherever you are calling action ajax101, you can just echo back a response

// so instead of $this->actionAjax101(); you can just echo the following

echo "user has been successfully registered";

// ..........

}



I am a newbie too, but i just tried some ajax stuff, so i’m pretty sure that i’m right. Do tell if it works, coz i haven’t tested your code.

The ID I referenced is coming from his CActiveForm widget in this part of his view file:


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

                'id'=>'user-reg-form-_RegForm-form',

                'enableAjaxValidation'=>false,

        )); ?>

That will be the HTML ID of the <form> tag in the HTML of the rendered page. Now that I read your reply though, I realized I made a mistake. He needs to replace the id=#ajax101 div tag rather than doing an "update" on the form tag mentioned above. This is because if the form view is spit back by the register action due to invalid input, it spits back this entire chunk of the page, including the #ajax101 div and the CActiveForm within it.


<?php echo CHtml::ajaxSubmitButton('Submit','/user/register',array(

    'replace'=>'#ajax101',

    'beforeSend'=>'$("#ajax101").html("Loading...")'

    )); ?>

Hmm, i agree, replace will be better.

Btw, i have just posted a question, please see if you can help me out. :)

Thank you, everyone!

You’re welcome!