mirror of
https://github.com/UndefinedOffset/SortableGridField.git
synced 2024-10-22 15:05:38 +00:00
Removed GridFieldSortableObject this is now handled by the developer (see README.md)
GridFieldSortableRows now requires the developer to set the field to sort on Cleaned up handling of many_many relationships
This commit is contained in:
parent
7c68ec17da
commit
3b19642c26
21
README.md
21
README.md
@ -4,25 +4,10 @@ SortableGridField
|
|||||||
Adds drag and drop functionality to SilverStripe 3.0's GridField
|
Adds drag and drop functionality to SilverStripe 3.0's GridField
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
To enable sorting on a data object add one of the following you your sites _config.php
|
To enable sorting on a has_many relationship set up an interger field on your data object.
|
||||||
*mysite/_config.php*
|
|
||||||
|
|
||||||
:::php
|
To enable drag and drop sorting on the grid field add the following to your grid field's config
|
||||||
GridFieldSortableObject::add_sortable_class('{ClassName}'); //For has_many relationships
|
|
||||||
|
|
||||||
GridFieldSortableObject::add_sortable_many_many_relation('{Owner ClassName}', '{Component Name}'); //For many_many relationships
|
|
||||||
|
|
||||||
|
|
||||||
To enable sorting on the grid field add the following to your grid field's config
|
|
||||||
*Grid Field Config*
|
*Grid Field Config*
|
||||||
|
|
||||||
:::php
|
:::php
|
||||||
$myGridConfig->addComponent(new GridFieldSortableRows());
|
$myGridConfig->addComponent(new GridFieldSortableRows('{Column to store sort}'));
|
||||||
|
|
||||||
|
|
||||||
## Known Isuses
|
|
||||||
* Many_many relationship is largely untested and may not work as expected
|
|
||||||
|
|
||||||
|
|
||||||
## Credits
|
|
||||||
GridFieldSortableObject is based off of dataobject_manager's SortableDataObject class by @unclecheese
|
|
@ -1,164 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* @package extensions
|
|
||||||
*/
|
|
||||||
class GridFieldSortableObject extends DataExtension {
|
|
||||||
public static $db=array(
|
|
||||||
'SortOrder'=>'Int'
|
|
||||||
);
|
|
||||||
|
|
||||||
protected static $sortable_classes = array();
|
|
||||||
protected static $many_many_sortable_relations = array();
|
|
||||||
protected static $sort_dir = "ASC";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the direction of the sort, by default it is ASC
|
|
||||||
* @param {string} $dir Sort direction ASC or DESC
|
|
||||||
*/
|
|
||||||
public static function set_sort_dir($dir) {
|
|
||||||
if(strtoupper($dir)!='ASC' && strtoupper($dir)!='DESC') {
|
|
||||||
user_error('Sort direction must be ASC or DESC', E_USER_ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
self::$sort_dir=$dir;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Makes a class sortable
|
|
||||||
* @param {string} $className Name of the DataObject to extend
|
|
||||||
*/
|
|
||||||
public static function add_sortable_class($className) {
|
|
||||||
if(!self::is_sortable_class($className)) {
|
|
||||||
Object::add_extension($className, 'GridFieldSortableObject');
|
|
||||||
|
|
||||||
self::$sortable_classes[]=$className;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Makes a many_many relationship sortable
|
|
||||||
* @param {string} $ownerClass Name of the owner class of the relationship
|
|
||||||
* @param {string} $componentName Name of the relationship
|
|
||||||
*/
|
|
||||||
public static function add_sortable_many_many_relation($ownerClass, $componentName) {
|
|
||||||
list($parentClass, $componentClass, $parentField, $componentField, $table)=singleton($ownerClass)->many_many($componentName);
|
|
||||||
|
|
||||||
Object::add_static_var($ownerClass, 'many_many_extraFields', array(
|
|
||||||
$componentName=>array(
|
|
||||||
'SortOrder'=>'Int'
|
|
||||||
)));
|
|
||||||
|
|
||||||
|
|
||||||
if(!isset(self::$many_many_sortable_relations[$componentClass])) {
|
|
||||||
self::$many_many_sortable_relations[$componentClass] = array();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
self::$many_many_sortable_relations[$componentClass][$parentClass]=$table;
|
|
||||||
self::add_sortable_class($componentClass);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks to see if a given DataObject class is sortable or not
|
|
||||||
* @param {string} $className Name of the DataObject to check
|
|
||||||
*/
|
|
||||||
public static function is_sortable_class($className) {
|
|
||||||
if(in_array($className, self::$sortable_classes)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach(self::$sortable_classes as $class) {
|
|
||||||
if(is_subclass_of($className, $class)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return Object::has_extension($className, 'GridFieldSortableObject');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks to see if a given many_many relationship is sortable or not
|
|
||||||
* @param {string} $componentClass Name of the component's class
|
|
||||||
* @param {string} $parentClass Name of the owner class of the relationship
|
|
||||||
* @return {bool} Returns boolean true if the many_many relationship is sortable
|
|
||||||
*/
|
|
||||||
public static function is_sortable_many_many($componentClass, $parentClass=null) {
|
|
||||||
$map=self::$many_many_sortable_relations;
|
|
||||||
if($parentClass===null) {
|
|
||||||
return isset($map[$componentClass]);
|
|
||||||
}else {
|
|
||||||
if(isset($map[$componentClass])) {
|
|
||||||
return isset($map[$componentClass][$parentClass]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the join tables for the given class name
|
|
||||||
* @param {string} $className Name of the DataObject to fetch for
|
|
||||||
*/
|
|
||||||
public static function get_join_tables($className) {
|
|
||||||
if(isset(self::$many_many_sortable_relations[$className])) {
|
|
||||||
return self::$many_many_sortable_relations[$className];
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Modifies the SQL appending the SortOrder with the direction to the orderby statement
|
|
||||||
* @param {SQLQuery} $query SQL Query to adjust
|
|
||||||
*/
|
|
||||||
public function augmentSQL(SQLQuery &$query) {
|
|
||||||
if(empty($query->select) || $query->delete || in_array("COUNT(*)", $query->select) || in_array("count(*)", $query->select)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
$sort_field=false;
|
|
||||||
if($join_tables=self::get_join_tables($this->owner->class)) {
|
|
||||||
foreach($query->from as $from) {
|
|
||||||
if($sort_field) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach($join_tables as $join_table) {
|
|
||||||
if(stristr($from,$join_table)) {
|
|
||||||
$sort_field="\"$join_table\".\"SortOrder\"";
|
|
||||||
|
|
||||||
if(isset($query->select['SortOrder'])) {
|
|
||||||
$query->select['SortOrder']="\"{$this->owner->class}\".SortOrder AS LocalSort";
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if(!$sort_field) {
|
|
||||||
$sort_field="\"SortOrder\"";
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!$query->orderby || ($query->orderby==$this->owner->stat('default_sort'))) {
|
|
||||||
$query->orderby="$sort_field ".self::$sort_dir;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the sort order on the DataObject when its being written to the database for the first time
|
|
||||||
*/
|
|
||||||
public function onBeforeWrite() {
|
|
||||||
if(!$this->owner->ID) {
|
|
||||||
if($peers=DataList::create($this->owner->class)) {
|
|
||||||
$this->owner->SortOrder=$peers->Count()+1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
?>
|
|
@ -2,7 +2,16 @@
|
|||||||
/**
|
/**
|
||||||
* @package forms
|
* @package forms
|
||||||
*/
|
*/
|
||||||
class GridFieldSortableRows implements GridField_HTMLProvider, GridField_ActionProvider {
|
class GridFieldSortableRows implements GridField_HTMLProvider, GridField_ActionProvider, GridField_DataManipulator {
|
||||||
|
protected $sortColumn;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} $sortColumn Column that should be used to update the sort information
|
||||||
|
*/
|
||||||
|
public function __construct($sortColumn) {
|
||||||
|
$this->sortColumn=$sortColumn;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a map where the keys are fragment names and the values are pieces of HTML to add to these fragments.
|
* Returns a map where the keys are fragment names and the values are pieces of HTML to add to these fragments.
|
||||||
* @param GridField $gridField Grid Field Reference
|
* @param GridField $gridField Grid Field Reference
|
||||||
@ -16,54 +25,52 @@ class GridFieldSortableRows implements GridField_HTMLProvider, GridField_ActionP
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
if(Object::has_extension($gridField->getModelClass(), 'GridFieldSortableObject')) {
|
//Sort order toggle
|
||||||
//Sort order toggle
|
$sortOrderToggle=new GridField_FormAction($gridField, 'sortablerows_toggle', 'Allow drag and drop re-ordering', 'saveGridRowSort', null);
|
||||||
$sortOrderToggle=new GridField_FormAction($gridField, 'sortablerows_toggle', 'Allow drag and drop re-ordering', 'saveGridRowSort', null);
|
$sortOrderToggle->addExtraClass('sortablerows_toggle');
|
||||||
$sortOrderToggle->addExtraClass('sortablerows_toggle');
|
|
||||||
|
|
||||||
//Disable Pagenator
|
//Disable Pagenator
|
||||||
if($gridField->getConfig()->getComponentByType('GridFieldPaginator')) {
|
$disablePagenator=new GridField_FormAction($gridField, 'sortablerows_disablepagenator', 'Disable Pagenator', 'sortableRowsDisablePaginator', null);
|
||||||
$disablePagenator=new GridField_FormAction($gridField, 'sortablerows_disablepagenator', 'Disable Pagenator', 'sortableRowsDisablePaginator', null);
|
$disablePagenator->addExtraClass('sortablerows_disablepagenator');
|
||||||
$disablePagenator->addExtraClass('sortablerows_disablepagenator');
|
|
||||||
}else {
|
|
||||||
$disablePagenator=null;
|
$forTemplate=new ArrayData(array(
|
||||||
}
|
'SortableToggle'=>$sortOrderToggle,
|
||||||
|
'PagenatorToggle'=>$disablePagenator,
|
||||||
$forTemplate=new ArrayData(array(
|
'Checked'=>($state->sortableToggle==true ? ' checked="checked"':'')
|
||||||
'SortableToggle'=>$sortOrderToggle,
|
));
|
||||||
'PagenatorToggle'=>$disablePagenator,
|
|
||||||
'Checked'=>($state->sortableToggle==true ? ' checked="checked"':'')
|
|
||||||
));
|
//Inject Requirements
|
||||||
|
Requirements::css('SortableGridField/css/GridFieldSortableRows.css');
|
||||||
|
Requirements::javascript('SortableGridField/javascript/GridFieldSortableRows.js');
|
||||||
//Inject Requirements
|
|
||||||
Requirements::css('SortableGridField/css/GridFieldSortableRows.css');
|
|
||||||
Requirements::javascript('SortableGridField/javascript/GridFieldSortableRows.js');
|
return array(
|
||||||
|
'header'=>$forTemplate->renderWith('GridFieldSortableRows', array('Colspan'=>count($gridField->getColumns())))
|
||||||
|
);
|
||||||
return array(
|
|
||||||
'header'=>$forTemplate->renderWith('GridFieldSortableRows', array('Colspan'=>count($gridField->getColumns())))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return array();
|
return array();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manipulate the datalist as needed by this grid modifier.
|
||||||
|
* @param {GridField} $gridField Grid Field Reference
|
||||||
|
* @param {SS_List} $dataList Data List to adjust
|
||||||
|
* @return {DataList} Modified Data List
|
||||||
|
*/
|
||||||
|
public function getManipulatedData(GridField $gridField, SS_List $dataList) {
|
||||||
|
return $dataList->sort($this->sortColumn);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a list of the actions handled by this action provider.
|
* Return a list of the actions handled by this action provider.
|
||||||
* @param GridField $gridField Grid Field Reference
|
* @param GridField $gridField Grid Field Reference
|
||||||
* @return {array} Array with action identifier strings.
|
* @return {array} Array with action identifier strings.
|
||||||
*/
|
*/
|
||||||
public function getActions($gridField) {
|
public function getActions($gridField) {
|
||||||
if(Object::has_extension($gridField->getModelClass(), 'GridFieldSortableObject')) {
|
return array('saveGridRowSort', 'sortableRowsDisablePaginator');
|
||||||
if($gridField->getConfig()->getComponentByType('GridFieldPaginator')) {
|
|
||||||
return array('saveGridRowSort', 'sortableRowsDisablePaginator');
|
|
||||||
}else {
|
|
||||||
return array('saveGridRowSort');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return array();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -88,10 +95,8 @@ class GridFieldSortableRows implements GridField_HTMLProvider, GridField_ActionP
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if(Object::has_extension($gridField->getModelClass(), 'GridFieldSortableObject')) {
|
if($actionName=='savegridrowsort') {
|
||||||
if($actionName=='savegridrowsort') {
|
return $this->saveGridRowSort($gridField, $data);
|
||||||
return $this->saveGridRowSort($gridField, $data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,25 +111,14 @@ class GridFieldSortableRows implements GridField_HTMLProvider, GridField_ActionP
|
|||||||
}
|
}
|
||||||
|
|
||||||
$className=$gridField->getModelClass();
|
$className=$gridField->getModelClass();
|
||||||
$ownerClass=$gridField->Form->Controller()->class;
|
$owner=$gridField->Form->getRecord();
|
||||||
$controllerID=$gridField->Form->Controller()->ID;
|
$items=$gridField->getList();
|
||||||
|
$many_many=($items instanceof ManyManyList);
|
||||||
|
$sortColumn=$this->sortColumn;
|
||||||
|
|
||||||
|
|
||||||
$many_many=GridFieldSortableObject::is_sortable_many_many($className);
|
|
||||||
if($many_many) {
|
if($many_many) {
|
||||||
$candidates=singleton($ownerClass)->many_many();
|
list($parentClass, $componentClass, $parentField, $componentField, $table)=$owner->many_many($gridField->getName());
|
||||||
if(is_array($candidates)) {
|
|
||||||
foreach($candidates as $name => $class)
|
|
||||||
if($class==$className) {
|
|
||||||
$relationName=$name;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!isset($relationName)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
list($parentClass, $componentClass, $parentField, $componentField, $table)=singleton($ownerClass)->many_many($relationName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -132,10 +126,10 @@ class GridFieldSortableRows implements GridField_HTMLProvider, GridField_ActionP
|
|||||||
for($sort=0;$sort<count($data['Items']);$sort++) {
|
for($sort=0;$sort<count($data['Items']);$sort++) {
|
||||||
$id=intval($data['Items'][$sort]);
|
$id=intval($data['Items'][$sort]);
|
||||||
if($many_many) {
|
if($many_many) {
|
||||||
DB::query('UPDATE "'.$table.'" SET "SortOrder" = '.($sort+1).' WHERE "'.$className.'ID" = $id AND "'.$ownerClass.'ID" = '.$controllerID);
|
DB::query('UPDATE "'.$table.'" SET "'.$sortColumn.'"='.($sort+1).' WHERE "'.$componentField.'"='.$id.' AND "'.$parentField.'"='.$owner->ID);
|
||||||
}else {
|
}else {
|
||||||
$obj=DataObject::get_by_id($className, $id);
|
$obj=$items->byID($data['Items'][$sort]);
|
||||||
$obj->SortOrder=$sort+1;
|
$obj->$sortColumn=$sort+1;
|
||||||
$obj->write();
|
$obj->write();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user