GridView AJAX requests entire page

I just created my first Yii app, which was a breeze - especially when using Gii. I did, however, notice the absence of an AJAX action for the GridView. As it turns out, it just pulls in the entire admin page every time you use the filters, search or pagination.

So I wondered: is this just to save on code, or am I missing something crucial here?

I wondered about same thing. It turns out, GII generates very inefficient code for GridView. When GridView sends AJAX request, it gets the entire page back. Then, using JQuery $.filter method, it selects the part of HTML which contains the grid contents and swaps it with the current grid.

This is all very fascinating, but it kind of defeats the purpose of AJAX (which is to get back only the data you need instead of the entire page, which can contain several asynchronous grids). So here’s what I did:

  1. I created a new view, "_grid.php", and moved GridView widget call there:

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

	'id'=>'orders-grid',

	'dataProvider'=>$model->search(),

	'filter'=>$model,

	'columns'=>array(

		....

	),

)); ?>

  1. In admin.php, instead of calling GridView, I wrote:

<?= $this->renderPartial('_grid', array('model'=>$model)); ?>

  1. And, finally, in actionAdmin:

public function actionAdmin()

{

	$model=new Order('search');

	$model->unsetAttributes();  // clear any default values

	if (isset($_GET['Order']))

		$model->attributes=$_GET['Order'];

	

	if ( $_GET['ajax'] == 'order-grid' )

	{

		$this->renderPartial('_grid', array('model'=>$model));

		return;

	}


	$this->menu = $this->getSideMenuItems();

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

		'model'=>$model,

	));

}

Here you go: instead of regenerating the entire page you send back only the data for the grid which is being updated.

I’m considering posting this to Issues, because, really, this kind of thing in default GII templates simply isn’t right. Actually, it’s not the only drawback of default templates. Check side menu generation: each CRUD view has it’s own definition of the same menu items. Code duplication -> invitation to errors. Because of this I ended up creating my own set of GII CRUD templates.

Welcome both to the forum!!

I agree with you, the CGridView is a bit inefficent, we can do better by changing the CRUD templates.

Just pay attention to the id: if you have some component that generate client scrupt code with an id (like yt0, yt1 and so on) BEFORE the CGridView, you can have some problem, because the id of the generated subveiw will be diffrent from the original.

Anyway, I think that the default code is just a sample, not a finished product, you have to work on it and create your application.

It is also a sample for help people understanding the principle of the framework, if it would be too difficoult newbies would have a harder learning curve.

If you have better proposals, just share to the community, we can prepare a new proposal for an alternative template.

Ah, thank you, [member=‘zaccaria’], it’s a good notion about auto generated ids. Though, as far as I understand it, the problem will arise only if you use some kind of autogenerated scripted links/buttons/whatever in CGridView (ajaxLinks, for example).

CGridView itself doesn’t use such elements by default, and, fortunately, you can specify the ID for the grid via it’s options. So there won’t be any ytN ids in CGridView at all.

As for ajaxLinks and the likes of them, I avoid using such code in a piece of HTML which is updated via AJAX. The inner workings of AJAX-using scripts can be somewhat subtle sometimes, and I find it safer and simpler when I control such code completely.

I also agree with your point that default GII templates are in fact a sample, and a good one. And because of that they contain some things which are not needed in a normal backend. For example, in my CRUD templates the default admin view is used as index, and the old index is removed entirely. However, in this particular instance - I mean, grid AJAX update - the default template is misleading, especially for newbies who may not even think to check how it works, and can be very surprised to learn about requesting the entire page.

As to my proposal for fixing this grid issue, well, I’ve stated it above. Transform grid into partial view.

About the abovementioned menu item code duplication in default templates… considering your very valid point about default code being an example and a demo - probably nothing. For my own templates I’ve added a special function to controller which contains all menu item definitions and combines them for various actions according to the settings which look like this:


array(

	'index'	 => array( 'create' ),

	'create' => array( 'index' ),

	'view'	 => array( 'index', 'create', 'update', 'delete' ),

	'update' => array( 'index', 'create', 'view', 'delete' )

);

A bit slower, much safer, much easier to modify. The implementation is debatable, though, and should it be in a demo? Not sure…

P.S. Thank you for welcoming us. :slight_smile: Though actually I’ve been around for at least a year… just in read-only mode. :slight_smile: