Class rootlocal\widgets\sortable\SortableGridBehavior

Inheritancerootlocal\widgets\sortable\SortableGridBehavior » yii\base\Behavior
Implementsrootlocal\widgets\sortable\SortableGridBehaviorInterface

Behavior for sortable Yii2 GridView widget.

For example:

public function behaviors()
{
   return [
      'sort' => [
          'class' => SortableGridBehavior::class,
          'sortableAttribute' => 'sort_order',
          'scope' => function ($query) {
             $query->andWhere(['group_id' => $this->group_id]);
          },
      ],
  ];
}

Public Properties

Hide inherited properties

Property Type Description Defined By
$afterGridSort \rootlocal\widgets\sortable\Closure|mixed Callable function for after before insert sorting rootlocal\widgets\sortable\SortableGridBehavior
$scope \rootlocal\widgets\sortable\Closure|mixed Callable function for query rootlocal\widgets\sortable\SortableGridBehavior
$sortableAttribute string Database field name for row sorting default value: sort_order rootlocal\widgets\sortable\SortableGridBehavior

Public Methods

Hide inherited methods

Method Description Defined By
beforeInsert() ModelEvent an event that is triggered before inserting a record. rootlocal\widgets\sortable\SortableGridBehavior
events() Declares event handlers for the owner's events. rootlocal\widgets\sortable\SortableGridBehavior
getSortableAttribute() Getting Database field name for row sorting default value: sort_order rootlocal\widgets\sortable\SortableGridBehavior
gridSort() Сортировка строк таблицы перетаскиванием "Drag-and-drop" rootlocal\widgets\sortable\SortableGridBehavior
gridSortUpOrDownButton() Сортировка строк таблицы нажатием на кнопки up или down rootlocal\widgets\sortable\SortableGridBehavior
setSortableAttribute() Setting Database field name for row sorting rootlocal\widgets\sortable\SortableGridBehavior

Property Details

Hide inherited properties

$afterGridSort public property

Callable function for after before insert sorting

public \rootlocal\widgets\sortable\Closure|mixed $afterGridSort null
$scope public property

Callable function for query

public \rootlocal\widgets\sortable\Closure|mixed $scope null
$sortableAttribute public property

Database field name for row sorting default value: sort_order

public string $sortableAttribute null

Method Details

Hide inherited methods

beforeInsert() public method

ModelEvent an event that is triggered before inserting a record.

public void beforeInsert ( )
throws \yii\base\InvalidConfigException

                public function beforeInsert(): void
{
    /** @var ActiveRecord $model */
    $model = $this->owner;
    if (!$model->hasAttribute($this->getSortableAttribute())) {
        throw new InvalidConfigException("Invalid sortable attribute `{$this->getSortableAttribute()}`.");
    }
    if (empty($model->{$this->getSortableAttribute()})) {
        $query = $model::find();
        if (is_callable($this->scope)) {
            call_user_func($this->scope, $query);
        }
        /* Override model alias if defined in the model's class */
        $query->from([$model::tableName() => $model::tableName()]);
        $maxOrder = $query->max('{{' . trim($model::tableName(), '{}')
            . '}}.[[' . $this->getSortableAttribute() . ']]');
        $model->{$this->getSortableAttribute()} = $maxOrder + 1;
    }
}

            
events() public method

Declares event handlers for the owner's events.

public array events ( )
return array

Events (array keys) and the corresponding event handler methods (array values).

                public function events(): array
{
    return [BaseActiveRecord::EVENT_BEFORE_INSERT => 'beforeInsert'];
}

            
getSortableAttribute() public method

Getting Database field name for row sorting default value: sort_order

public string getSortableAttribute ( )

                public function getSortableAttribute(): string
{
    if ($this->_sortableAttribute === null) {
        $this->_sortableAttribute = 'sort_order';
    }
    return $this->_sortableAttribute;
}

            
gridSort() public method

Сортировка строк таблицы перетаскиванием "Drag-and-drop"

public array gridSort ( array $items = [] )
$items array

['old_primary_key' => 'new_primary_key']

return array

New values attributes (new sorted values) [['id' => primary_key_value, 'sort_id' => sort_value]]

