Download the PHP package sjaakp/yii2-sortable-behavior without Composer

On this page you can find all versions of the php package sjaakp/yii2-sortable-behavior. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package yii2-sortable-behavior

Yii2 Sortable

Latest Stable Version Total Downloads License

This package contains five classes to handle the sorting of ActiveRecords:

The previous version of Sortable was dependent on jQuery. It now has no dependencies at all. It should work in all modern desktop browsers. At the time of writing the new HTML Drag and Drop, and thus Sortable, only works for few mobile browsers.

The old jQuery-dependent widgets are still available. Some may prefer their esthetics.

A demonstration of the Sortable suit is here.

Installation

The preferred way to install Sortable is through Composer. Either add the following to the require section of your composer.json file:

"sjaakp/yii2-sortable-behavior": "*"

Or run:

composer require sjaakp/yii2-sortable-behavior "*"

You can manually install Sortable by downloading the source in ZIP-format.

SortableGridView and SortableListView

These widgets are derived from the standard GridView and ListView classes, but have one extra capability: the items can be moved to another position by means of drag and drop (using HTML Drag and Drop functionality). If an item is dropped on a new position, a message is posted with the following data:

SortableGridView and SortableListView have one configurable property:

orderUrl

array|string. The URL which is called after a sorting operation. The format is that of yii\helpers\Url::toRoute.

SortableGridView and SortableListView don't go together with the Pjax-widget. However, Sortable is not very usable with paged data-widgets anyway.

Sortable

With this Behavior, an ActiveRecord becomes 'sortable'. It has one configurable property and one extra method:

orderAttribute

string|array. The order attribute(s) of the ActiveRecord.

This can take the following values:

Default is "ord".

order()

public function order( $newPosition, $foreignKeyName = null, where = [] )

This method puts the owner on the new position $newPosition by manipulating the order attribute. The order attribute is a zero-indexed, contiguous integer.

If $foreignKeyName is null (default) all the records are ordered.

If it is a string, the ordering is restricted to the records with the same value of $foreignKeyName. $foreignKeyName must be a key in orderAttribute. This comes in handy with one-to-many relations.

