How to update CGridView with ajax?

I have searched for a solution long time.

Can anyone show me a simple example?

To keep things simple, I want to add names to table.

I have working autocomplete field and an ajax button, which adds name to the database through ajax.

After request is completed, table update should be triggered.

Currently I have no idea, how to use CGridViews properties. What should be returned? I found an example how to trigger update manually and that part works:


'success' => 'js:function(){$.fn.yiiGridView.update("athletes_'.$contest->id.'")}'));

Currently, grid widget creation looks like this:


<?php 

$this->widget('zii.widgets.grid.CGridView', array(

		'dataProvider' => $athletes,

		'ajaxUpdate' => 'contest_'.$contest->id,

		'id' => 'athletes_'.$contest->id,

		'ajaxUrl' => '/admin/contest/updateAthleteList/id/'.$contest->id,));

?>

Same code widget will be returned through ajax.

lets start from zero:

[list=1][]Create a table named: player with 3 columns: idplayer, firstname, lastname, and add some players to it:[list=1][][indent]

idplayer firstname lastname[/indent][indent]

----------------------------------------------------------------[/indent][indent]

1, ‘name player 1’, ‘last name player 1’[/indent][indent]

2, ‘name player 2’, ‘last name player 2’

[i]

[/i][/indent][/list][*]using Gii, create a model named [b]Player.php

[/b][]again using Gii, create a controller for that model, name: ‘player’, with an action: ‘list’[]Creates the actionList on player controller:




public function actionList()

	{

		// for demo propouses, list all players

		$dataProvider = Player::model()->search();


		$this->render('list',array('dataProvider'=>$dataProvider));

	}

[*]In your view: views/player/list.php (this file was created by Gii when you creates your controller, step 3) put the following:[/list]

[indent]




<h1>My Players</h1>

<?php

$this->widget('zii.widgets.grid.CGridView', array(

    'dataProvider'=>$dataProvider,

    'columns'=>array(

        'idplayer',

        'firstname',

        'lastname',

    ),

));

?>

[/indent][indent]

[/indent][indent]6. Test your view: http://localhost/tes...p?r=player/list (use your own URL) it will display a CGridView with your players created in step 1.

[/indent][indent]7. Create a new action in your player controller, named: ‘actionAjaxCreate’[/indent]

[indent]




	public function actionAjaxCreate() {

		$p = new Player();

		$p->firstname = 'new Player firstname';

		$p->lastname = 'new Player lastname';

		if($p->save()){

			echo "OK"; // echo or not, if an exception dont occur then is OK.

		}

		else{

			throw new Exception("Sorry, cant create a player",500);

		}

	}

[/indent]

[indent]

  1. create a "New Player" Button with auto refresh of your grid:[/indent]

[indent]




<h1>My Players</h1>


<!--  CODE TO INSERT NEW PLAYER BEGINS -->

<div id='results'>...</div>

<script>

	function allFine(data) {

		// display data returned from action

		$("#results").html(data);

		// refresh your grid

		$.fn.yiiGridView.update('player-grid');

	}

</script>

<?php echo CHtml::ajaxButton("Insert New Player", array('player/ajaxcreate'), array('success'=>'allFine')); ?>

<!--  CODE TO INSERT NEW PLAYER ENDS -->


<?php

$this->widget('zii.widgets.grid.CGridView', array(

	'id'=>'player-grid',

    'dataProvider'=>$dataProvider,

    'columns'=>array(

        'idplayer',

        'firstname',

        'lastname',

    ),

));

?>

[/indent]

[indent]

  1. test it. It works fine, and will insert a new player refreshing your grid inmediatly.[/indent]

[size=2]Ok, I got that working, although currently i dont understand, why and how this works.[/size]

Where does gridview gets its data? How does it know, where to pull it?

Thank You!

thanks to bluyell, i was watching this thread and tried sample code, it works great to start with.

that was also my question in term of the seems-magic of ajax and jquery,

here is what i found:

when your ajax button success return

it will trigger js function allFine which calls $.fn.yiiGridView.update

in this plugin, yii-1.1.10\framework\zii\widgets\assets\gridview\jquery.yiigridview.js




