GithubHelp home page GithubHelp logo

spatie / eloquent-sortable Goto Github PK

View Code? Open in Web Editor NEW
1.3K 22.0 131.0 174 KB

Sortable behaviour for Eloquent models

Home Page: https://spatie.be/open-source/packages

License: MIT License

PHP 100.00%
laravel php eloquent sort trait

eloquent-sortable's Introduction

Sortable behaviour for Eloquent models

Latest Version GitHub Workflow Status Software License Total Downloads

This package provides a trait that adds sortable behaviour to an Eloquent model.

The value of the order column of a new record of a model is determined by the maximum value of the order column of all records of that model + 1.

The package also provides a query scope to fetch all the records in the right order.

Spatie is a webdesign agency in Antwerp, Belgium. You'll find an overview of all our open source projects on our website.

Support us

Learn how to create a package like this one, by watching our premium video course:

Laravel Package training

We invest a lot of resources into creating best in class open source packages. You can support us by buying one of our paid products.

We highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using. You'll find our address on our contact page. We publish all received postcards on our virtual postcard wall.

Installation

For Laravel 6.x or PHP 7.x, use version 3.x of this package.

This package can be installed through Composer.

composer require spatie/eloquent-sortable

In Laravel 5.5 and above the service provider will automatically get registered. In older versions of the framework just add the service provider in config/app.php file:

'providers' => [
    ...
    Spatie\EloquentSortable\EloquentSortableServiceProvider::class,
];

Optionally you can publish the config file with:

php artisan vendor:publish --tag=eloquent-sortable-config

This is the content of the file that will be published in config/eloquent-sortable.php

return [
  /*
   * The name of the column that will be used to sort models.
   */
  'order_column_name' => 'order_column',

  /*
   * Define if the models should sort when creating. When true, the package
   * will automatically assign the highest order number to a new model
   */
  'sort_when_creating' => true,

  /*
   * Define if the timestamps should be ignored when sorting.
   * When true, updated_at will not be updated when using setNewOrder
   */
  'ignore_timestamps' => false,
];

Usage

To add sortable behaviour to your model you must:

  1. Implement the Spatie\EloquentSortable\Sortable interface.
  2. Use the trait Spatie\EloquentSortable\SortableTrait.
  3. Optionally specify which column will be used as the order column. The default is order_column.

Example

use Spatie\EloquentSortable\Sortable;
use Spatie\EloquentSortable\SortableTrait;

class MyModel extends Model implements Sortable
{
    use SortableTrait;

    public $sortable = [
        'order_column_name' => 'order_column',
        'sort_when_creating' => true,
    ];

    // ...
}

If you don't set a value $sortable['order_column_name'] the package will assume that your order column name will be named order_column.

If you don't set a value $sortable['sort_when_creating'] the package will automatically assign the highest order number to a new model;

Assuming that the db-table for MyModel is empty:

$myModel = new MyModel();
$myModel->save(); // order_column for this record will be set to 1

$myModel = new MyModel();
$myModel->save(); // order_column for this record will be set to 2

$myModel = new MyModel();
$myModel->save(); // order_column for this record will be set to 3


//the trait also provides the ordered query scope
$orderedRecords = MyModel::ordered()->get();

You can set a new order for all the records using the setNewOrder-method

/**
 * the record for model id 3 will have order_column value 1
 * the record for model id 1 will have order_column value 2
 * the record for model id 2 will have order_column value 3
 */
MyModel::setNewOrder([3,1,2]);

Optionally you can pass the starting order number as the second argument.

/**
 * the record for model id 3 will have order_column value 11
 * the record for model id 1 will have order_column value 12
 * the record for model id 2 will have order_column value 13
 */
MyModel::setNewOrder([3,1,2], 10);

You can modify the query that will be executed by passing a closure as the fourth argument.

/**
 * the record for model id 3 will have order_column value 11
 * the record for model id 1 will have order_column value 12
 * the record for model id 2 will have order_column value 13
 */
