mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
API: Treedropdownfield showsearch default true, provide better ui
Set search option true on treedropdown fields by default, to provide a fallback solution when trees fail to render (too many children errors) Provide better indication/more meaningful styling to search (match chosen styles for consistency)
This commit is contained in:
parent
4af619e5a0
commit
8b5f89f3b9
@ -1,8 +1,18 @@
|
|||||||
|
/*Mixin used to generate slightly smaller text and forms
|
||||||
|
Used in side panels and action tabs
|
||||||
|
*/
|
||||||
div.TreeDropdownField { width: 400px; background: #fff; border: 1px solid #aaa; cursor: pointer; overflow: visible; position: relative; }
|
div.TreeDropdownField { width: 400px; background: #fff; border: 1px solid #aaa; cursor: pointer; overflow: visible; position: relative; }
|
||||||
div.TreeDropdownField input { border: none; background: none; padding: 0; margin: 0; }
|
div.TreeDropdownField input { border: none; background: none; padding: 0; margin: 0; }
|
||||||
div.TreeDropdownField .treedropdownfield-title { float: left; padding: 7px; width: 90%; line-height: 16px; overflow: hidden; outline: none; }
|
div.TreeDropdownField .treedropdownfield-title, div.TreeDropdownField .treedropdownfield-search { float: left; padding: 7px; width: 90%; line-height: 16px; overflow: hidden; outline: none; z-index: 1; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; -o-text-overflow: ellipsis; }
|
||||||
div.TreeDropdownField .treedropdownfield-panel { clear: left; position: absolute; overflow: auto; display: none; cursor: default; border: 1px solid #aaa; border-top: none; margin: 1px 0 0 -1px; /* account for border on container div */ max-height: 200px; background-color: #fff; z-index: 50; -webkit-box-shadow: 0 4px 5px rgba(0, 0, 0, 0.15); -moz-box-shadow: 0 4px 5px rgba(0, 0, 0, 0.15); -o-box-shadow: 0 4px 5px rgba(0, 0, 0, 0.15); box-shadow: 0 4px 5px rgba(0, 0, 0, 0.15); }
|
div.TreeDropdownField .treedropdownfield-search { background: url("../admin/thirdparty/chosen/chosen/chosen-sprite.png") no-repeat 100% -22px; background: url("../admin/thirdparty/chosen/chosen/chosen-sprite.png") no-repeat 100% -22px, -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(1%, #eeeeee), color-stop(15%, #ffffff)); background: url("../admin/thirdparty/chosen/chosen/chosen-sprite.png") no-repeat 100% -22px, -webkit-linear-gradient(top, #eeeeee 1%, #ffffff 15%); background: url("../admin/thirdparty/chosen/chosen/chosen-sprite.png") no-repeat 100% -22px, -moz-linear-gradient(top, #eeeeee 1%, #ffffff 15%); background: url("../admin/thirdparty/chosen/chosen/chosen-sprite.png") no-repeat 100% -22px, -o-linear-gradient(top, #eeeeee 1%, #ffffff 15%); background: url("../admin/thirdparty/chosen/chosen/chosen-sprite.png") no-repeat 100% -22px, linear-gradient(top, #eeeeee 1%, #ffffff 15%); -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; position: relative; z-index: 1100; border: 1px solid #aaa; display: inline-block; font-family: sans-serif; font-size: 1em; margin: 1.5%; outline: 0; padding: 4px 20px 4px 5px; width: 97%; }
|
||||||
div.TreeDropdownField .treedropdownfield-panel.loading { min-height: 30px; background: white url("../images/network-save.gif") 7px 7px no-repeat; }
|
div.TreeDropdownField.searchable .treedropdownfield-panel.loading { min-height: 64px; background-position: 98% 39px; }
|
||||||
|
div.TreeDropdownField .treedropdownfield-panel { clear: left; position: absolute; display: none; cursor: default; border: 1px solid #aaa; border-top: none; margin: 1px 0 0 -1px; /* account for border on container div */ background-color: #fff; z-index: 70; -webkit-box-shadow: 0 4px 5px rgba(0, 0, 0, 0.15); -moz-box-shadow: 0 4px 5px rgba(0, 0, 0, 0.15); -o-box-shadow: 0 4px 5px rgba(0, 0, 0, 0.15); box-shadow: 0 4px 5px rgba(0, 0, 0, 0.15); }
|
||||||
|
div.TreeDropdownField .treedropdownfield-panel.loading { min-height: 30px; background: white url("../images/network-save.gif") 98% 7px no-repeat; }
|
||||||
|
div.TreeDropdownField .treedropdownfield-panel .tree-holder { position: relative; z-index: 1; }
|
||||||
|
div.TreeDropdownField .treedropdownfield-panel .tree-holder > ul { position: relative; max-height: 200px; overflow-y: auto; }
|
||||||
|
div.TreeDropdownField .treedropdownfield-panel ul { overflow-x: hidden; float: left; width: 100%; }
|
||||||
|
div.TreeDropdownField .treedropdownfield-panel ul .jstree-icon { margin-left: 5px; }
|
||||||
|
div.TreeDropdownField .treedropdownfield-panel ul .jstree-open > ins { background-position: -18px 0; }
|
||||||
div.TreeDropdownField .treedropdownfield-panel ul.tree { margin: 0; }
|
div.TreeDropdownField .treedropdownfield-panel ul.tree { margin: 0; }
|
||||||
div.TreeDropdownField .treedropdownfield-panel ul.tree a { font-size: 12px; }
|
div.TreeDropdownField .treedropdownfield-panel ul.tree a { font-size: 12px; }
|
||||||
div.TreeDropdownField .treedropdownfield-toggle-panel-link { border: none; margin: 0; z-index: 0; padding: 7px 3px; overflow: hidden; -webkit-border-radius: 0 4px 4px 0; -moz-border-radius: 0 4px 4px 0; border-radius: 0 4px 4px 0; }
|
div.TreeDropdownField .treedropdownfield-toggle-panel-link { border: none; margin: 0; z-index: 0; padding: 7px 3px; overflow: hidden; -webkit-border-radius: 0 4px 4px 0; -moz-border-radius: 0 4px 4px 0; border-radius: 0 4px 4px 0; }
|
||||||
|
26
docs/en/changelogs/3.1.1.md
Normal file
26
docs/en/changelogs/3.1.1.md
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
# 3.1.1 (unreleased)
|
||||||
|
|
||||||
|
## Overview ##
|
||||||
|
|
||||||
|
### CMS
|
||||||
|
|
||||||
|
### Framework
|
||||||
|
|
||||||
|
* Treedropdownfield showsearch defaults to true
|
||||||
|
|
||||||
|
## Details
|
||||||
|
|
||||||
|
|
||||||
|
## Upgrading
|
||||||
|
|
||||||
|
### Treedropdownfield showsearch defaults to true
|
||||||
|
The showSearch option of TreedropdownField is now set to true by default. This is to provide a fallback ui for when children of a tree node fail to render (due to too many children). You may set search as false when initializing a TreedropdownField, or afterwards:
|
||||||
|
|
||||||
|
:::php
|
||||||
|
$treedropdownfield->setShowSearch(false);
|
||||||
|
|
||||||
|
If your data requires a specialized search function, you may specify it within:
|
||||||
|
|
||||||
|
:::php
|
||||||
|
$treedropdownfield->setSearchFunction();
|
||||||
|
|
@ -86,7 +86,7 @@ class TreeDropdownField extends FormField {
|
|||||||
* entering the text in the input field.
|
* entering the text in the input field.
|
||||||
*/
|
*/
|
||||||
public function __construct($name, $title = null, $sourceObject = 'Group', $keyField = 'ID',
|
public function __construct($name, $title = null, $sourceObject = 'Group', $keyField = 'ID',
|
||||||
$labelField = 'TreeTitle', $showSearch = false
|
$labelField = 'TreeTitle', $showSearch = true
|
||||||
) {
|
) {
|
||||||
|
|
||||||
$this->sourceObject = $sourceObject;
|
$this->sourceObject = $sourceObject;
|
||||||
@ -181,7 +181,11 @@ class TreeDropdownField extends FormField {
|
|||||||
if($record) {
|
if($record) {
|
||||||
$title = $record->{$this->labelField};
|
$title = $record->{$this->labelField};
|
||||||
} else {
|
} else {
|
||||||
$title = _t('DropdownField.CHOOSE', '(Choose)', 'start value of a dropdown');
|
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');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO Implement for TreeMultiSelectField
|
// TODO Implement for TreeMultiSelectField
|
||||||
|
@ -24,8 +24,8 @@
|
|||||||
|
|
||||||
var strings = {
|
var strings = {
|
||||||
'openlink': 'Open',
|
'openlink': 'Open',
|
||||||
'fieldTitle': '(choose)',
|
'fieldTitle': '(Choose)',
|
||||||
'searchFieldTitle': '(choose or search)'
|
'searchFieldTitle': '(Choose or Search)'
|
||||||
};
|
};
|
||||||
|
|
||||||
var _clickTestFn = function(e) {
|
var _clickTestFn = function(e) {
|
||||||
@ -280,24 +280,14 @@
|
|||||||
$('.TreeDropdownField.searchable').entwine({
|
$('.TreeDropdownField.searchable').entwine({
|
||||||
onadd: function() {
|
onadd: function() {
|
||||||
this._super();
|
this._super();
|
||||||
|
var title = ss.i18n._t(
|
||||||
|
'DropdownField.ENTERTOSEARCH',
|
||||||
|
'Press enter to search'
|
||||||
|
);
|
||||||
|
|
||||||
var title = decodeURIComponent(this.data('title'));
|
this.find('.treedropdownfield-panel').prepend(
|
||||||
this.find('.treedropdownfield-title').replaceWith(
|
$('<input type="text" class="search treedropdownfield-search" data-skip-autofocus="true" placeholder="' + title + '" value="' + this.getValue(title) + '" />')
|
||||||
$('<input type="text" class="treedropdownfield-title search" data-skip-autofocus="true" />')
|
|
||||||
);
|
);
|
||||||
|
|
||||||
this.setTitle(title ? title : strings.searchFieldTitle);
|
|
||||||
},
|
|
||||||
setTitle: function(title) {
|
|
||||||
if(!title && title !== '') title = strings.fieldTitle;
|
|
||||||
|
|
||||||
this.find('.treedropdownfield-title').val(title);
|
|
||||||
},
|
|
||||||
getTitle: function() {
|
|
||||||
return this.find('.treedropdownfield-title').val();
|
|
||||||
},
|
|
||||||
resetTitle: function() {
|
|
||||||
this.setTitle(decodeURIComponent(this.data('title')));
|
|
||||||
},
|
},
|
||||||
search: function(str, callback) {
|
search: function(str, callback) {
|
||||||
this.openPanel();
|
this.openPanel();
|
||||||
@ -306,18 +296,24 @@
|
|||||||
cancelSearch: function() {
|
cancelSearch: function() {
|
||||||
this.closePanel();
|
this.closePanel();
|
||||||
this.loadTree();
|
this.loadTree();
|
||||||
this.resetTitle();
|
},
|
||||||
|
getValue: function(title){
|
||||||
|
//Provide value for IE8 and 9 as they don't support placeholders
|
||||||
|
return ($.browser.msie && parseInt($.browser.version, 10) <= 9) ? title:'';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$('.TreeDropdownField.searchable input.search').entwine({
|
$('.TreeDropdownField.searchable input.search').entwine({
|
||||||
onfocusin: function(e) {
|
onfocusin: function(){
|
||||||
var field = this.getField();
|
//IE placeholder support
|
||||||
field.setTitle('');
|
this.val('');
|
||||||
},
|
},
|
||||||
onfocusout: function(e) {
|
onfocusout: function(){
|
||||||
var field = this.getField();
|
//IE placeholder support
|
||||||
field.resetTitle();
|
var value = this.closest('.TreeDropdownField').getValue(this.attr('placeholder'));
|
||||||
|
if(this.val() === ''){
|
||||||
|
this.val(value);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
onkeydown: function(e) {
|
onkeydown: function(e) {
|
||||||
var field = this.getField();
|
var field = this.getField();
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
@import 'compass';
|
||||||
|
@import "../admin/scss/_mixins";
|
||||||
|
|
||||||
div.TreeDropdownField {
|
div.TreeDropdownField {
|
||||||
width: 400px;
|
width: 400px;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
@ -20,20 +23,49 @@ div.TreeDropdownField {
|
|||||||
line-height: 16px;
|
line-height: 16px;
|
||||||
overflow:hidden;
|
overflow:hidden;
|
||||||
outline: none;
|
outline: none;
|
||||||
|
z-index:1;
|
||||||
|
@include hide-text-overflow;
|
||||||
|
}
|
||||||
|
|
||||||
|
.treedropdownfield-search{
|
||||||
|
@extend .treedropdownfield-title;
|
||||||
|
|
||||||
|
//Style search box to match chosen search
|
||||||
|
$bgImage: '../admin/thirdparty/chosen/chosen/chosen-sprite.png';
|
||||||
|
|
||||||
|
background:url($bgImage) no-repeat 100% -22px; //For browers that only support 1 background
|
||||||
|
@include background(
|
||||||
|
url($bgImage) no-repeat 100% -22px,
|
||||||
|
linear-gradient(top, #eeeeee 1%, #ffffff 15%)
|
||||||
|
);
|
||||||
|
@include box-sizing(border-box);
|
||||||
|
position:relative;
|
||||||
|
z-index:1100; //Needed to work within modales in chrome
|
||||||
|
border: 1px solid #aaa;
|
||||||
|
display:inline-block;
|
||||||
|
font-family: sans-serif;
|
||||||
|
font-size: 1em;
|
||||||
|
margin:1.5%;
|
||||||
|
outline: 0;
|
||||||
|
padding: 4px 20px 4px 5px;
|
||||||
|
width:97%; //optimized for most common tree width
|
||||||
|
}
|
||||||
|
|
||||||
|
&.searchable .treedropdownfield-panel.loading{
|
||||||
|
min-height: 16px /* icon */ + 14px /* padding */ + 34px /* approx height search input */; // Ensure there's room for loading indicator
|
||||||
|
background-position: 98% 39px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.treedropdownfield-panel {
|
.treedropdownfield-panel {
|
||||||
clear: left;
|
clear: left;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
overflow: auto;
|
|
||||||
display: none;
|
display: none;
|
||||||
cursor: default;
|
cursor: default;
|
||||||
border: 1px solid #aaa;
|
border: 1px solid #aaa;
|
||||||
border-top: none;
|
border-top: none;
|
||||||
margin: 1px 0 0 -1px; /* account for border on container div */
|
margin: 1px 0 0 -1px; /* account for border on container div */
|
||||||
max-height:200px;
|
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
z-index: 50;
|
z-index: 70;
|
||||||
-webkit-box-shadow: 0 4px 5px rgba(0,0,0,.15);
|
-webkit-box-shadow: 0 4px 5px rgba(0,0,0,.15);
|
||||||
-moz-box-shadow : 0 4px 5px rgba(0,0,0,.15);
|
-moz-box-shadow : 0 4px 5px rgba(0,0,0,.15);
|
||||||
-o-box-shadow : 0 4px 5px rgba(0,0,0,.15);
|
-o-box-shadow : 0 4px 5px rgba(0,0,0,.15);
|
||||||
@ -41,12 +73,33 @@ div.TreeDropdownField {
|
|||||||
|
|
||||||
&.loading {
|
&.loading {
|
||||||
min-height: 16px /* icon */ + 14px /* padding */; // Ensure there's room for loading indicator
|
min-height: 16px /* icon */ + 14px /* padding */; // Ensure there's room for loading indicator
|
||||||
background: #fff url("../images/network-save.gif") 7px 7px no-repeat;
|
background: #fff url("../images/network-save.gif") 98% 7px no-repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree-holder{
|
||||||
|
position:relative;
|
||||||
|
z-index:1;
|
||||||
|
> ul{
|
||||||
|
position:relative;
|
||||||
|
max-height:200px;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ul{
|
||||||
|
overflow-x:hidden;
|
||||||
|
float:left;
|
||||||
|
width:100%;
|
||||||
|
.jstree-icon{
|
||||||
|
margin-left:5px; //move to align with possible search box
|
||||||
|
}
|
||||||
|
.jstree-open > ins{
|
||||||
|
background-position:-18px 0; //move to align with possible search box
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ul.tree {
|
ul.tree {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
|
||||||
a {
|
a {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user