Reputation: 180
I am using GridView to display some data. I need to add default sorting by 2 columns as follows:
(CASE
WHEN (inbound_datetime IS NULL AND outbound_datetime < NOW()) OR (inbound_datetime IS NOT NULL AND inbound_datetime < NOW())
THEN 9999
WHEN (inbound_datetime IS NOT NULL AND outbound_datetime < NOW())
THEN inbound_datetime
ELSE outbound_datetime
END) ASC
If I add this code in the ORDER BY
clause in the data provider query, then all of the other sorting options don't work because this condition is applied to the query itself.
I tried to apply the default sorting as I would to any other grid, but it is not working (the method searches for an attribute with that name):
'sort' => [
'defaultOrder' => [
'(CASE
WHEN (inbound_datetime IS NULL AND outbound_datetime < NOW()) OR (inbound_datetime IS NOT NULL AND inbound_datetime < NOW())
THEN 9999
WHEN (inbound_datetime IS NOT NULL AND outbound_datetime < NOW())
THEN inbound_datetime
ELSE outbound_datetime
END)' => SORT_ASC,
],
],
Is there any way to make this default sorting work and still keep the ability to use grid sorting by column names correctly?
Upvotes: 0
Views: 3079
Reputation: 180
I did some more thinking and have come up with a solution to this problem.
I define the query in my controller method which opens the view. So I added a condition that checks if sort parameter is passed to the get request. If it is passed, I create the query without the ORDER BY
clause. If sort parameter is not passed (no column sorting is done), I create a query with the ORDER BY
clause.
In my controller method:
if (Yii::$app->request->get('sort')) {
$query = Travel::find();
} else {
$query = Travel::find()
->orderBy('(CASE
WHEN (inbound_datetime IS NULL AND outbound_datetime < NOW()) OR (inbound_datetime IS NOT NULL AND inbound_datetime < NOW())
THEN 9999
WHEN (inbound_datetime IS NOT NULL AND outbound_datetime < NOW())
THEN inbound_datetime
ELSE outbound_datetime
END) ASC');
}
Upvotes: 1