Sortable allows to sort rows of a table by using a numeric field.
TESTED ON CakePHP 4.x (this should also work on CakePHP 3.x)
- Install the plugin with composer from your CakePHP project's ROOT directory (where composer.json file is located)
php composer.phar require hacheraw/sortable- Load the plugin by running command
bin/cake plugin load SortableAttach the Sortable behavior to your table class.
/**
* @mixin \Sortable\Model\Behavior\SortableBehavior
*/
class ElementsTable extends Table
{
/**
* @param array $config
* @return void
*/
public function initialize(array $config): void
{
parent::initialize($config);
// Add the behavior to your table
$this->addBehavior('Sortable.Sortable', [
'field' => 'name_of_the_field', // default name is `position`
'group' => [], // If there are associations you must set the foreign keys. eg: ['post_id']
'start' => 1, // First item of the list (where to start counting from)
'steps' => 1 // How much to add or substract
]
);
}Sortable updates all values when you edit or insert a new record. In addition, you can manually call the following functions:
// Controller::action()
// Move the row to a new position
$this->Elements->move($row_id, $new_place);
// Move the row to the top
$this->Elements->toTop($row_id);
// Move the row to the bottom
$this->Elements->toBottom($row_id); // Controller::action()
/**
* If there are fields that must be included in where clauses, you must specify them.
* For example, if you want to sort post images and images' table has a column named
* post_id, then you must add it as a condition.
*/
$conditions = ['post_id' => 7];
// Passing variables to the View
$this->set('min', $this->Proceedings->ProceedingColumns->getStart());
$this->set('max', $this->Proceedings->ProceedingColumns->getLast($conditions)); // When editing order of existing row
$this->set('max', $this->Proceedings->ProceedingColumns->getNew($conditions)); // When adding a new row
$this->set('step', $this->Proceedings->ProceedingColumns->getStep()); // View
echo $this->Form->control('position', ['min' => $min, 'max' => $max, 'step' => $step, ]); // When editing order of existing row
echo $this->Form->control('position', ['min' => $min, 'max' => $max, 'step' => $step, 'value' => $max]); // When adding a new row-
The column's type must be numeric (tinyint, smallint, int, double...) Note that CakePHP assumes tiniInt(1) as boolean so you have to use tinyInt(2) or greater
-
Be aware that
orderis a MySQL reserved word. You should not use it. Consider using something likepositionorweight. Also, if you usepositionas field name you will not need to pass it to the Behavior as that is the default field name.
- It is my first public CakePHP Plugin / Composer Package.
- It lacks of unit tests... sorry.
- I have not tested it on tables with a large amount of rows.
PoliteComments or questions are welcome on Issues section. Even Pull Request!