MyModel::setNewOrder([3,1,2], 10, null, function($query) {
    $query->withoutGlobalScope(new ActiveScope);
});

To sort using a column other than the primary key, use the setNewOrderByCustomColumn-method.

/**
 * the record for model uuid '7a051131-d387-4276-bfda-e7c376099715' will have order_column value 1
 * the record for model uuid '40324562-c7ca-4c69-8018-aff81bff8c95' will have order_column value 2
 * the record for model uuid '5dc4d0f4-0c88-43a4-b293-7c7902a3cfd1' will have order_column value 3
 */
MyModel::setNewOrderByCustomColumn('uuid', [
   '7a051131-d387-4276-bfda-e7c376099715',
   '40324562-c7ca-4c69-8018-aff81bff8c95',
   '5dc4d0f4-0c88-43a4-b293-7c7902a3cfd1'
]);

As with setNewOrder, setNewOrderByCustomColumn will also accept an optional starting order argument.

/**
 * the record for model uuid '7a051131-d387-4276-bfda-e7c376099715' will have order_column value 10
 * the record for model uuid '40324562-c7ca-4c69-8018-aff81bff8c95' will have order_column value 11
 * the record for model uuid '5dc4d0f4-0c88-43a4-b293-7c7902a3cfd1' will have order_column value 12
 */
MyModel::setNewOrderByCustomColumn('uuid', [
   '7a051131-d387-4276-bfda-e7c376099715',
   '40324562-c7ca-4c69-8018-aff81bff8c95',
   '5dc4d0f4-0c88-43a4-b293-7c7902a3cfd1'
], 10);

You can also move a model up or down with these methods:

$myModel->moveOrderDown();
$myModel->moveOrderUp();

You can also move a model to the first or last position:

$myModel->moveToStart();
$myModel->moveToEnd();

You can determine whether an element is first or last in order:

$myModel->isFirstInOrder();
$myModel->isLastInOrder();

You can swap the order of two models:

MyModel::swapOrder($myModel, $anotherModel);

Grouping

If your model/table has a grouping field (usually a foreign key): id, user_id, title, order_column and you'd like the above methods to take it into considerations, you can create a buildSortQuery method at your model:

// MyModel.php

public function buildSortQuery()
{
    return static::query()->where('user_id', $this->user_id);
}

This will restrict the calculations to fields value of the model instance.

Tests

The package contains some integration/smoke tests, set up with Orchestra. The tests can be run via phpunit.

vendor/bin/phpunit

Changelog

Please see CHANGELOG for more information on what has changed recently.

Contributing

Please see CONTRIBUTING for details.

Security Vulnerabilities

Please review our security policy on how to report security vulnerabilities.

Credits

Alternatives

License

The MIT License (MIT). Please see License File for more information.

eloquent-sortable's People

Contributors

adrianmrn avatar dependabot[bot] avatar driade avatar freekmurze avatar github-actions[bot] avatar kristories avatar matthiasdewinter avatar mokhosh avatar mouhcinemahfoud avatar newtongamajr avatar nguyentranchung avatar nielsvanpach avatar nwidart avatar pascalbaljet avatar pashtostories avatar patinthehat avatar patrickbrouwers avatar propaganistas avatar ralphmrivera avatar riasvdv avatar rvxlab avatar sebastiandedeyne avatar sebdesign avatar srmklive avatar stevebauman avatar swapnilsarwe avatar tjoosten avatar twickstrom avatar weiyongsheng avatar yahav avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

eloquent-sortable's Issues

Relation

Hi,
Very nice package!

I try to understand how can I use it for pivot tables?
I have a Venue and an Event model. A Venue can have many Event(s) and an Event belongToMany Venue(s). So I have the pivot table but no Eloquent Model...
For each Venue, I would like to display the attached Event(s) and being able to manage Event(s) order for that Venue. I should keep track of Event position within the pivot table, right?

Can you help me please?

Why drop support for Laravel < 5.8?

