Understanding widgets and searching

I am a fairly new user to Yii and a very new user to the concepts of widgets. I believe I am comfortable creating and using a widget, but I am running into a problem that I can’t seem to figure out.

So, I have a widget call that looks like this:

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


    'id' => 'account-grid',


    'dataProvider' => Account::model()->search(),


    'filter' => Account::model(),


    'columns' => array(


        'company_name',


        array(


            'class' => 'CLinkColumn',


            'label' => 'Select account',


            'urlExpression' => 'account/'.$data->id


            ));',


        ),


    ),


));

So this widget call creates the view just fine. I look at it, and I see a list of accounts with a text box above it where I can (presumably) type into the text box and see the filtered account list. However, this is the problem. I type something in the text box and nothing happens, no filtered list, it is as if it has done nothing.

Can someone give me a direction to go or something look into? I have spent the last few hours searching for an answer, but I have been unsuccessful so far.

Hello Lebowski, welcome to the forum.

CGridView is a very powerful widget, and it will help you very much. So I think you are on the right track when you are starting with it.

Now, what you have to do, I think from my own experience, is to read the gii generated codes for admin action carefully. Not just the actionAdmin() method of the controller, but also the view(‘admin.php’), the search form(’_search.php’), the javascripts in them, and the search() method in the model. They are all related when you use the grid.

And in addition, reading the generated HTML code of the admin page will help you understand the grid a lot.

1: First, it creates an instance of a model in actionAdmin.

It is not meant for the container for the data to be displayed in the grid. It’s a holder of the search parameters.

2: Clear the contents of the model instance to give it the default empty search parameters.

3: Check to see if $_GET[‘Model’] is defined. When it’s the first time around, $_GET[‘Model’] will not be defined.

4: If $_GET[‘Model’] is defined, then it means that the action has been called from the admin view with some search parameters defined. Then we will set the search parameters to the model attributes according to $_GET[‘Model’].

5: Render an admin view passing the model instance with the name of ‘model’.

6: In the view, the CGridView widget will be created with the ‘dataProvider’ property set as ‘$model->search()’. That means the search() method of the model will create a data provider and give it to the grid. When the instance of that model is empty (that is the case when it’s the first time around), then all the data will be displayed in the grid. But when it has something defined, for example, $model->company_name is defined (that can be the case when the action was called the 2nd time and after), then search() method will create some WHERE clause to filter the search results according to the attributes, and eventually the grid will show you the filtered results.

7: Also in the view, a form for ‘advanced search’ will be created. Each field of the form has a ‘name’ in the format of “Model[attribute]”, so that the form can send back and forth the search parameters contained in the model instance to the admin action.

See how the CActiveForm is used to create the search form using the model in ‘_search.php’.

8: Usually the CGridView also has a property ‘filter’ set to the model. It’s roughly equivalent to the model usage in the advanced search form. It will create the header filter fields with the same naming convention.

There are more things to learn about the grid, pagination and sorting, for example.

But understanding the basic structure stated above will surely be a help, I hope. :)

Thank you. I figured out my problem. I was creating a new object on the fly (Account::model()->search()) Whereas, I SHOULD have been creating the object in the controller and setting the search term in the object, then using that object to perform the search.

Added this to the controller:

$account_search = $this->view->account_search = Account::model();


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


{


	$account_search->attributes=$_GET['Account'];


}

And added this to the view:

$account->search();

Thanks for all the help.

Yes, that was the point. :)

But I don’t understand the following line in your code:

Is there any specific reason for you to write like that?

I would rather follow the example of actionAdmin and write like this:




	$account_search = new Account::model('search');

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

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

	{

		$account_sarch->attributes = $_GET['Account'];

	}

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

		'account'=>$account_search,

	));

	....

// in the view

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

	'id' => 'account-grid',

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

	....



Note that you can pass any local variables to the view file using the 2nd parameter of CController::render().

http://www.yiiframework.com/doc/guide/1.1/en/basics.view

And the model instance should be created with the ‘search’ scenario. Otherwise the massive assignment




		$account_sarch->attributes = $_GET['Account'];



may fail in some attribute.