throws \yii\base\InvalidConfigException
throws Throwable

                public function gridSort(array $items = []): array
{
    /** @var ActiveRecord $model */
    $model = $this->owner;
    /** @var ?string $primaryKey */
    $primaryKey = !empty($model::primaryKey()) && is_array($model::primaryKey()) ? $model::primaryKey()[0] : null;
    if ($primaryKey === null) {
        throw new InvalidConfigException("Model does not have primaryKey");
    }
    if (!$model->hasAttribute($this->getSortableAttribute())) {
        throw new InvalidConfigException(
            "Model does not have sortable attribute `{$this->getSortableAttribute()}`."
        );
    }
    /** @var int[] $newOrder */
    $newOrder = [];
    /** @var ActiveRecord[] $models */
    $models = [];
    foreach ($items as $old => $new) {
        $models[$new] = $model::find()
            ->select([$this->getSortableAttribute(), $primaryKey])
            ->where([$primaryKey => $new])->one();
        $newOrder[$old] =
            !empty($models[$new]->{$this->getSortableAttribute()})
                ? $models[$new]->{$this->getSortableAttribute()} : $new;
    }
    $transaction = $model::getDb()->beginTransaction();
    $result = [];
    try {
        foreach ($newOrder as $modelId => $orderValue) {
            $models[$modelId]->updateAttributes([$this->getSortableAttribute() => $orderValue]);
            $result[] = ['id' => $modelId, 'sort_id' => $orderValue];
        }
        $transaction->commit();
    } catch (Exception|Throwable $e) {
        $transaction->rollBack();
        Yii::error($e->getMessage(), self::class);
        return [];
    }
    if (is_callable($this->afterGridSort)) {
        call_user_func($this->afterGridSort, $model);
    }
    return $result;
}

            
gridSortUpOrDownButton() public method

Сортировка строк таблицы нажатием на кнопки up или down

public array gridSortUpOrDownButton ( string $button, integer $id )
$button string

String name "up" or "down" action button

$id integer

Primary Key value Model

return array

New values models New values attributes (new sorted values) [['id' => primary_key_value, 'sort_id' => sort_value]]

throws \yii\web\BadRequestHttpException

                public function gridSortUpOrDownButton(string $button, int $id): array
{
    /** @var ActiveRecord $model */
    $model = $this->owner;
    /** @var ?string $primaryKey */
    $primaryKey = !empty($model::primaryKey()) && is_array($model::primaryKey()) ? $model::primaryKey()[0] : null;
    if ($primaryKey === null) {
        throw new InvalidConfigException("Model does not have primaryKey");
    }
    $owner = $model->find()
        ->select([$this->getSortableAttribute(), $primaryKey])
        ->where([$primaryKey => $id])->one();
    $target = $model::find()->select([$this->getSortableAttribute(), $primaryKey]);
    if ($button === 'up') {
        $target = $target->andWhere($model::tableName() . '.' . $this->sortableAttribute . ' < :sort', [
            ':sort' => $owner->{$this->sortableAttribute}
        ])->orderBy([$this->sortableAttribute => SORT_DESC])->one();
    } else {
        $target = $target->andWhere($model::tableName() . '.' . $this->sortableAttribute . ' > :sort', [
            ':sort' => $owner->{$this->sortableAttribute}
        ])->orderBy([$this->sortableAttribute => SORT_ASC])->one();
    }
    if ($target === null) {
        throw new BadRequestHttpException('Can\'t find target model');
    }
    $transaction = $model->getDb()->beginTransaction();
    try {
        $ownerSortId = $owner->{$this->sortableAttribute};
        $targetSortId = $target->{$this->sortableAttribute};
        $owner->{$this->sortableAttribute} = $targetSortId;
        $target->{$this->sortableAttribute} = $ownerSortId;
        if ($owner->save(false)
            && $target->save(false)) {
            $transaction->commit();
            return [
                0 => ['id' => $owner->getPrimaryKey(), 'sort_id' => $owner->{$this->sortableAttribute}],
                1 => ['id' => $target->getPrimaryKey(), 'sort_id' => $target->{$this->sortableAttribute}],
            ];
        }
        $transaction->rollBack();
    } catch (Exception|Throwable $e) {
        $transaction->rollBack();
        Yii::error($e->getMessage(), self::class);
    }
    throw new BadRequestHttpException('Unknown error');
}

            
setSortableAttribute() public method

Setting Database field name for row sorting

public void setSortableAttribute ( string $sortableAttribute )
$sortableAttribute string

                public function setSortableAttribute(string $sortableAttribute): void
{
    $this->_sortableAttribute = $sortableAttribute;
}