Came across this great library you have put together but discovered I can't use as our application is on Laravel 5.5.

Going through your changelogs and commits, there doesn't seem to be a reason as to why you have dropped support for < 5.8 despite the code in src/ not changing for 2 years.

Grouped ordering

Hi,

Is it possible to add a feature to permit grouped ordering?

Overwriting order on create

When I provide the order_column value in the create method of the model, I would not like it to be overwritten. Could you make sure it checks if the order_column is present, and then not set the sort_order? Or make this optional

moveOrderStart() and moveOrderEnd()

I propose adding two new methods, moveOrderStart() and moveOrderEnd(). These methods would swap the model with the very first one, or the very last one, respectively.

I achieved the creation of these methods simply by getting moveOrderUp() and moveOrderDown() and swapping the order type (replacing ordered() with ordered('desc') in moveOrderEnd() and removing the 'desc' in moveOrderStart()).

Exception thrown on using ordered() scope

Argument 1 passed to App\Model::scopeOrdered() must be an instance of Illuminate\Database\Query\Builder, instance of Illuminate\Database\Eloquent\Builder given

I have defined scopes myself in the model and seems I didn't use any typehinting at all for $query. So this could be a possible fix?

Add at position

What do you think about setting a desired order value when for a new model?

$model->setOrder(3);

This should place the given model at position 3 and move current models 3-X one up.

Call to undefined method `Spatie\Tags\Tag::qgetHighestOrderNumberuery()`

I'm using spatie/nova-tags-field which in turn uses spatie/laravel-tags which again in turn pulls in this package (Version 3.8.0 of this package).

Now if I add some tags to my resource and try to save it I get:

