mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 12:05:37 +00:00
FEATURE: Disable specific tree nodes in TreeDropdownField
DO NOT MERGE: to be reviewed. This feature request was born out of wanting the ability to disable (for example) a top level page from being selected, while still being able to select a child page. Using setFilterFunction() simply removes the node and its children. Extra styling for disabled nodes Disable ability to select a disabled node for TreeDropdownField Disable hover CSS changes Fixing merge conflict during rebase Return a boolean for nodeIsDisabled()
This commit is contained in:
parent
92e98f0adb
commit
6b3b61873a
@ -747,6 +747,7 @@ form.import-form label.left { width: 250px; }
|
||||
.cms .jstree li.jstree-open > ul, .TreeDropdownField .treedropdownfield-panel .jstree li.jstree-open > ul { display: block; }
|
||||
.cms .jstree li.jstree-closed > ul, .TreeDropdownField .treedropdownfield-panel .jstree li.jstree-closed > ul { display: none; }
|
||||
.cms .jstree li.disabled > a, .TreeDropdownField .treedropdownfield-panel .jstree li.disabled > a { color: #aaaaaa; }
|
||||
.cms .jstree li.disabled > a:hover, .TreeDropdownField .treedropdownfield-panel .jstree li.disabled > a:hover { background: transparent; cursor: default; }
|
||||
.cms .jstree li.edit-disabled > a, .TreeDropdownField .treedropdownfield-panel .jstree li.edit-disabled > a { color: #aaaaaa; }
|
||||
.cms .jstree li > .jstree-icon, .TreeDropdownField .treedropdownfield-panel .jstree li > .jstree-icon { cursor: pointer; }
|
||||
.cms .jstree ins, .TreeDropdownField .treedropdownfield-panel .jstree ins { display: inline-block; text-decoration: none; width: 18px; height: 18px; margin: 0 0 0 0; padding: 0; float: left; }
|
||||
@ -817,6 +818,7 @@ form.import-form label.left { width: 250px; }
|
||||
.tree-holder.jstree-apple li.Root > a .jstree-icon, .cms-tree.jstree-apple li.Root > a .jstree-icon { background-position: -56px -36px; }
|
||||
.tree-holder.jstree-apple li.status-deletedonlive .text, .cms-tree.jstree-apple li.status-deletedonlive .text { text-decoration: line-through; }
|
||||
.tree-holder.jstree-apple li.jstree-checked > a, .tree-holder.jstree-apple li.jstree-checked > a:link, .cms-tree.jstree-apple li.jstree-checked > a, .cms-tree.jstree-apple li.jstree-checked > a:link { background-color: #efe999; }
|
||||
.tree-holder.jstree-apple li.disabled > a > .jstree-checkbox, .cms-tree.jstree-apple li.disabled > a > .jstree-checkbox { background-position: -57px -54px; }
|
||||
.tree-holder.jstree-apple li.readonly, .cms-tree.jstree-apple li.readonly { color: #aaaaaa; padding-left: 18px; }
|
||||
.tree-holder.jstree-apple li.readonly a, .tree-holder.jstree-apple li.readonly a:link, .cms-tree.jstree-apple li.readonly a, .cms-tree.jstree-apple li.readonly a:link { margin: 0; padding: 0; }
|
||||
.tree-holder.jstree-apple li.readonly .jstree-icon, .cms-tree.jstree-apple li.readonly .jstree-icon { display: none; }
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 6.8 KiB After Width: | Height: | Size: 2.5 KiB |
@ -32,6 +32,10 @@
|
||||
}
|
||||
&.disabled > a {
|
||||
color: #aaaaaa;
|
||||
&:hover {
|
||||
background: transparent;
|
||||
cursor: default;
|
||||
}
|
||||
}
|
||||
&.edit-disabled > a {
|
||||
color: #aaaaaa;
|
||||
@ -438,7 +442,12 @@
|
||||
> a, > a:link{
|
||||
background-color: $color-cms-batchactions-menu-selected-background;
|
||||
}
|
||||
}
|
||||
}
|
||||
&.disabled {
|
||||
> a > .jstree-checkbox {
|
||||
background-position: -57px -54px;
|
||||
}
|
||||
}
|
||||
&.readonly {
|
||||
color: $color-text-disabled;
|
||||
padding-left: 18px;
|
||||
|
@ -53,7 +53,8 @@ class TreeDropdownField extends FormField {
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
protected $sourceObject, $keyField, $labelField, $filterCallback, $searchCallback, $baseID = 0;
|
||||
protected $sourceObject, $keyField, $labelField, $filterCallback,
|
||||
$disableCallback, $searchCallback, $baseID = 0;
|
||||
/**
|
||||
* @var string default child method in Hierarcy->getChildrenAsUL
|
||||
*/
|
||||
@ -122,6 +123,20 @@ class TreeDropdownField extends FormField {
|
||||
$this->filterCallback = $callback;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a callback used to disable checkboxes for some items in the tree
|
||||
*
|
||||
* @param callback $callback
|
||||
*/
|
||||
public function setDisableFunction($callback) {
|
||||
if(!is_callable($callback, true)) {
|
||||
throw new InvalidArgumentException('TreeDropdownField->setDisableFunction(): not passed a valid callback');
|
||||
}
|
||||
|
||||
$this->disableCallback = $callback;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a callback used to search the hierarchy globally, even before
|
||||
@ -181,11 +196,11 @@ class TreeDropdownField extends FormField {
|
||||
if($record) {
|
||||
$title = $record->{$this->labelField};
|
||||
} else {
|
||||
if($this->showSearch){
|
||||
if($this->showSearch) {
|
||||
$title = _t('DropdownField.CHOOSESEARCH', '(Choose or Search)', 'start value of a dropdown');
|
||||
}else{
|
||||
$title = _t('DropdownField.CHOOSE', '(Choose)', 'start value of a dropdown');
|
||||
}
|
||||
} else {
|
||||
$title = _t('DropdownField.CHOOSE', '(Choose)', 'start value of a dropdown');
|
||||
}
|
||||
}
|
||||
|
||||
// TODO Implement for TreeMultiSelectField
|
||||
@ -276,12 +291,13 @@ class TreeDropdownField extends FormField {
|
||||
$keyField = $self->keyField;
|
||||
$labelField = $self->labelField;
|
||||
return sprintf(
|
||||
'<li id="selector-%s-%s" data-id="%s" class="class-%s %s"><a rel="%d">%s</a>',
|
||||
'<li id="selector-%s-%s" data-id="%s" class="class-%s %s %s"><a rel="%d">%s</a>',
|
||||
Convert::raw2xml($self->getName()),
|
||||
Convert::raw2xml($child->$keyField),
|
||||
Convert::raw2xml($child->$keyField),
|
||||
Convert::raw2xml($child->class),
|
||||
Convert::raw2xml($child->markingClasses()),
|
||||
($self->nodeIsDisabled($child)) ? 'disabled' : '',
|
||||
(int)$child->ID,
|
||||
$escapeLabelField ? Convert::raw2xml($child->$labelField) : $child->$labelField
|
||||
);
|
||||
@ -351,6 +367,15 @@ class TreeDropdownField extends FormField {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Marking a specific node in the tree as disabled
|
||||
* @param $node
|
||||
* @return boolean
|
||||
*/
|
||||
public function nodeIsDisabled($node) {
|
||||
return ($this->disableCallback && call_user_func($this->disableCallback, $node));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param String $field
|
||||
*/
|
||||
|
@ -228,7 +228,25 @@
|
||||
'themes': {
|
||||
'theme': 'apple'
|
||||
},
|
||||
'plugins': ['html_data', 'ui', 'themes']
|
||||
'types' : {
|
||||
'types' : {
|
||||
'default': {
|
||||
'check_node': function(node) {
|
||||
return ( ! node.hasClass('disabled'));
|
||||
},
|
||||
'uncheck_node': function(node) {
|
||||
return ( ! node.hasClass('disabled'));
|
||||
},
|
||||
'select_node': function(node) {
|
||||
return ( ! node.hasClass('disabled'));
|
||||
},
|
||||
'deselect_node': function(node) {
|
||||
return ( ! node.hasClass('disabled'));
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
'plugins': ['html_data', 'ui', 'themes', 'types']
|
||||
};
|
||||
},
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user