Sorting
Sorting adds reordering abilities to GORM models and sorts collections.
Register GORM Callbacks
Sorting utilises GORM callbacks to log data, so you will need to register callbacks first:
import (
"github.com/jinzhu/gorm"
"github.com/qor/sorting"
)
func main() {
db, err := gorm.Open("sqlite3", "demo_db")
sorting.RegisterCallbacks(db)
}
Sort Modes
Sorting two modes which can be applied as anonymous fields in a model.
- Ascending mode:smallest first (
sorting.Sorting
) - Descending mode: smallest last (
sorting.SortingDESC
)
They can be used as follows:
type Category struct {
gorm.Model
sorting.Sorting
}
db.Find(&categories)
type Product struct {
gorm.Model
sorting.SortingDESC
}
db.Find(&products)
Reordering
sorting.MoveUp(&db, &product, 1)
sorting.MoveDown(&db, &product, 1)
sorting.MoveTo(&db, &product, 1)
Sorting Collections
Sorts a slice of data:
sorter := sorting.SortableCollection{
PrimaryKeys: []string{"5", "3", "1", "2"}
}
products := []Product{
{Model: gorm.Model{ID: 1}, Code: "1"},
{Model: gorm.Model{ID: 2}, Code: "2"},
{Model: gorm.Model{ID: 3}, Code: "3"},
{Model: gorm.Model{ID: 3}, Code: "4"},
{Model: gorm.Model{ID: 3}, Code: "5"},
}
sorter.Sort(products)
products
Sorting GORM-backend Models
After enabling sorting modes for GORM models, QOR Admin will automatically enable the sorting feature for the resource.
Sorting Demo with QOR
Sorting Collections
If you want to make a sortable select_many, collection_edit field, You could add a sorting.SortableCollection
field with name: Field's name + 'Sorter'; which is used to save above field's data order. That Field will also be identified as sortable in QOR Admin.
type Product struct {
gorm.Model
l10n.Locale
Collections []Collection
CollectionsSorter sorting.SortableCollection
ColorVariations []ColorVariation `l10n:"sync"`
ColorVariationsSorter sorting.SortableCollection
}
type selectedProductsArgument struct {
Products []string
ProductsSorter sorting.SortableCollection
}
selectedProductsResource := Admin.NewResource(&selectedProductsArgument{})
selectedProductsResource.Meta(&admin.Meta{Name: "Products", Type: "select_many", Collection: func(value interface{}, context *qor.Context) [][]string {
var collectionValues [][]string
var products []*models.Product
db.DB.Find(&products)
for _, product := range products {
collectionValues = append(collectionValues, []string{fmt.Sprint(product.ID), product.Name})
}
return collectionValues
}})
Widgets.RegisterWidget(&widget.Widget{
Name: "Products",
Templates: []string{"products"},
Setting: selectedProductsResource,
}
About record with composite primary key.
It do support sorting records with composite primary key. However there is a exception, the version_name
is a "reserved" primary key for the qor/publish2 support. So DO NOT use version_name
as a part of the composite primary key unless you are using qor/publish2.
License
Released under the MIT License.