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 Sortable
Attach 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
order
is a MySQL reserved word. You should not use it. Consider using something likeposition
orweight
. Also, if you useposition
as 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!