[2020-03-20 13:08:09] local.ERROR: Call to undefined method Spatie\Tags\Tag::qgetHighestOrderNumberuery() {"userId":1,"exception":"[object] (BadMethodCallException(code: 0): Call to undefined method Spatie\\Tags\\Tag::qgetHighestOrderNumberuery() at /path/to/project/vendor/laravel/framework/src/Illuminate/Support/Traits/ForwardsCalls.php:50)
[stacktrace]
#0 /path/to/project/vendor/laravel/framework/src/Illuminate/Support/Traits/ForwardsCalls.php(36): Illuminate\\Database\\Eloquent\\Model::throwBadMethodCallException()
#1 /path/to/project/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(1618): Illuminate\\Database\\Eloquent\\Model->forwardCallTo()
#2 /path/to/project/vendor/spatie/eloquent-sortable/src/SortableTrait.php(173): Illuminate\\Database\\Eloquent\\Model->__call()
#3 /path/to/project/vendor/spatie/eloquent-sortable/src/SortableTrait.php(30): Spatie\\Tags\\Tag->buildSortQuery()
#4 /path/to/project/vendor/spatie/eloquent-sortable/src/SortableTrait.php(25): Spatie\\Tags\\Tag->getHighestOrderNumber()
#5 /path/to/project/vendor/spatie/eloquent-sortable/src/SortableTrait.php(16): Spatie\\Tags\\Tag->setHighestOrderNumber()
#6 /path/to/project/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php(347): Spatie\\Tags\\Tag::Spatie\\EloquentSortable\\{closure}()
#7 /path/to/project/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php(196): Illuminate\\Events\\Dispatcher->Illuminate\\Events\\{closure}()
#8 /path/to/project/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php(169): Illuminate\\Events\\Dispatcher->dispatch()
#9 /path/to/project/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasEvents.php(188): Illuminate\\Events\\Dispatcher->until()
#10 /path/to/project/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(787): Illuminate\\Database\\Eloquent\\Model->fireModelEvent()
#11 /path/to/project/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(667): Illuminate\\Database\\Eloquent\\Model->performInsert()
#12 /path/to/project/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php(795): Illuminate\\Database\\Eloquent\\Model->save()
#13 /path/to/project/vendor/laravel/framework/src/Illuminate/Support/helpers.php(1124): Illuminate\\Database\\Eloquent\\Builder->Illuminate\\Database\\Eloquent\\{closure}()
#14 /path/to/project/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php(796): tap()
#15 /path/to/project/vendor/laravel/framework/src/Illuminate/Support/Traits/ForwardsCalls.php(23): Illuminate\\Database\\Eloquent\\Builder->create()
#16 /path/to/project/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(1618): Illuminate\\Database\\Eloquent\\Model->forwardCallTo()
#17 /path/to/project/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(1630): Illuminate\\Database\\Eloquent\\Model->__call()
#18 /path/to/project/vendor/spatie/laravel-tags/src/Tag.php(89): Illuminate\\Database\\Eloquent\\Model::__callStatic()
#19 /path/to/project/vendor/spatie/laravel-tags/src/Tag.php(50): Spatie\\Tags\\Tag::findOrCreateFromString()
#20 [internal function]: Spatie\\Tags\\Tag::Spatie\\Tags\\{closure}()
#21 /path/to/project/vendor/laravel/framework/src/Illuminate/Support/Collection.php(1120): array_map()
#22 /path/to/project/vendor/spatie/laravel-tags/src/Tag.php(51): Illuminate\\Support\\Collection->map()
#23 /path/to/project/vendor/spatie/laravel-tags/src/HasTags.php(220): Spatie\\Tags\\Tag::findOrCreate()
#24 /path/to/project/vendor/spatie/nova-tags-field/src/Tags.php(95): App\\Teaser->syncTagsWithType()

I checked the SortableTrait::buildSortQuery which is

    public function buildSortQuery()
    {
        return static::qgetHighestOrderNumberuery();
    }

but I can't find any implementation of qgetHighestOrderNumberuery and also no documentation about this other than you can overide buildSortQuery.

Please help me out with what I'm missing here.

If you need further information or this is the wrong project for this issue report please let me know.

Don't override order on create when provided

If a specific order is provided when creating a model, fx. order_column => 3, then it will be overridden with the highest order by default.

Changing SortableTrait::shouldSortWhenCreating() would accommodate this:

/**
 * Determine if the order column should be set when saving a new model instance.
 *
 * @return bool
 */
public function shouldSortWhenCreating(): bool
{
    if ($this->isDirty($this->determineOrderColumnName())) {
        return false;
    }

    return isset($this->sortable['sort_when_creating'])
        ? $this->sortable['sort_when_creating']
        : config('eloquent-sortable.sort_when_creating', true);
}

Soft deleting models are not reordered as expected

I have a model which uses the SoftDeletes trait and the SortableTrait. On the front-end of my app I'm displaying only the ordered non-trashed models, but on the back-end I'm including the trashed models, which can be reordered.

The soft deleting trait adds a constraint when the setNewOrder method is looping over the ids, therefore the order column is updated only on the non-trashed models. This is a bug because the new order is not synced across all the given models, which gives us duplicate order numbers, and that leads to unexpected results.

I'm happy to submit a PR if this is something that should be fixed. Thanks!

Feature request: moveBefore and moveAfter

Scenario:
You have four items:

  • Basketball
  • Volleyball
  • Handball
  • Football

You want to move Football infront of Volleyball, and push the others down

$football->moveBefore($volleyball); :
Ordered result is now

  • Basketball
  • Football
  • Volleyball
  • Handball

Same as for moveAfter. Eg $basketball->moveAfter($volleyball); :

  • Football
  • Volleyball
  • Basketball
  • Handball

Don't work EloquentSortable

I use Laravel^7.29, nwidart/laravel-modules^7.2.0 and spatie/eloquent-sortable^3.11

exception: "TypeError"
file: "C:\OpenServer\domains\starter-laravel-vue-avis\vendor\spatie\eloquent-sortable\src\SortableTrait.php"
line: 118
message: "Argument 1 passed to Modules\AvisAdmin\Entities\Setting::swapOrderWithModel() must be an instance of Spatie\EloquentSortable\Sortable, instance of Modules\AvisAdmin\Entities\Setting given, called in C:\OpenServer\domains\starter-laravel-vue-avis\vendor\spatie\eloquent-sortable\src\SortableTrait.php on line 99"

My model:

namespace Modules\AvisAdmin\Entities;

use Illuminate\Database\Eloquent\Model;
use \Spatie\EloquentSortable\Sortable;
use \Spatie\EloquentSortable\SortableTrait;

class Setting extends Model
{
	use SortableTrait;
	
        protected $guarded = [];
    
	public $sortable = [
        'order_column_name' => 'order_column',
        'sort_when_creating' => true,
    ];
}

Order is getting overwritten when creating

Example in tinker:
MyModel::create(['sort_order' => 15]) results in the sort_order being 1.

I was expecting the sort_order to be 15, but I wonder if this is the expected behavior?

Currently solved by adding this to my model:

public function shouldSortWhenCreating(): bool
{
    if (!is_null($this->{$this->determineOrderColumnName()})) {
        return false;
    }

    return $this->sortable['sort_when_creating'] ?? config('eloquent-sortable.sort_when_creating', true);
}

Fails with unique index.

Hey guys,

I'm unsure if this is intentional, but I added this to a project that uses unique indexes on the order column, and it caused this package to fail because of that. I removed the unique index and it works perfectly.

Feature request: global configuration for per-model options

Let me start off by saying thank you for this package, it's looking to be really useful in one of my projects that I'm currently rewriting in Laravel. This feature request concerns these options:

    public $sortable = [
        'order_column_name' => 'order_column',
        'sort_when_creating' => true,
    ];

Since these have to be set for each model and my previous project's colum naming does not line up with this package's defaults, I currently need to specify these options for every model, making the code slightly more verbose. To avoid this I created an intermediary trait that I use in my models:

use Spatie\EloquentSortable\SortableTrait as OriginSortableTrait;

trait SortableTrait {
    use OriginSortableTrait;
    public $sortable = ['order_column_name' => 'order'];
}

but this seems like a tacky solution. I would like to propose being able to change the default values for these options via a file in the config folder, which is publishable to the project via the standard Laravel config publishing mechanism.

Is setting a default sort possible?

Pardon if this has been asked before or is listed somewhere, but I have struggled and can't find an answer.

I would like to set the default of sorting to the last name of employees. When I implement Sortable in the model, I lose this as the default. Is there a way to set it?

Controller:

    $employees = Employee::activeEmployees()->paginate(10);

    $employee = Employee::find(1);

    try {
        $employees = $employee->Sortable()->paginate(10);
    } catch (\Kyslik\ColumnSortable\Exceptions\ColumnSortableException $e) {
        dd($e);
    }

Model:

public $sortable = [
    'last_name',
    'name',
    'department_id',
    'status',
    'email',
    'supervisor_id',
    'active',
    'sort_when_creating' => true,
];


public function nameSortable($query, $direction){

    return $query->join('users', 'users.id', '=', 'employees.user_id')
        ->orderBy('name', $direction)
        ->select('users.*', 'employees.*');
}

public function lastNameSortable($query, $direction){

    return $query->join('users', 'users.id', '=', 'employees.user_id')
        ->orderBy('last_name', $direction)
        ->select('users.*', 'employees.*');
}

public function scopeActiveEmployees($query){
    return $query->join('users', 'users.id', '=', 'employees.user_id')
        ->where('employees.active', true)
        ->orderBy('last_name', 'asc')
        ->select('users.*', 'employees.*');
}

Question re: sort_when_creating

Hi Freek/Spatie,

I'm looking into using your packages. I found this one and was reading the docs. GitHub says:

If you don't set a value $sortable['sort_when_creating'] the package will automatically assign the highest order number to a new model;

I don't fully understand the opposite case, maybe it's one of those "too obvious" things haha. What happens when I DO set that value (as shown above)? What does sort_when_creating = true mean?

Thanks!

Sorting without touching timestamps

Is there a way to sort without changing the updated_at column?

My model defaults is timestamps active BUT when sorting with Model::setNewOrder() I would like to disable it temporarily.

Any help is welcome.

Changing the sort breaks the sort if the model uses scopeOrdered()

changing the sort ( using moveOrder*() ) breaks the sort if the model uses scopeOrdered()

protected $orderBy = 'order_col';
protected $orderDirection = 'ASC';

public function scopeOrdered($query)
    {
        if ($this->orderBy)
        {
            return $query->orderBy($this->orderBy, $this->orderDirection);
        }

        return $query;
    }

Custom pivot model: order_column doesn't have a default value

Hello! I can't make work this behavior with custom pivot model.
I have models:

class Questionnaire extends Model
{
    use HasTranslations;

    protected $fillable = [
        'title', 'is_default', 'type', 'company_id'
    ];
    public $translatable = ['title'];

    public function attributes()
    {
        return $this->belongsToMany(Attribute::class, 'questionnaire_attribute')->using(QuestionnaireAttribute::class);
    }
}

class Attribute extends Model
{
    use HasTranslations;

    protected $fillable = [
        'name', 'title', 'type', 'icon', 'is_notify_filter'
    ];
    public $translatable = ['title'];

    public function questionnaires()
    {
        return $this->belongsToMany(Questionnaire::class, 'questionnaire_attribute')->using(QuestionnaireAttribute::class);
    }
}

class QuestionnaireAttribute extends Pivot implements Sortable
{
    use HasTranslations, SortableTrait;

    protected $table = 'questionnaire_attribute';
    public $translatable = ['title'];

    public function questionnaire()
    {
        return $this->belongsTo(Questionnaire::class);
    }

    public function attribute()
    {
        return $this->belongsTo(Attribute::class);
    }
}

And when try to attach, I get this error:

SQLSTATE[HY000]: General error: 1364 Field 'order_column' doesn't have a default value (SQL: insert into `questionnaire_attribute` (`attribute_id`, `is_clearable`, `is_required`, `questionnaire_id`, `title`) values (1, 0, 1, 1, {"en":"Test"}))

Laravel 5.7, MariaDB 10.3.9

Unable to run all the test with illuminate/support 5+

Hello, good night.

Maybe I am wrong but running the tests with the latest version of Illuminate is not possible, as the method "lists" was removed.

For example

$newOrder = Collection::make(Dummy::all()->lists('id'))->shuffle()->toArray();

I think the correct method on Illuminate 5 is "pluck".

Should we make SortableTest compatible with both?

Rearranging Isn't Working

I'm using eloquent-sortable in my Laravel Admin CRUD table and everything is appearing okay, but when I try to reorder items, I get a success message but the items don't reorder.

I wasn't able to find any guidelines on how the database tables should be set up, so I'm wondering if my order_column isn't set up correctly.

Video Controller

use SortableTrait;

public $sortable = [
    'order_column_name' => 'order',
    'sort_when_creating' => true,
];
...
$grid->order('Order')->orderable()->sortable();

Database
The database has a column order with integers, but they aren't unique. Hoping they don't NEED to be because it would be a pain to fix this.

Not firing model events when changing order

Perhaps a feature request rather than an issue.

When I sort a model and change its order column I would like it recognise that is has been updated in the same way as if I changed any other field. As well as changing the updated_at column (which it does) I need to use $touches to touch the parent and also to fire the updated event so that I can mark the "parent of the parent" as updated. These don't appear to happen.

Add Global Scope

I have seen in other issues that you pretend to keep this package as light as possible, but I think adding a global scope to order by the order column by default would make sense for this package. Would you consider a PR for this?

How I can make it order by type (grouped)

Hi, I have have a model with multiple types (just a filed "type") and each type should have it's own order, how I can achieve this with this package? If no, can you recommend any alternative?

Update order column & re-sort all models

If $model->update(['order' => 3]);..
Would be 🔥 if other models updated also.
So the model originally with order 3 would be 4 and so on.
I have the order in a nova field and it would make it so simple.
Not quite sure how one would go about it design wise though.

moveToEnd() is not working correctly when a grouping field is used

Hi,
Here the scenario: I've a "sortable" Page model that is related to a Topic model (foreign_key: topic_id) and "sort_when_creating" is true.
The sort order for each group of Pages is related to the Topic: if Topic 1 has five pages they have order_column values of 1,2,3,4,5, if I've a "Topic 2" with four pages, order_column's values are "1,2,3,4".

Here is the bug: if I create the first Page for the Topic 1, is "topic_id" is null, so the order_column value is 1. Then I associate the Page to the Topic and I call the moveToEnd() (topic_id now is 1): order_colum is 1, because I've only one Page.
Then I create a second Page: "topic_id" is null, so the order_column value is 1, again..when I associate the Page to the Topic 1 and I call the moveToEnd(), I'm expecting the order_column value to be "2"...but is not: its value is still 1.

I've already forked the project and solved the bug (I ran the tests and they are green), I'm opening the issue just to associate the PR to it...I'm not sure if I'm doing right....sorry, in case!

Thanks

Using Eloquet Sortable on Pivot table

I've looked through the issues, and was wondering if it would be possible to add documentation for using this package on pivot tables. I know that Spatie/tags uses it, but was having trouble understanding it there.

Installing on MAMP but error not to install Laravel

I'm trying to install on Laravel. 5.4.18. But I'm getting this error:

    - Conclusion: remove laravel/framework v5.4.18
    - Conclusion: don't install laravel/framework v5.4.18
    - spatie/eloquent-sortable 2.3.0 requires illuminate/support ~5.1.0|~5.2.0|~5.3.0 -> satisfiable by illuminate/support[v5.1.1, v5.1.13, v5.1.16, v5.1.2, v5.1.20, v5.1.22, v5.1.25, v5.1.28, v5.1.30, v5.1.31, v5.1.41, v5.1.6, v5.1.8, v5.2.0, v5.2.19, v5.2.21, v5.2.24, v5.2.25, v5.2.26, v5.2.27, v5.2.28, v5.2.31, v5.2.32, v5.2.37, v5.2.43, v5.2.45, v5.2.6, v5.2.7, v5.3.0, v5.3.16, v5.3.23, v5.3.4].
    - don't install illuminate/support v5.1.1|don't install laravel/framework v5.4.18
    - don't install illuminate/support v5.1.13|don't install laravel/framework v5.4.18
    - don't install illuminate/support v5.1.16|don't install laravel/framework v5.4.18
    - don't install illuminate/support v5.1.2|don't install laravel/framework v5.4.18
    - don't install illuminate/support v5.1.20|don't install laravel/framework v5.4.18
    - don't install illuminate/support v5.1.22|don't install laravel/framework v5.4.18
    - don't install illuminate/support v5.1.25|don't install laravel/framework v5.4.18
    - don't install illuminate/support v5.1.28|don't install laravel/framework v5.4.18
    - don't install illuminate/support v5.1.30|don't install laravel/framework v5.4.18
    - don't install illuminate/support v5.1.31|don't install laravel/framework v5.4.18
    - don't install illuminate/support v5.1.41|don't install laravel/framework v5.4.18
    - don't install illuminate/support v5.1.6|don't install laravel/framework v5.4.18
    - don't install illuminate/support v5.1.8|don't install laravel/framework v5.4.18
    - don't install illuminate/support v5.2.0|don't install laravel/framework v5.4.18
    - don't install illuminate/support v5.2.19|don't install laravel/framework v5.4.18
    - don't install illuminate/support v5.2.21|don't install laravel/framework v5.4.18
    - don't install illuminate/support v5.2.24|don't install laravel/framework v5.4.18
    - don't install illuminate/support v5.2.25|don't install laravel/framework v5.4.18
    - don't install illuminate/support v5.2.26|don't install laravel/framework v5.4.18
    - don't install illuminate/support v5.2.27|don't install laravel/framework v5.4.18
    - don't install illuminate/support v5.2.28|don't install laravel/framework v5.4.18
    - don't install illuminate/support v5.2.31|don't install laravel/framework v5.4.18
    - don't install illuminate/support v5.2.32|don't install laravel/framework v5.4.18
    - don't install illuminate/support v5.2.37|don't install laravel/framework v5.4.18
    - don't install illuminate/support v5.2.43|don't install laravel/framework v5.4.18
    - don't install illuminate/support v5.2.45|don't install laravel/framework v5.4.18
    - don't install illuminate/support v5.2.6|don't install laravel/framework v5.4.18
    - don't install illuminate/support v5.2.7|don't install laravel/framework v5.4.18
    - don't install illuminate/support v5.3.0|don't install laravel/framework v5.4.18
    - don't install illuminate/support v5.3.16|don't install laravel/framework v5.4.18
    - don't install illuminate/support v5.3.23|don't install laravel/framework v5.4.18
    - don't install illuminate/support v5.3.4|don't install laravel/framework v5.4.18
    - Installation request for laravel/framework (locked at v5.4.18, required as 5.4.*) -> satisfiable by laravel/framework[v5.4.18].

MAMP is set to PHP7.1.1.

What could be the cause?

Grouped ordering

Hello.

Would you accept a PR that implements grouped ordering? With tests of course.

This feature was requested multiple times in #2 and #36.

I would really love this feature. It's the only thing that's keeping me from using this package.

Thanks

Reset order when destroy

Hi,
after all thanks for the package, it´s super usefull!

One question about destroy models. Is there no method to reset the positions?
For example, I have the following models:

[
  0 => [
    "title" => "Item 1",
    "order_column" => "1",
  ],
  1 => [
    "title" => "Item 1",
    "order_column" => "2",
  ],
  2 => [
    "title" => "Item 1",
    "order_column" => "3",
  ],
  3 => [
    "title" => "Item 1",
    "order_column" => "4",
  ],
]

Now, if I destroy Item 3, there are a gap between orders 2 and 4.
A method that reset all orders without gap??

Actually, I do this, but I´m not sure if it´s the best option:

public function destroy( Link $link )
{
    $link->delete();

    $orderedLinks = Link::ordered()->pluck('id')->toArray();

    Link::setNewOrder($orderedLinks);

    return redirect()->back();
}

Thank you!!

Option to reverse sort order when creating

When creating a new model, this package currently set to order column to the maximum value + 1.

I believe it would be useful to have the option to reverse this functionality. An optional element in the $sortable array could trigger the package to set the order column to the minimum value - 1, when creating a new model.

laravel 5.4 with php5.6 can not install.

The eloquent-sortable v2.3.0 is lastest version support php5.X but can not install in laravel 5.4 that is the lastest version support php 5.X.

Many old system need more time to upgrade to php 7.X.
Any possible to provide a version support laravel 5.4 with php5.X?

Thanks.

Possible Duplicate Order Values?

The following code (from

public function setHighestOrderNumber(): void
):

public function setHighestOrderNumber(): void
{
    $orderColumnName = $this->determineOrderColumnName();

    $this->$orderColumnName = $this->getHighestOrderNumber() + 1;
}

public function getHighestOrderNumber(): int
{
    return (int) $this->buildSortQuery()->max($this->determineOrderColumnName());
}

...seems to generate the order number, using max then simply adds one to it.

But if one fired enough of these in succession, wouldn't it be possible to get the same max? And hence, on might get an order column with value 1,1,1,2,3,4,5?

moveOrderUp select always first element

In the method 'moveOrderUp' of the trait, it selects the first element of all the ones with lower ordering than the current:

$swapWithModel = static::limit(1)
->ordered()
->where($orderColumnName, '<', $this->$orderColumnName)
->first();

Shouldn't that be 'last()' in line 131, because the last element would be the element 'above' the current one, since the first is always the one with order number 1?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.