diff --git a/modules/backend/lang/en/lang.php b/modules/backend/lang/en/lang.php
index ce47fd36b..ea44841bb 100644
--- a/modules/backend/lang/en/lang.php
+++ b/modules/backend/lang/en/lang.php
@@ -343,7 +343,8 @@ return [
'email' => 'Email'
],
'filter' => [
- 'all' => 'all'
+ 'all' => 'all',
+ 'options_method_not_exists' => "The model class :model must define a method :method() returning options for the ':filter' filter."
],
'import_export' => [
'upload_csv_file' => '1. Upload a CSV file',
diff --git a/modules/backend/widgets/Filter.php b/modules/backend/widgets/Filter.php
index 4e674cdb6..30d5dd53a 100644
--- a/modules/backend/widgets/Filter.php
+++ b/modules/backend/widgets/Filter.php
@@ -1,6 +1,8 @@
setScopeValue($scope, $checked);
break;
+
+ case 'switch':
+ $value = post('value');
+ $this->setScopeValue($scope, $value);
+ break;
}
/*
@@ -179,12 +186,12 @@ class Filter extends WidgetBase
*/
protected function getAvailableOptions($scope, $searchQuery = null)
{
- if (count($scope->options)) {
- return $scope->options;
+ if ($scope->options) {
+ return $this->getOptionsFromArray($scope, $searchQuery);
}
$available = [];
- $nameColumn = $this->getScopeNameColumn($scope);
+ $nameColumn = $this->getScopeNameFrom($scope);
$options = $this->getOptionsFromModel($scope, $searchQuery);
foreach ($options as $option) {
$available[$option->getKey()] = $option->{$nameColumn};
@@ -216,6 +223,7 @@ class Filter extends WidgetBase
/**
* Looks at the model for defined scope items.
+ * @return Collection
*/
protected function getOptionsFromModel($scope, $searchQuery = null)
{
@@ -232,10 +240,97 @@ class Filter extends WidgetBase
return $query->get();
}
- $searchFields = [$model->getKeyName(), $this->getScopeNameColumn($scope)];
+ $searchFields = [$model->getKeyName(), $this->getScopeNameFrom($scope)];
return $query->searchWhere($searchQuery, $searchFields)->get();
}
+ /**
+ * Look at the defined set of options for scope items, or the model method.
+ * @return array
+ */
+ protected function getOptionsFromArray($scope, $searchQuery = null)
+ {
+ /*
+ * Load the data
+ */
+ $options = $scope->options;
+
+ if (is_scalar($options)) {
+ $model = $this->scopeModels[$scope->scopeName];
+ $methodName = $options;
+
+ if (!$model->methodExists($methodName)) {
+ throw new ApplicationException(Lang::get(
+ 'backend::lang.filter.options_method_not_exists',
+ ['model'=>get_class($model), 'method'=>$methodName, 'filter'=>$scope->scopeName]
+ ));
+ }
+
+ $options = $model->$methodName();
+ }
+ elseif (!is_array($options)) {
+ $options = [];
+ }
+
+ /*
+ * Apply the search
+ */
+ $searchQuery = Str::lower($searchQuery);
+ if (strlen($searchQuery)) {
+ $options = $this->filterOptionsBySearch($options, $searchQuery);
+ }
+
+ return $options;
+ }
+
+ /**
+ * Filters an array of options by a search term.
+ * @param array $options
+ * @param string $query
+ * @return array
+ */
+ protected function filterOptionsBySearch($options, $query)
+ {
+ $filteredOptions = [];
+
+ $optionMatchesSearch = function($words, $option) {
+ foreach ($words as $word) {
+ $word = trim($word);
+ if (!strlen($word)) {
+ continue;
+ }
+
+ if (!Str::contains(Str::lower($option), $word)) {
+ return false;
+ }
+ }
+
+ return true;
+ };
+
+ /*
+ * Exact
+ */
+ foreach ($options as $index => $option) {
+ if (Str::is(Str::lower($option), $query)) {
+ $filteredOptions[$index] = $option;
+ unset($options[$index]);
+ }
+ }
+
+ /*
+ * Fuzzy
+ */
+ $words = explode(' ', $query);
+ foreach ($options as $index => $option) {
+ if ($optionMatchesSearch($words, $option)) {
+ $filteredOptions[$index] = $option;
+ }
+ }
+
+ return $filteredOptions;
+ }
+
/**
* Creates a flat array of filter scopes from the configuration.
*/
@@ -362,6 +457,15 @@ class Filter extends WidgetBase
* Condition
*/
if ($scopeConditions = $scope->conditions) {
+
+ /*
+ * Switch scope: multiple conditions, value either 1 or 2
+ */
+ if (is_array($scopeConditions)) {
+ $conditionNum = is_array($value) ? 0 : $value - 1;
+ list($scopeConditions) = array_slice($scopeConditions, $conditionNum);
+ }
+
if (is_array($value)) {
$filtered = implode(',', array_build($value, function ($key, $_value) {
return [$key, Db::getPdo()->quote($_value)];
@@ -444,7 +548,7 @@ class Filter extends WidgetBase
* @param string $scope
* @return string
*/
- public function getScopeNameColumn($scope)
+ public function getScopeNameFrom($scope)
{
if (is_string($scope)) {
$scope = $this->getScope($scope);
diff --git a/modules/backend/widgets/filter/partials/_scope_switch.htm b/modules/backend/widgets/filter/partials/_scope_switch.htm
new file mode 100644
index 000000000..0a9bf2df4
--- /dev/null
+++ b/modules/backend/widgets/filter/partials/_scope_switch.htm
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/modules/backend/widgets/form/partials/_field_checkboxlist.htm b/modules/backend/widgets/form/partials/_field_checkboxlist.htm
index 78508b84e..836d682ba 100644
--- a/modules/backend/widgets/form/partials/_field_checkboxlist.htm
+++ b/modules/backend/widgets/form/partials/_field_checkboxlist.htm
@@ -1,6 +1,7 @@
options();
$checkedValues = (array) $field->value;
+ $isScrollable = count($fieldOptions) > 10;
?>
previewMode && $field->value): ?>
@@ -34,8 +35,8 @@
previewMode && count($fieldOptions)): ?>
-
- 10): ?>
+
+
= e(trans('backend::lang.form.select')) ?>:
@@ -76,7 +77,7 @@
- 10): ?>
+
diff --git a/modules/cms/widgets/TemplateList.php b/modules/cms/widgets/TemplateList.php
index 16ba076c2..28fef8719 100644
--- a/modules/cms/widgets/TemplateList.php
+++ b/modules/cms/widgets/TemplateList.php
@@ -322,7 +322,7 @@ class TemplateList extends WidgetBase
return true;
}
- protected function itemContainsWord($word, $item , $exact = false)
+ protected function itemContainsWord($word, $item, $exact = false)
{
$operator = $exact ? 'is' : 'contains';
diff --git a/modules/system/assets/ui/js/checkbox.js b/modules/system/assets/ui/js/checkbox.js
index c0047155f..b33334b81 100644
--- a/modules/system/assets/ui/js/checkbox.js
+++ b/modules/system/assets/ui/js/checkbox.js
@@ -24,4 +24,68 @@
}
})
+ //
+ // Intermediate checkboxes
+ //
+
+ $(document).render(function() {
+ $('div.custom-checkbox.is-indeterminate > input').each(function() {
+ var $el = $(this),
+ checked = $el.data('checked')
+
+ switch (checked) {
+
+ // Unchecked
+ case 1:
+ $el.prop('indeterminate', true)
+ break
+
+ // Checked
+ case 2:
+ $el.prop('indeterminate', false)
+ $el.prop('checked', true)
+ break
+
+ // Unchecked
+ default:
+ $el.prop('indeterminate', false)
+ $el.prop('checked', false)
+ }
+ })
+ })
+
+ $(document).on('click', 'div.custom-checkbox.is-indeterminate > label', function() {
+ var $el = $(this).parent().find('input:first'),
+ checked = $el.data('checked')
+
+ if (checked === undefined) {
+ checked = $el.is(':checked') ? 1 : 0
+ }
+
+ switch (checked) {
+
+ // Unchecked, going indeterminate
+ case 0:
+ $el.data('checked', 1)
+ $el.prop('indeterminate', true)
+ break
+
+ // Indeterminate, going checked
+ case 1:
+ $el.data('checked', 2)
+ $el.prop('indeterminate', false)
+ $el.prop('checked', true)
+ break
+
+ // Checked, going unchecked
+ default:
+ $el.data('checked', 0)
+ $el.prop('indeterminate', false)
+ $el.prop('checked', false)
+ }
+
+ $el.trigger('change')
+ return false
+ })
+
})(jQuery);
\ No newline at end of file
diff --git a/modules/system/assets/ui/js/filter.js b/modules/system/assets/ui/js/filter.js
index 40e15ef08..3b765435e 100644
--- a/modules/system/assets/ui/js/filter.js
+++ b/modules/system/assets/ui/js/filter.js
@@ -82,14 +82,14 @@
var self = this
this.$el.on('change', '.filter-scope input[type="checkbox"]', function(){
- var isChecked = $(this).is(':checked'),
- $scope = $(this).closest('.filter-scope'),
- scopeName = $scope.data('scope-name')
+ var $scope = $(this).closest('.filter-scope')
- self.scopeValues[scopeName] = isChecked
- self.checkboxToggle(scopeName, isChecked)
-
- $scope.toggleClass('active', isChecked)
+ if ($scope.hasClass('is-indeterminate')) {
+ self.switchToggle($(this))
+ }
+ else {
+ self.checkboxToggle($(this))
+ }
})
$('.filter-scope input[type="checkbox"]', this.$el).each(function() {
@@ -351,22 +351,54 @@
})
}
- FilterWidget.prototype.checkboxToggle = function(scopeName, isChecked) {
- if (!this.options.updateHandler)
- return
+ FilterWidget.prototype.checkboxToggle = function($el) {
+ var isChecked = $el.is(':checked'),
+ $scope = $el.closest('.filter-scope'),
+ scopeName = $scope.data('scope-name')
- var $form = this.$el.closest('form'),
- data = {
- scopeName: scopeName,
- value: isChecked
- }
+ this.scopeValues[scopeName] = isChecked
- $.oc.stripeLoadIndicator.show()
- $form.request(this.options.updateHandler, {
- data: data
- }).always(function(){
- $.oc.stripeLoadIndicator.hide()
- })
+ if (this.options.updateHandler) {
+ var $form = this.$el.closest('form'),
+ data = {
+ scopeName: scopeName,
+ value: isChecked
+ }
+
+ $.oc.stripeLoadIndicator.show()
+ $form.request(this.options.updateHandler, {
+ data: data
+ }).always(function(){
+ $.oc.stripeLoadIndicator.hide()
+ })
+ }
+
+ $scope.toggleClass('active', isChecked)
+ }
+
+ FilterWidget.prototype.switchToggle = function($el) {
+ var switchValue = $el.data('checked'),
+ $scope = $el.closest('.filter-scope'),
+ scopeName = $scope.data('scope-name')
+
+ this.scopeValues[scopeName] = switchValue
+
+ if (this.options.updateHandler) {
+ var $form = this.$el.closest('form'),
+ data = {
+ scopeName: scopeName,
+ value: switchValue
+ }
+
+ $.oc.stripeLoadIndicator.show()
+ $form.request(this.options.updateHandler, {
+ data: data
+ }).always(function(){
+ $.oc.stripeLoadIndicator.hide()
+ })
+ }
+
+ $scope.toggleClass('active', !!switchValue)
}
diff --git a/modules/system/assets/ui/less/checkbox.less b/modules/system/assets/ui/less/checkbox.less
index 40ede8e06..0e24c06da 100644
--- a/modules/system/assets/ui/less/checkbox.less
+++ b/modules/system/assets/ui/less/checkbox.less
@@ -71,7 +71,7 @@
top: 0;
background-color: #FFFFFF;
border: 1px solid @color-checkbox-border;
- .box-shadow(~"inset 0 1px 0 @{input-border}, 0 1px 0 #fff");
+ .box-shadow(~"inset 0 1px 0 @{input-border}, 0 1px 0 rgba(255,255,255,.5)");
}
&:hover:before {
border-color: darken(@color-checkbox-border, 10%);
@@ -123,8 +123,8 @@
}
}
+ input[type=checkbox]:indeterminate + label:before,
input[type=checkbox]:checked + label:before {
- .icon(@check);
border-color: @color-checkbox-checked;
background-color: @color-checkbox-checked;
font-size: 12px;
@@ -133,6 +133,22 @@
.box-shadow(none);
}
+ input[type=checkbox]:checked + label:before {
+ .icon(@check);
+ }
+
+ input[type=checkbox]:indeterminate + label:before {
+ .icon(@minus);
+ }
+
+ input:disabled + label:before {
+ border: 1px solid @color-checkbox-border !important;
+ }
+
+ input:disabled:checked + label:before {
+ background-color: #999;
+ }
+
&:focus {
outline: none;
label:before {
diff --git a/modules/system/assets/ui/less/filter.less b/modules/system/assets/ui/less/filter.less
index add9fccb9..4f337c3bc 100644
--- a/modules/system/assets/ui/less/filter.less
+++ b/modules/system/assets/ui/less/filter.less
@@ -79,10 +79,6 @@
label {
padding-left: 25px;
-
- &:before {
- top: -1px;
- }
}
&:after {
@@ -116,6 +112,7 @@
border: none;
border-bottom: 1px solid @color-filter-border;
.border-bottom-radius(0);
+ .box-shadow(none);
background-color: transparent;
}
@@ -159,7 +156,7 @@
}
.filter-items {
- height: 100px;
+ max-height: 135px;
overflow: auto;
background-color: @color-filter-items-bg;
@@ -191,7 +188,7 @@
@media (max-width: @screen-xs) {
.control-filter-popover {
.filter-items {
- height: 200px;
+ max-height: 200px;
}
.filter-search {
input {
diff --git a/modules/system/assets/ui/less/form.less b/modules/system/assets/ui/less/form.less
index d3fbca5d8..4fc4cdc3d 100644
--- a/modules/system/assets/ui/less/form.less
+++ b/modules/system/assets/ui/less/form.less
@@ -153,6 +153,10 @@
margin-top: -5px;
}
+ &.field-align-above {
+ margin-top: -5px;
+ }
+
&.field-slim {
&.span-left, &.span-right {
width: 50%;
@@ -287,18 +291,25 @@
&.size-giant { min-height: @size-giant; }
}
-.field-checkboxlist {
+.field-checkboxlist:not(.is-scrollable) {
padding: 20px 20px 2px 20px;
.border-radius(@border-radius-base);
background: @color-form-checkboxlist-background;
+ border: 1px solid @color-form-checkboxlist-border;
- .checkbox:last-of-type {
- margin-bottom: 0;
+ //.checkbox:last-of-type {
+ // margin-bottom: 0;
+ //}
+}
+
+.field-checkboxlist.is-scrollable {
+ small {
+ color: @text-muted;
}
}
.field-checkboxlist-scrollable {
- background: white;
+ background: @color-form-checkboxlist-background;
border: 1px solid @color-form-checkboxlist-border;
padding-left: 15px;
height: @size-large + 100;
diff --git a/modules/system/assets/ui/storm-min.js b/modules/system/assets/ui/storm-min.js
index d4482b45b..1b1f11a0e 100644
--- a/modules/system/assets/ui/storm-min.js
+++ b/modules/system/assets/ui/storm-min.js
@@ -1925,7 +1925,29 @@ return
$cb.get(0).checked=!$cb.get(0).checked
$cb.data('oc-space-timestamp',e.timeStamp)
$cb.trigger('change')
-return false}})})(jQuery);+function($){"use strict";var BalloonSelector=function(element,options){this.$el=$(element)
+return false}})
+$(document).render(function(){$('div.custom-checkbox.is-indeterminate > input').each(function(){var $el=$(this),checked=$el.data('checked')
+switch(checked){case 1:$el.prop('indeterminate',true)
+break
+case 2:$el.prop('indeterminate',false)
+$el.prop('checked',true)
+break
+default:$el.prop('indeterminate',false)
+$el.prop('checked',false)}})})
+$(document).on('click','div.custom-checkbox.is-indeterminate > label',function(){var $el=$(this).parent().find('input:first'),checked=$el.data('checked')
+if(checked===undefined){checked=$el.is(':checked')?1:0}
+switch(checked){case 0:$el.data('checked',1)
+$el.prop('indeterminate',true)
+break
+case 1:$el.data('checked',2)
+$el.prop('indeterminate',false)
+$el.prop('checked',true)
+break
+default:$el.data('checked',0)
+$el.prop('indeterminate',false)
+$el.prop('checked',false)}
+$el.trigger('change')
+return false})})(jQuery);+function($){"use strict";var BalloonSelector=function(element,options){this.$el=$(element)
this.$field=$('input',this.$el)
this.options=options||{};var self=this;$('li',this.$el).click(function(){if(self.$el.hasClass('control-disabled'))
return
@@ -2076,10 +2098,9 @@ FilterWidget.prototype.getPopoverTemplate=function(){return'
\
'}
FilterWidget.prototype.init=function(){var self=this
-this.$el.on('change','.filter-scope input[type="checkbox"]',function(){var isChecked=$(this).is(':checked'),$scope=$(this).closest('.filter-scope'),scopeName=$scope.data('scope-name')
-self.scopeValues[scopeName]=isChecked
-self.checkboxToggle(scopeName,isChecked)
-$scope.toggleClass('active',isChecked)})
+this.$el.on('change','.filter-scope input[type="checkbox"]',function(){var $scope=$(this).closest('.filter-scope')
+if($scope.hasClass('is-indeterminate')){self.switchToggle($(this))}
+else{self.checkboxToggle($(this))}})
$('.filter-scope input[type="checkbox"]',this.$el).each(function(){$(this).closest('.filter-scope').toggleClass('active',$(this).is(':checked'))})
this.$el.on('click','a.filter-scope',function(){var $scope=$(this),scopeName=$scope.data('scope-name')
if($scope.hasClass('filter-scope-open'))return
@@ -2166,11 +2187,18 @@ return
var $form=this.$el.closest('form'),data={scopeName:scopeName,options:this.scopeValues[scopeName]}
$.oc.stripeLoadIndicator.show()
$form.request(this.options.updateHandler,{data:data}).always(function(){$.oc.stripeLoadIndicator.hide()})}
-FilterWidget.prototype.checkboxToggle=function(scopeName,isChecked){if(!this.options.updateHandler)
-return
-var $form=this.$el.closest('form'),data={scopeName:scopeName,value:isChecked}
+FilterWidget.prototype.checkboxToggle=function($el){var isChecked=$el.is(':checked'),$scope=$el.closest('.filter-scope'),scopeName=$scope.data('scope-name')
+this.scopeValues[scopeName]=isChecked
+if(this.options.updateHandler){var $form=this.$el.closest('form'),data={scopeName:scopeName,value:isChecked}
$.oc.stripeLoadIndicator.show()
$form.request(this.options.updateHandler,{data:data}).always(function(){$.oc.stripeLoadIndicator.hide()})}
+$scope.toggleClass('active',isChecked)}
+FilterWidget.prototype.switchToggle=function($el){var switchValue=$el.data('checked'),$scope=$el.closest('.filter-scope'),scopeName=$scope.data('scope-name')
+this.scopeValues[scopeName]=switchValue
+if(this.options.updateHandler){var $form=this.$el.closest('form'),data={scopeName:scopeName,value:switchValue}
+$.oc.stripeLoadIndicator.show()
+$form.request(this.options.updateHandler,{data:data}).always(function(){$.oc.stripeLoadIndicator.hide()})}
+$scope.toggleClass('active',!!switchValue)}
var old=$.fn.filterWidget
$.fn.filterWidget=function(option){var args=arguments,result
this.each(function(){var $this=$(this)
diff --git a/modules/system/assets/ui/storm.css b/modules/system/assets/ui/storm.css
index 026761ab1..ff73b7438 100644
--- a/modules/system/assets/ui/storm.css
+++ b/modules/system/assets/ui/storm.css
@@ -2348,7 +2348,7 @@ html.cssanimations .cursor-loading-indicator.hide{display:none}
.custom-checkbox,.custom-radio{padding-left:23px;margin-top:0}
.custom-checkbox input[type=radio],.custom-radio input[type=radio],.custom-checkbox input[type=checkbox],.custom-radio input[type=checkbox]{display:none}
.custom-checkbox label,.custom-radio label{display:inline-block;cursor:pointer;position:relative;padding-left:25px;margin-right:15px;margin-left:-20px;font-size:13px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}
-.custom-checkbox label:before,.custom-radio label:before{content:"";display:inline-block;text-align:center;color:#ffffff;width:18px;height:18px;margin-right:15px;position:absolute;left:-3px;top:0;background-color:#FFFFFF;border:1px solid #bdc3c7;-webkit-box-shadow:inset 0 1px 0 #bdc3c7,0 1px 0 #fff;box-shadow:inset 0 1px 0 #bdc3c7,0 1px 0 #fff}
+.custom-checkbox label:before,.custom-radio label:before{content:"";display:inline-block;text-align:center;color:#ffffff;width:18px;height:18px;margin-right:15px;position:absolute;left:-3px;top:0;background-color:#FFFFFF;border:1px solid #bdc3c7;-webkit-box-shadow:inset 0 1px 0 #bdc3c7,0 1px 0 rgba(255,255,255,.5);box-shadow:inset 0 1px 0 #bdc3c7,0 1px 0 rgba(255,255,255,.5)}
.custom-checkbox label:hover:before,.custom-radio label:hover:before{border-color:#a1aab0}
.custom-checkbox label:active:before,.custom-radio label:active:before{border-color:#869198;border-width:2px}
.custom-checkbox input[type=radio]:checked + label:before,.custom-radio input[type=radio]:checked + label:before{border-color:#1f99dc;line-height:17px;border-width:2px}
@@ -2357,7 +2357,11 @@ html.cssanimations .cursor-loading-indicator.hide{display:none}
.custom-checkbox input[type=radio][data-radio-color=green]:checked + label:after,.custom-radio input[type=radio][data-radio-color=green]:checked + label:after{background-color:#76a544}
.custom-checkbox input[type=radio][data-radio-color=red]:checked + label:before,.custom-radio input[type=radio][data-radio-color=red]:checked + label:before{border-color:#bb2424}
.custom-checkbox input[type=radio][data-radio-color=red]:checked + label:after,.custom-radio input[type=radio][data-radio-color=red]:checked + label:after{background-color:#bb2424}
-.custom-checkbox input[type=checkbox]:checked + label:before,.custom-radio input[type=checkbox]:checked + label:before{font-family:FontAwesome;font-weight:normal;font-style:normal;text-decoration:inherit;-webkit-font-smoothing:antialiased;*margin-right:.3em;content:"\f00c";border-color:#1f99dc;background-color:#1f99dc;font-size:12px;line-height:17px;border-width:2px;-webkit-box-shadow:none;box-shadow:none}
+.custom-checkbox input[type=checkbox]:indeterminate + label:before,.custom-radio input[type=checkbox]:indeterminate + label:before,.custom-checkbox input[type=checkbox]:checked + label:before,.custom-radio input[type=checkbox]:checked + label:before{border-color:#1f99dc;background-color:#1f99dc;font-size:12px;line-height:17px;border-width:2px;-webkit-box-shadow:none;box-shadow:none}
+.custom-checkbox input[type=checkbox]:checked + label:before,.custom-radio input[type=checkbox]:checked + label:before{font-family:FontAwesome;font-weight:normal;font-style:normal;text-decoration:inherit;-webkit-font-smoothing:antialiased;*margin-right:.3em;content:"\f00c"}
+.custom-checkbox input[type=checkbox]:indeterminate + label:before,.custom-radio input[type=checkbox]:indeterminate + label:before{font-family:FontAwesome;font-weight:normal;font-style:normal;text-decoration:inherit;-webkit-font-smoothing:antialiased;*margin-right:.3em;content:"\f068"}
+.custom-checkbox input:disabled + label:before,.custom-radio input:disabled + label:before{border:1px solid #bdc3c7 !important}
+.custom-checkbox input:disabled:checked + label:before,.custom-radio input:disabled:checked + label:before{background-color:#999}
.custom-checkbox:focus,.custom-radio:focus{outline:none}
.custom-checkbox:focus label:before,.custom-radio:focus label:before{border-color:#3498db}
.custom-checkbox p.help-block,.custom-radio p.help-block{padding-left:6px;margin-bottom:17px}
@@ -2409,6 +2413,7 @@ html.cssanimations .cursor-loading-indicator.hide{display:none}
.form-group.checkbox-field{padding-bottom:5px}
.form-group.number-field > .form-control{text-align:right}
.form-group.checkbox-align{padding-left:28px;margin-top:-5px}
+.form-group.field-align-above{margin-top:-5px}
.form-group.field-slim.span-left,.form-group.field-slim.span-right{width:50%}
.form-group.field-indent{padding-left:23px}
.form-group.input-sidebar-control{padding-right:35px}
@@ -2438,9 +2443,9 @@ html.cssanimations .cursor-loading-indicator.hide{display:none}
.field-textarea.size-large{min-height:200px}
.field-textarea.size-huge{min-height:250px}
.field-textarea.size-giant{min-height:350px}
-.field-checkboxlist{padding:20px 20px 2px 20px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;background:#ffffff}
-.field-checkboxlist .checkbox:last-of-type{margin-bottom:0}
-.field-checkboxlist-scrollable{background:white;border:1px solid #e2e2e2;padding-left:15px;height:300px}
+.field-checkboxlist:not(.is-scrollable){padding:20px 20px 2px 20px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;background:#ffffff;border:1px solid #e2e2e2}
+.field-checkboxlist.is-scrollable small{color:#999999}
+.field-checkboxlist-scrollable{background:#ffffff;border:1px solid #e2e2e2;padding-left:15px;height:300px}
.field-checkboxlist-scrollable .checkbox{margin-top:15px;margin-bottom:5px}
.field-checkboxlist-scrollable .checkbox ~ .checkbox{margin-top:0}
.field-recordfinder{background-color:#ffffff;border:1px solid #bdc3c7;overflow:hidden;position:relative;-webkit-box-shadow:inset 0 1px 0 #bdc3c7,0 1px 0 #fff;box-shadow:inset 0 1px 0 #bdc3c7,0 1px 0 #fff;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}
@@ -2753,14 +2758,13 @@ ul.autocomplete.dropdown-menu.inspector-autocomplete li a{padding:5px 12px;white
.control-filter > .filter-scope.checkbox{padding-left:35px}
.control-filter > .filter-scope.checkbox,.control-filter > .filter-scope.checkbox label{margin-bottom:0}
.control-filter > .filter-scope.checkbox label{padding-left:25px}
-.control-filter > .filter-scope.checkbox label:before{top:-1px}
.control-filter > .filter-scope.checkbox:after{content:''}
.control-filter > .filter-scope:hover,.control-filter > .filter-scope.active,.control-filter > .filter-scope:hover.custom-checkbox label,.control-filter > .filter-scope.active.custom-checkbox label{color:#000000}
.control-filter > .filter-scope:hover .filter-label,.control-filter > .filter-scope.active .filter-label{color:#000000}
.control-filter > .filter-scope:hover.active .filter-setting,.control-filter > .filter-scope.active.active .filter-setting{background-color:#5f9a4c}
.control-filter-popover{min-width:275px}
.control-filter-popover .filter-search{min-height:36px}
-.control-filter-popover .filter-search input{min-height:36px;border:none;border-bottom:1px solid #d7dbdd;border-bottom-right-radius:0;border-bottom-left-radius:0;background-color:transparent}
+.control-filter-popover .filter-search input{min-height:36px;border:none;border-bottom:1px solid #d7dbdd;border-bottom-right-radius:0;border-bottom-left-radius:0;-webkit-box-shadow:none;box-shadow:none;background-color:transparent}
.control-filter-popover .filter-search .form-control.icon.search{background-position:right -81px}
.control-filter-popover .filter-search .close{display:none}
.control-filter-popover .filter-items,.control-filter-popover .filter-active-items{color:rgba(0,0,0,0.6);font-size:13px}
@@ -2769,14 +2773,14 @@ ul.autocomplete.dropdown-menu.inspector-autocomplete li a{padding:5px 12px;white
.control-filter-popover .filter-items a,.control-filter-popover .filter-active-items a{text-decoration:none;color:rgba(0,0,0,0.6);display:block;padding:7px 15px}
.control-filter-popover .filter-items a:before,.control-filter-popover .filter-active-items a:before{margin-right:8px;display:inline-block;vertical-align:baseline}
.control-filter-popover .filter-items a:hover,.control-filter-popover .filter-active-items a:hover{background-color:#4da7e8;color:#FFFFFF}
-.control-filter-popover .filter-items{height:100px;overflow:auto;background-color:#fafafa;border-bottom:1px solid #d7dbdd}
+.control-filter-popover .filter-items{max-height:135px;overflow:auto;background-color:#fafafa;border-bottom:1px solid #d7dbdd}
.control-filter-popover .filter-items a:before{font-family:FontAwesome;font-weight:normal;font-style:normal;text-decoration:inherit;-webkit-font-smoothing:antialiased;*margin-right:.3em;content:"\f067"}
.control-filter-popover .filter-items li.loading{padding:7px}
.control-filter-popover .filter-items li.loading > span{display:block;height:20px;width:20px;background-image:url('images/loader-transparent.svg');background-size:20px 20px;background-position:50% 50%;-webkit-animation:spin 1s linear infinite;animation:spin 1s linear infinite}
.control-filter-popover .filter-items li.animate-enter{-webkit-animation:fadeInUp 0.5s;animation:fadeInUp 0.5s}
.control-filter-popover .filter-active-items a:before{font-family:FontAwesome;font-weight:normal;font-style:normal;text-decoration:inherit;-webkit-font-smoothing:antialiased;*margin-right:.3em;content:"\f00d"}
.control-filter-popover .filter-active-items li.animate-enter{-webkit-animation:fadeInDown 0.5s;animation:fadeInDown 0.5s}
-@media (max-width:480px){.control-filter-popover .filter-items{height:200px}
+@media (max-width:480px){.control-filter-popover .filter-items{max-height:200px}
.control-filter-popover .filter-search input{padding-left:36px;padding-right:36px}
.control-filter-popover .filter-search .form-control.icon.search{background-position:0 -81px}
.control-filter-popover .filter-search .close{width:30px;display:block;position:absolute;top:5px;right:5px;font-size:28px;z-index:2}