391: $.fn.yiiGridView.update = function (id, options) {

392:	$('#' + id).yiiGridView('update', options);


330: $.fn.yiiGridView = function (method) {

331:  if (methods[method]) {

332:     return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));


036: methods = {


191: update: function (options) {


// magic begins here .......




hello rootbear,

the gridview ajax update function will perform all dirty work from behind of your eyes, don’t worry abut that. It will ‘reloads’ the last call, you can view how grid.updates it works looking at the browser generated source code (render the view, and when browser presents it, right click on browser and selects: “view source code”).

in the provided example:

the view views/player/list.php will presents you a standar CgridView object, rendered directly from PHP, when it is rendered, the object CGridView will creates a set of JS functions at the bottom of your generated page, this code includes some functionality to provides you the magic-update.

the ajaxbutton, will call an ajax-based action that inserts the new records and informs you the success launching the "allFine" js provided function, when this function detects no error, then uses the magic-update provided automatically by CGridView object.

please let me know about any dude,

@bluyell, did not scratch my head enough to dig deeper yet.

quick question:

does it render the whole list after the ajax button success or if we can simply add new added row only by jquery tricks?

The


$.fn.yiiGridView.update()

actually refreshes the table contents by making another ajax call to the source url.

The response of that ajax call is the full page (head, content etc). From this response, behind the scenes, the grivview div is extracted and replaces the one you see, thus refreshing your table contents.

Adding a new row (skipping the refresh ajax call) could be possible if e.g. the new player ajax call returned

  • the new player data in json format and you build the html and append it

  • the complete html row

in any case you would have to consider the functionality a new row would require (button column? in place edit? etc).

Y.

Just a note… the default code generated by Gii returns the full page, but for any advanced app it’s better to create a partial grid view and return just the grid.

Hi, But what about if you have many gridviews on one page ? it’s go into url trouble

Mohamed

This wiki shows how to update only one of two grids on the page using ajax. It also renders just the grid and not the entire page - as mdomba suggested above in post #8.

See specifically the RoleController’s actionAdmin() “Group B” and “the Ajax”.

http://www.yiiframework.com/wiki/323/dynamic-parent-and-child-cgridciew-on-single-view-using-ajax-to-update-child-gridview-via-controller-with-many_many-relation-after-row-in-parent-gridview-was-clicked/

Apologies for posting to an old thread but I have a very similar situation.

Trying to update the contents of my grid view after an ajax call to an action that triggers some DB changes:


 $.ajax({

    'url': '" . $this->createUrl('//myController/myAction') . "',

    'type': 'post',

    'data': serial,

    'success': $.fn.yiiGridView.update('my-grid'),

   }

});

My problem is that the grid update ajax call seems to be called before my ajax call is completed so although the grid values are updated in the db the changes can only be seen after I manually refresh the page.

As far as I can tell yiiGridView.update does not have a field for async:fasle, how can I solve this issue?

Thank’s you very much…

This help me a lot… I’m newbie in Yii, and it help me to understand CGridView… :)

hi every one?

i have been following this post since i started to learn yii but unfortunately my code is not inserting to the database even after exactly copy pasting the code and even running it in a different browser currently am using Firefox browser version Firefox Setup 29.0b2

my code is like this:

list.php(view)

<h1>My Players</h1>

<!-- CODE TO INSERT NEW PLAYER BEGINS -->

<div id=‘results’>…</div>

<script>

    function allFine(data) {


            // display data returned from action


            &#036;(&quot;#results&quot;).html(data);


            // refresh your grid


            &#036;.fn.yiiGridView.update('player-grid');


    }

</script>

<?php echo CHtml::ajaxButton(“Insert New Player”, array(‘player/ajaxcreate’), array(‘success’=>‘allFine’)); ?>

<!-- CODE TO INSERT NEW PLAYER ENDS -->

<?php

$this->widget(‘zii.widgets.grid.CGridView’, array(

    'id'=&gt;'player-grid',


'dataProvider'=&gt;&#036;dataProvider,


'columns'=&gt;array(


    'idplayer',


    'firstname',


    'lastname',


),

));

?>

the PlayerController.php

<?php

class PlayerController extends Controller

{

public function actionList()


{


	 // for demo propouses, list all players


            &#036;dataProvider = Player::model()-&gt;search();





            &#036;this-&gt;render('list',array('dataProvider'=&gt;&#036;dataProvider));


}








 public function actionAjaxCreate() {


            &#036;p = new Player();


            &#036;p-&gt;firstname = 'new Player firstname';


            &#036;p-&gt;lastname = 'new Player lastname';


            if(&#036;p-&gt;save()){


                    echo &quot;OK&quot;; // echo or not, if an exception dont occur then is OK.


            }


            else{


                    throw new Exception(&quot;Sorry, cant create a player&quot;,500);


            }


    }





// Uncomment the following methods and override them if needed


/*


public function filters()


{


	// return the filter configuration for this controller, e.g.:


	return array(


		'inlineFilterName',


		array(


			'class'=&gt;'path.to.FilterClass',


			'propertyName'=&gt;'propertyValue',


		),


	);


}





public function actions()


{


	// return external action classes, e.g.:


	return array(


		'action1'=&gt;'path.to.ActionClass',


		'action2'=&gt;array(


			'class'=&gt;'path.to.AnotherActionClass',


			'propertyName'=&gt;'propertyValue',


		),


	);


}


*/

}

or am my suppose to configure the ajax in the config/main.php? if yes how?

PLEASE HELP