You are viewing revision #5 of this wiki article.
This version may not be up to date with the latest version.
You may want to view the differences to the latest version or see the changes made in this revision.
The most easy way to update content in AJAX is to use the partialRender method.
For this exemple I have three files: a controller (HelloWorldController.php) and two views (index.php and _ajaxContent.php)
controllers/HelloWorldController.php ¶
class HelloWorldController extends CController
{
public function actionIndex()
{
$data = array();
$data["myValue"] = "Content loaded";
$this->render('index', $data);
}
public function actionUpdateAjax()
{
$data = array();
$data["myValue"] = "Content updated in AJAX";
$this->renderPartial('_ajaxContent', $data, false, true);
}
}
The actionIndex set myValue to "Content loaded" and this variable is passed to the view "index.php" and to "_ajaxContent.php"
Note: if using accessRules() in your controller file, you will need to modify accessRules() by adding the appropriate part of the function name to a rule set - in this case 'updateajax' like this:
array('allow', // allow all users to perform 'index' and 'view' actions
'actions'=>array('index','view','updateajax'),
'users'=>array('*'),
),
views/helloWorld/index.php ¶
<div id="data">
<?php $this->renderPartial('_ajaxContent', array('myValue'=>$myValue)); ?>
</div>
<?php echo CHtml::ajaxButton ("Update data",
CController::createUrl('helloWorld/UpdateAjax'),
array('update' => '#data'));
?>
The ajaxButton call "actionUpdateAjax" and the returned data are inserted in the div "data"
views/helloWorld/_ajaxContent.php ¶
<?php echo $myValue ?>
Display $myValue
Now, run index.php?r=helloWorld
Enjoy!
Notice that example has processOutput=true
The fourth parameter to renderPartial() is processOutput and it defaults to false. Note that it is set to true in actionUpdateAjax(). I've never paid any attention to this parameter until I tried to load a form through AJAX and the form has widgets on it. The widgets did not work because they weren't getting initialized by the usual call to .ready(). The solution seems to be processOutput=true. With that, the initialization code gets put into the HTML that is returned by the ajax call. My ajax-form-with-widgets now works.
No need for 2 actions
Instead of using 2 actions you can put all logic in one.
if(Yii::app()->request->isAjaxRequest)
{
$this->renderPartial('_ajaxContent',$data);
}
else
{
$this->render('index',$data);
}
process output
Pay attention that this fourth parameter set to true can create conflict with existing widgets outside the rendered subform.
This can happen because Yii uses a counter for generate the widget ID, and if you are not rendering all the widget (if there are some outside your panel) the new widget will have the same Id of the external.
A partial solution for this problem is to set a unique Id for each compoment inside the rendered panel, this solves many problem
Good
this is the kind of tutorials that I need!
Wonderful
Thanks for this wonderful tutorials .
Below is the code for radio button list
<?php echo CHtml::radioButtonList( 'cars','4', array(4 => 'GM', 5 => 'FORD'), array('separator' => '', 'onChange'=>CHtml::ajax(array('type'=>'GET', 'url'=>array("editProfile/UpdateAjax"), 'update'=>'#data'))));
YII FAN
The best shortest clear example!
Thank you my friend, thank you for sharing such a simple example which shows the whole concept of AJAX using Yii. I think this is the most beautiful and clear example I've ever seen together with some Android Java examples. Thank you!
You're welcome
@socialdev
@vasireddy
@nettrinity
You're welcome! I'm still woking with yii (of course, it's the best framework ever :) ), when I'll have more time I'll do more simple tutorials like this one :)
Instead of the ajaxButton you can also use an ajaxLink
echo CHtml::ajaxLink('clickMe', array('ajax'), array('update'=>'#ajax-results'));
This will call actionAjax() in the controller and the div with id 'ajax-results' will be updated.
Great tutorial by the way - thanks!
Code for the Dropdown
If you need to updated the contents of a div through the onchange event of the dropdown then use the following code.
echo $form->dropDownListRow($model,'vehId', $listVeh , array( 'empty'=> 'Select Vehicle', 'ajax' => array( 'type' => 'POST', 'url' => CController::createUrl('UpdateAjax'), 'data'=> array('vehId'=>'js: $(this).val()'), 'update'=>'#data', ) ) );
nice article
its very helpfull article.
Nice!
Good work man, I like it!
help me plz :)
thx great article but I have a problem.. :s (certainly a stupid newbie problem :p)
so in my view, I have a form with several option, then I put a comboBox with 2 choices.
depending of this choice, I show different options in my form.
So I put this in my radioButton,
'onChange'=>CHtml::ajax(array( 'type'=>'POST', 'url'=>array("admin/UpdateAjaxFormGestionnaire"), 'update'=>'#gestionnaireCell')),
then this in my controller
public function actionUpdateAjaxFormGestionnaire() { $this->renderPartial('_ajaxContentFormGestionnaire', array( 'eventForm'=>$eventForm, 'gestionnaire'=>$gestionnaire, ), false, true); }
and this in my _ajax view file :
<td class="enableCreate"> <div class="row"> <?php echo $form->labelEx($eventForm,'Nom'); ?> <?php echo $form->textField($eventForm,'Nom',array('size'=>50,'maxlength'=>50)); ?> <?php echo $form->error($eventForm,'Nom'); ?> </div> <div class="row"> <?php echo $form->labelEx($eventForm,'Prenom'); ?> <?php echo $form->textField($eventForm,'Prenom',array('size'=>50,'maxlength'=>50)); ?> <?php echo $form->error($eventForm,'Prenom'); ?> </div> ...
But the problem is that the $form widget is not initialized or passed or ... in the _ajax file. So I have this error :
Fatal error: Call to a member function labelEx() on a non-object in D:\WWW\VincentM\LayoutColloques\protected\views\admin\_ajaxContentFormGestionnaire.php on line 4
do you have any idea to help me?
thx in advance.
@VincentM
Thanks!
I see your problem, in your _ajax something is missing:
<?php $form=$this->beginWidget('CActiveForm', array( 'id'=>'news-form', 'enableAjaxValidation'=>false, )); ?> .... your form ... <?php $this->endWidget(); ?>
That's it :)
thx again :)
edit : [Problem Solved]
thx for your response, but I made something else. I send the form to the controller and then to the view with GET option. I don't know if it is possible with POST :/
If you wan't to keep helping me I posted that on the forum at this link :http://www.yiiframework.com/forum/index.php/topic/51416-how-to-send-a-cactiveform-widget/
But thanks again for your article, it helped me a lot :)
Update Modal Window
Hi, I need to update a modal window and show it when I click in the edit button.
CONTROLLER:
public function actionUpdateAjax($id) { $contratos = ZfContratos::model()->findByPk($id); $this->renderPartial('//ZfContratos/_form_update', array('model'=>$contratos), false, true); }
INDEX:
<?php $this->beginWidget( 'bootstrap.widgets.TbModal', array('id' => 'actualizar_contrato') ); ?> <div class="modal-header"> <a class="close" data-dismiss="modal">×</a> <h4>Actualizar contrato</h4> </div> <div class="modal-body"> <?php $this->renderPartial('//ZfContratos/_form_update', array('model'=>$contrato));?> </div> <div class="modal-footer"> <?php $this->widget( 'bootstrap.widgets.TbButton', array( 'label' => 'CANCELAR', 'url' => '#', 'htmlOptions' => array('data-dismiss' => 'modal'), ) ); ?> </div> <?php $this->endWidget(); ?>
AND VIEW _contratos
At this moment I have this:
<?php echo CHtml::link('EDITAR', array('//ZfInmuebles/UpdateAjax', 'id'=>$data->zf_contrato_id), array('class'=>'btn', 'id'=>'vermas')); ?>
But I need that to be an ajaxbutton or ajaxlink, that refresh the div "actualizar_contrato" and show it.
How to redirect if success submit form
I have a form, how to redirect if success submit form with model validation and ajax request ? thx
Redirection after validation
@kuncolaksmono if you want to perform a redirection after the validation, you can simply return a piece of javascript instead of html in "_ajaxContent.php" like:
<script type="text/javascript"> window.location = 'your-url'; </script>
Is that ok?
How can I update view if I trigger Ajax from js?
I want to update _partialCategory.php when user clicks on parent category.
Schenario:
I m able to populate parent category.
I m also able to make a ajax call to the controller but I m not able to update view based on new data from ajax call.
getChildCategory.js
`
javascriptvar url = '/site/get-child-category';
var data = { id : parentId}; $.ajax({ url: url, type: 'get', dataType: 'json', data: data }) .done(function(response) { if (response.data.success == true) { alert(response.data.message); } }) .fail(function() { console.log("error"); }); }
index.php ```php <?= $this->render('_signupCategory', array('category'=>$category)); ?>
_partialCategory.php
`
phpforeach ($category as $item) { ?>
<div class="cat-wrapper category"> <div class="card-block radio"> <div class="row justify-content-center d-flex"> <div class="cat-icon"> <i class="<?= $item['imagepath'] ?>"></i> </div> </div> </div> <h5 class="cat-name"><?= $item['name'] ?></h5> <p class="cat-id" value="<?= $item['id'] ?>"></p> </div>
<?php } ?>
`
Sitecontroller.php
`
phppublic function actionGetChildCategory($id){
$category = Category::find() ->where(['parent_id' => $id]) ->orderBy('id') ->asArray() ->all(); if (Yii::$app->request->isAjax) { Yii::$app->response->format = Response::FORMAT_JSON; if ($category != null) { $message = 'Please select child category'; return [ 'data' => [ 'success' => true, 'data' => $category, 'message' => $message, ], 'code' => 0, ]; } else { return [ 'data' => [ 'success' => false, 'data' => null, 'message' => 'An error occured.', ], 'code' => 1, // Some semantic codes that you know them for yourself ]; } }else{ return "Outside isAjax"; } }
@Shubham Agrawal
This article is for Yii1, and you are using Yii2 ;)
You get your data with your JS in JSON so you have to build the html on the client side. If you want to return HTML directly you have to render the view.
$.get("/get-child-categories", function(data) { $("#div-with-children").html(data); })
public function actionGetChildCategories($id) { //get the children //$children = ... // renders a view named "view" and applies a layout to it return $this->render('children', [ 'children' => $children, ]); }
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.