$where is an array of extra conditions in the format used by
[QueryInterface where()](https://www.yiiframework.com/doc/api/2.0/yii-db-queryinterface#where()-detail). May be used to add extra foreign key restraints. Default: [ ] (empty array).


Usage scenario 1

Simple sorting

Suppose we have a very simple table of movie titles:

CREATE TABLE movie (
  id int(10) unsigned NOT NULL AUTO_INCREMENT,
  ord int(10) unsigned NOT NULL,
  title tinytext NOT NULL,
  PRIMARY KEY (id)
)

Where ord will be our order attribute.

We can make the Movie ActiveRecord sortable like this:

class Movie extends ActiveRecord
{
    public function behaviors( ) {
        return [
            [
                'class' => 'sjaakp\sortable\Sortable',
            ],
        ];
    }
    ...
}

In the controller we define an index action and an order action:

class MovieController extends Controller
{
    ...
    public function actionIndex( )
    {
        $dataProvider = new ActiveDataProvider( [
            'query' => Movie::find( )->orderBy( 'ord' ),    // notice the orderBy clause
            'sort' => false,
            'pagination' => false
        ] );

        return $this->render( 'index', [
            'dataProvider' => $dataProvider,
        ] );
    }
    ...
    public function actionOrder( )   {
        $post = Yii::$app->request->post( );
        if (isset( $post['key'], $post['pos'] ))   {
            $this->findModel( $post['key'] )->order( $post['pos'] );
        }
    }
    ...
}

In the index view, we use a SortableGridView:

use sjaakp\sortable\SortableGridView;
...
<?= SortableGridView::widget( [
    'dataProvider' => $dataProvider,
    'orderUrl' => ['order'],
    'columns' => [
        ...
        'title:ntext',
        ...
    ],
    ...
] ); ?>

And bingo! The list of movie titles is now sortable by drag and drop.


Usage scenario 2

One-to-many sorting

Suppose we also have a list of directors. Each director has many movies, each movie belongs to one director (thinking of the Coen brothers, I know this is not necessarily true in reality).

We add two columns to our movie table:

CREATE TABLE movie (
  id int(10) unsigned NOT NULL AUTO_INCREMENT,
  ord int(10) unsigned NOT NULL,
  title tinytext NOT NULL,
  director_id int(10) unsigned NOT NULL,
  director_ord int(10) unsigned NOT NULL,
  PRIMARY KEY (id)
)

Where director_ord is the order attribute just for movies belonging to the same director.

In the Director model we define a one-to-many relation, like we would normally do (notice the orderBy clause):

class Director extends ActiveRecord {
    ...
    public function getMovies( ) {
        return $this->hasMany( Movie::class, ['director_id' => 'id'] )
            ->orderBy( 'director_ord' );
    }
    ...
}

The Movie model is sortable like before, but with another orderAttribute:

class Movie extends ActiveRecord
{
    public function behaviors( ) {
        return [
            [
                'class' => 'sjaakp\sortable\Sortable',
                'orderAttribute' => [
                    'director_id' => 'director_ord'
                ]
            ],
        ];
    }
    ...
}

This time, DirectorController sports an extra action:

class DirectorController extends Controller
{
    ...
    public function actionMovieOrder( )   {
        $post = Yii::$app->request->post( );
        if (isset( $post['key'], $post['pos'] ))   {
            $movie = Movie::findOne( $post['key'] );
            if ($movie) $movie->order( $post['pos'], 'director_id' );
        }
    }
    ...
}

Let's now use a SortableGridView to display all the movies of the director in director/view:

use sjaakp\sortable\SortableGridView;
...
$movies = new ActiveDataProvider( [
    'query' => $model->getMovies( ),  // Do not use $model->movies, it returns array of Movies in stead of an ActiveQueryInterface
    'sort' => false,
    'pagination' => false
] );
...
<h1><?= Html::encode( $model->name ) ?></h1>
...
<?= SortableGridView::widget( [
    'dataProvider' => $movies,
    'orderUrl' => ['movie-order'],
    'columns' => [
        ...
        'title:ntext',
        ...
    ],
    ...
] ); ?>

Now each director's view shows a sortable list of his or her movies.

It's easy to combine Usage scenario's 1 and 2, so that all movies are sortable in movie/index and only the director's movies in director/view. Just initialize Movie's Sortable behavior like this:

class Movie extends ActiveRecord
{
    public function behaviors( ) {
        return [
            [
                'class' => 'sjaakp\sortable\Sortable',
                'orderAttribute' => [
                    'ord',
                    'director_id' => 'director_ord'
                ]
            ],
        ];
    }
    ...
}

PivotRecord

This is the base ActiveRecord for the pivot table of two sortable Models in a many-to-many relation.

The ordering information is stored in the pivot table as well.

A pivot table might look something like this:

CREATE TABLE actor_movie (
  actor_id int(10) unsigned NOT NULL,   # actor's primary key
  movie_id int(10) unsigned NOT NULL,   # movie's primary key
  actor_ord int(10) unsigned NOT NULL,  # actor's order
  movie_ord int(10) unsigned NOT NULL,  # movie's order
  PRIMARY KEY (actor_id,movie_id),
)

Using best practices it means:

Of course, it would be wise to add some indexes.

A concrete pivot record has to be derived from PivotRecord. Two static functions must be defined in the derived class:

aClass() and bClass()

protected static function aClass( ) protected static function bClass( )

These static member functions should return the fully qualified class names of the related Models.

aClass and bClass are completely equivalent. PivotRecord is in any respect a symmetric class.

A complete definition of a pivot record might look like this:

namespace app\models;
use sjaakp\sortable\PivotRecord;

class MovieActor extends PivotRecord    {

    protected static function aClass( )   {
        return Movie::class;
    }

    protected static function bClass( )   {
        return Actor::class;
    }
}

Notice that you can define some other static values as well, for special cases. Refer to the source code if you need this.

A PivotRecord-derived class has the following extra functions.

getAs() and getBs()

public static function getAs( ActiveRecord $b )

Get the ordered records of classA belonging to classB $b.

public static function getBs( ActiveRecord $a )

Get the ordered records of classB belonging to classA $a.

The result is returned as an ActiveQuery, which can be modified further, or used as source of an ActiveDataProvider.

Notice these are static functions, not referring to any instantiation of the PivotRecord-derived class.

orderA() and orderB()

public function orderA( $newPosition )

Place classA at $newPosition in the list of all classA's belonging to classB.

public function orderB( $newPosition )

Place classB at $newPosition in the list of all classB's belonging to classA.

These are member functions. The id's of classA and classB are stored in the current PivotRecord.

MMSortable

This is a Behavior of both partner ActiveRecords in a many-to-many relations. PivotRecord relies on it. MMSortable performs some housekeeping and has no (interesting) member functions. However, two properties have to be configured:

pivotClass

string. The fully classified class name of the pivot class (the PivotRecord-derived class).

pivotIdAttr

string. The attribute name of the owner's id in the pivot class. If this is not set, it will be derived from the owner's class name; for instance: if the owner is class Movie, $pivotIdAttr will be "movie_id".


Usage scenario 3

Many-to-many sorting

Apart from our movie table, we also have an actor table. They are linked via an actor_movie pivot table: each movie can have many actors, and each actor can have many movies.

First, we define a pivot class, like so:

namespace app\models;
use sjaakp\sortable\PivotRecord;

class MovieActor extends PivotRecord    {

    protected static function aClass( )   {
        return Movie::class;
    }

    protected static function bClass( )   {
        return Actor::class;
    }
}

Then, we make sure that both Movie and Actor have a MMSortable Behavior:

class Movie extends ActiveRecord    {
    ...
    public function behaviors( ) {
        return [
            [
                'class' => 'sjaakp\sortable\MMSortable',
                'pivotClass' => MovieActor::class
            ]
        ];
    }
    ...
}

For convenience, we add a very simple member function to Movie:

class Movie extends ActiveRecord    {
    ...
    public function getActors( ) {
        return MovieActor::getBs( $this );
    }
    ...
}

Define an order-actor-action in MovieController:

class MovieController extends Controller
{
    ...
    public function actionOrderActor( $id )   {
        $post = Yii::$app->request->post( );
        if (isset( $post['key'], $post['pos'] ))   {
            $piv = MovieActor::find( )->where( [
                'movie_id' => $id,
                'actor_id' => $post['key']
            ] )->one( );
            $piv->orderB( $post['pos'] );
        }
    }
    ...
}

Now, in movie/view, we can display a SortableGridView with all the actors appearing in the movie.

use sjaakp\sortable\SortableGridView;
...
$actors = new ActiveDataProvider( [
    'query' => $model->getActors( ),
    'sort' => false,
    'pagination' => false
] );
...
<h1><?= Html::encode( $model->title ) ?></h1>
...
<?= SortableGridView::widget( [
    'dataProvider' => $actors,
    'orderUrl' => ['order-actor', 'id' => $model->getPrimaryKey()],
    'columns' => [
        ...
        'name:ntext',
        ...
    ],
    ...
] ); ?>

Sortable with jQuery

The previous version of Sortable (1.0) used jQuery Draggable and Sortable. The old jQuery-widgets are still available as SortableGridViewJquery and SortableListViewJquery. They are exchangeable with their non-jQuery counterparts.

You may prefer the esthetics of the jQuery variants. Also, the new HTML Drag and Drop may not work for all mobile browsers.

SortableGridViewJquery and SortableListViewJquery have two extra configurable properties:

sortOptions

array. The options for the jQuery sortable object. See https://api.jqueryui.com/sortable/.

Notice that the options 'items', 'helper', and 'update' will be overwritten.

Default: [] (empty array).

sortAxis

boolean|string The 'axis' option for the jQuery sortable. If false, it is not set. Default: 'y'.

For compatibility, SortableGridView and SortableListView have these options as well, but they are not functional.


Thanks


All versions of yii2-sortable-behavior with dependencies

PHP Build Version
Package Version
Requires yiisoft/yii2 Version *
yiisoft/yii2-jui Version *
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package sjaakp/yii2-sortable-behavior contains the following files

Loading the files please wait ....