1
votes

I have a table rendered by Yii2 GridView. The table header contains the link to sort by date. If I click on it, it sorts the table first in ascending order and on the second click in descending order. But I want descending order on the first click.

I solved it with a hack in the search method of the search controller (asc->SORT_DESC):

   $dataProvider->sort->attributes['updated_at'] = [ 
      'asc'  => [$this->tablename() . '.updated_at' => SORT_DESC ], 
      'desc' => [$this->tablename() . '.updated_at' => SORT_ASC], 
   ]; 

Is there a better solution?

4

4 Answers

5
votes

Use default:

The "default" element specifies by which direction the attribute should be sorted if it is not currently sorted (the default value is ascending order).

$dataProvider->sort->attributes['updated_at'] = [ 
    'default' => SORT_DESC
]; 
1
votes
$dataProvider = new ActiveDataProvider([
  'query' => YourClass::find(),
  'sort' => [
    'defaultOrder' => [
        'updated_at' => SORT_ASC,
    ],
  ],
]);

You can use sort option in $dataProvider. It will display data in ascending order and when you click on column very first time, It will first display in descending order.

I checked it. It is working for me.

For more info, please have a look Rendering Data In List View & Grid View : Yii2

0
votes

My solution:

add Sort.php

namespace backend\components;

use yii\base\InvalidConfigException;

class Sort extends \yii\data\Sort
{
/**
 * @var int
 */
public $defaultSort = SORT_DESC;

/**
 * Rewrite
 * @param string $attribute the attribute name
 * @return string the value of the sort variable
 * @throws InvalidConfigException if the specified attribute is not defined in [[attributes]]
 */
public function createSortParam($attribute)
{
    if (!isset($this->attributes[$attribute])) {
        throw new InvalidConfigException("Unknown attribute: $attribute");
    }
    $definition = $this->attributes[$attribute];
    $directions = $this->getAttributeOrders();
    if (isset($directions[$attribute])) {
        $direction = $directions[$attribute] === SORT_DESC ? SORT_ASC : SORT_DESC;
        unset($directions[$attribute]);
    } else {
        $direction = isset($definition['default']) ? $definition['default'] : $this->defaultSort;
    }

    if ($this->enableMultiSort) {
        $directions = array_merge([$attribute => $direction], $directions);
    } else {
        $directions = [$attribute => $direction];
    }

    $sorts = [];
    foreach ($directions as $attribute => $direction) {
        $sorts[] = $direction === SORT_DESC ? '-' . $attribute : $attribute;
    }

    return implode($this->separator, $sorts);
}
}

in Controller:

    $dataProvider = new ActiveDataProvider([
        'query' => MyModel::find(),
    ]);
    /**@var $sort \backend\components\Sort */
    $sort = Yii::createObject(array_merge(['class' => Sort::className()], [
        'defaultOrder' => [
            '_id' => SORT_ASC,
        ],
    ]));
    $dataProvider->setSort($sort);
0
votes
$dataProvider->sort = ['defaultOrder' => ['id' => 'DESC']];