1
votes

I am trying to understand how sorting works in GridView by means of generating a default CRUD application. Sorting happens after clicking the respective attribute which is the table header. The column name is attached to the url with the variable sort and on click the action method is invoked, but what I am wondering is that the action method which is mentioned in the url with the actual variable $sort is not present in the controller.

Below is a example

The url looks like the below,

/advanced/frontend/web/index.php?r=site%2Findex&sort=customer_user_name2

But there is no corresponding action method in the site controller as function actionIndex($sort);

1

1 Answers

0
votes

Consider following example

We have Passenger CRUD

Consider Passenger - a model and PassengerSearch - its corresponding search model

Passenger attribute are id, name and country_name

In PassengerController.php

<?php
...
public function actionIndex()
{
    $searchModel = new PassengerSearch();    
    $dataProvider = $searchModel->search(Yii::$app->request->queryParams);

    return $this->render('index', [
        'searchModel' => $searchModel,
        'dataProvider' => $dataProvider,
    ]);
}
...
?>

Search string a in name column and sort id column in desc order

Look at the url generated, it would be like

`http://localhost/YII2proj/passenger/index?PassengerSearch%5Bid%5D=&PassengerSearch%5Bname%5D=a&PassengerSearch%5Bcountry_name%5D=&sort=-id`

In human readable format

http://localhost/YII2proj/passenger/index?
PassengerSearch[id]=&
PassengerSearch[name]=a&
PassengerSearch[country_name]=&
sort=-id

Observe PassengerSearch is a array. Please refer - How to send a array in url request?

Focus on the parameter to search() method of object PassengerSearch class it is Yii::$app->request->queryParams

Before $dataProvider = $searchModel->search(Yii::$app->request->queryParams);

line, insert following code

echo '<pre>';
print_r(Yii::$app->request->queryParams);
echo '</pre>';
die;

and see the result

Array
(
    [PassengerSearch] => Array
        (
            [id] => 
            [name] => a
            [country_name] => 
        )

    [sort] => -id
)

If no searching sorting done, then this array will be empty

So this line does your code like following

<?php
if(isset($_GET['sort']) ||  isset($_GET['PassengerSearch']['id'] ...)
{
    // validate it because what if I changed url like
    // `http://localhost/YII2proj/passenger/index?PassengerSearcasdh[dfsid]=&PassengerSearch[name]=a&PassengerSearch[country_name]=&sorsfdft=-idadlashdfhls`
    // ie some scrap value
    // If error returned from validate function, default sorting is done, and malformed search param is not set
    // if success, fill up that array
}
?>

Then in search Model load() is the hero.

Where and how above code is done? - Refer Model and load()

Searching is done via andFilterWhere after loading ie load() and that you can see in search() method

Hope you got the idea behind searching and sorting.