Removed `minNumber` and `maxNumber` options, they are not enforceable on the client side without a lot more work. Added `number` filter type, added missing numberrange filter template, consolidated styles for filter-date and filter-number filters.
This commit is contained in:
Luke Towers 2017-08-05 18:10:36 -06:00
parent be87fbbb87
commit a705a70f35
9 changed files with 133 additions and 122 deletions

View File

@ -440,7 +440,8 @@ return [
'filter' => [
'all' => 'all',
'options_method_not_exists' => "The model class :model must define a method :method() returning options for the ':filter' filter.",
'date_all' => 'all period'
'date_all' => 'all periods',
'number_all' => 'all numbers',
],
'import_export' => [
'upload_csv_file' => '1. Upload a CSV file',

View File

@ -135,6 +135,12 @@ class Filter extends WidgetBase
}
}
break;
case 'number':
if (is_numeric($scope->value)) {
$params['number'] = $scope->value;
}
break;
case 'numberrange':
if ($scope->value && is_array($scope->value) && count($scope->value) === 2 &&
@ -144,25 +150,14 @@ class Filter extends WidgetBase
$min = $scope->value[0];
$max = $scope->value[1];
if($min) {
$params['minStr'] = $min;
$params['min'] = $min;
}
else {
$params['minStr'] = '';
$params['min'] = null;
}
$params['minStr'] = $min ? $min : '';
$params['min'] = $min ? $min : null;
if($max) {
$params['maxStr'] = $max;
$params['max'] = $max;
}
else {
$params['maxStr'] = '∞';
$params['max'] = null;
}
$params['maxStr'] = $max ? $max : '∞';
$params['max'] = $max ? $max : null;
}
break
break;
}
return $this->makePartial('scope_'.$scope->type, $params);
@ -230,8 +225,22 @@ class Filter extends WidgetBase
$this->setScopeValue($scope, $dates);
break;
case 'number':
$numbers = $this->numbersFromAjax(post('options.numbers'));
if (!empty($numbers)) {
list($number) = $numbers;
}
else {
$number = null;
}
$this->setScopeValue($scope, $number);
break;
case 'numberrange':
$numbers = $this->numbersFromAjax(post('options.numbers'));
if (!empty($numbers)) {
list($min, $max) = $numbers;
@ -242,7 +251,7 @@ class Filter extends WidgetBase
}
$this->setScopeValue($scope, $numbers);
break;
break;
}
/*
@ -527,14 +536,6 @@ class Filter extends WidgetBase
$scopeObj->{$property} = $value;
}
/*
* Ensure number options are set
*/
if (!isset($config['minNumber'])) {
$scopeObj->minNumber = '0';
$scopeObj->maxNumber = '999999999';
}
$this->allScopes[$name] = $scopeObj;
}
}
@ -658,6 +659,24 @@ class Filter extends WidgetBase
break;
case 'number':
if (is_numeric($scope->value)) {
/*
* Condition
*/
if ($scopeConditions = $scope->conditions) {
$query->whereRaw(DbDongle::parse(strtr($scopeConditions, [
':filtered' => $scope->value,
])));
}
/*
* Scope
*/
elseif ($scopeMethod = $scope->scope) {
$query->$scopeMethod($scope->value);
}
}
case 'numberrange':
if (is_array($scope->value) && count($scope->value) > 1) {
list($min, $max) = array_values($scope->value);
@ -846,7 +865,6 @@ class Filter extends WidgetBase
/**
* Convert an array from the posted dates
*
* @param mixed $scope
* @param array $dates
*
* @return array
@ -881,6 +899,36 @@ class Filter extends WidgetBase
return $dates;
}
/**
* Convert an array from the posted numbers
*
* @param array $dates
*
* @return array
*/
protected function numbersFromAjax($ajaxNumbers)
{
$numbers = [];
$numberRegex = '/\d/';
if (!empty($ajaxNumbers)) {
if (!is_array($ajaxNumbers) && preg_match($numberRegex, $ajaxNumbers)) {
$numbers = [$ajaxNumbers];
} else {
foreach ($ajaxNumbers as $i => $number) {
if (preg_match($numberRegex, $number)) {
$numbers[] = $number;
} else {
$numbers = [];
break;
}
}
}
}
return $numbers;
}
/**
* @param mixed $scope
*

View File

@ -1,6 +1,6 @@
<!-- Date scope -->
<a
class="filter-scope-date <?= isset($date) ? 'active' : '' ?>"
class="filter-scope-date filter-has-popover <?= isset($date) ? 'active' : '' ?>"
href="javascript:;"
data-scope-name="<?= $scope->scopeName ?>"
data-scope-data="<?= e(json_encode([

View File

@ -1,6 +1,6 @@
<!-- Date Range scope -->
<a
class="filter-scope-date range <?= isset($after) || isset($before) ? 'active' : '' ?>"
class="filter-scope-date filter-has-popover range <?= isset($after) || isset($before) ? 'active' : '' ?>"
href="javascript:;"
data-scope-name="<?= $scope->scopeName ?>"
data-scope-data="<?= e(json_encode([

View File

@ -0,0 +1,12 @@
<!-- Number scope -->
<a
class="filter-scope-number filter-has-popover <?= isset($number) ? 'active' : '' ?>"
href="javascript:;"
data-scope-name="<?= $scope->scopeName ?>"
data-scope-data="<?= e(json_encode([
'number' => isset($number) ? $number : null,
]))
?>">
<span class="filter-label"><?= e(trans($scope->label)) ?>:</span>
<span class="filter-setting"><?= isset($number) ? $number : e(trans('backend::lang.filter.number_all')) ?></span>
</a>

View File

@ -0,0 +1,12 @@
<!-- Number Range scope -->
<a
class="filter-scope-number filter-has-popover range <?= isset($min) || isset($max) ? 'active' : '' ?>"
href="javascript:;"
data-scope-name="<?= $scope->scopeName ?>"
data-scope-data="<?= e(json_encode([
'numbers' => [isset($min) ? $min : null, isset($max) ? $max : null],
]))
?>">
<span class="filter-label"><?= e(trans($scope->label)) ?>:</span>
<span class="filter-setting"><?= isset($minStr) && isset($maxStr) ? ($minStr . ' → ' . $maxStr) : e(trans('backend::lang.filter.number_all')) ?></span>
</a>

View File

@ -106,7 +106,7 @@
return ' \
<form> \
<input type="hidden" name="scopeName" value="{{ scopeName }}" /> \
<div id="controlFilterPopover" class="control-filter-popover control-filter-date-popover"> \
<div id="controlFilterPopover" class="control-filter-popover control-filter-box-popover"> \
<div class="filter-search loading-indicator-container size-input-text"> \
<div class="field-datepicker"> \
<div class="input-with-icon right-align"> \
@ -138,7 +138,7 @@
return ' \
<form> \
<input type="hidden" name="scopeName" value="{{ scopeName }}" /> \
<div id="controlFilterPopover" class="control-filter-popover control-filter-date-popover --range"> \
<div id="controlFilterPopover" class="control-filter-popover control-filter-box-popover --range"> \
<div class="filter-search loading-indicator-container size-input-text"> \
<div class="field-datepicker"> \
<div class="input-with-icon right-align"> \

View File

@ -93,22 +93,27 @@
}
/*
* Get popover date template
* Get popover number template
*/
FilterWidget.prototype.getPopoverNumberTemplate = function () {
return ' \
<form> \
<input type="hidden" name="scopeName" value="{{ scopeName }}" /> \
<div id="controlFilterPopoverNum" class="control-filter-popover control-filter-number-popover"> \
<div id="controlFilterPopoverNum" class="control-filter-popover control-filter-box-popover --range">\
<div class="filter-search loading-indicator-container size-input-text"> \
<input \
type="text" \
name="number" \
value="{{ number }}" \
class="form-control align-right" \
autocomplete="off" \
placeholder="{{ number_placeholder }}" /> \
<div class="field-number"> \
<input \
type="number" \
name="number" \
value="{{ number }}" \
class="form-control align-right" \
autocomplete="off" \
placeholder="{{ number_placeholder }}" /> \
</div> \
<div class="filter-buttons"> \
<button class="btn btn-block btn-primary" data-trigger="filter"> \
{{ filter_button_text }} \
</button> \
<button class="btn btn-block btn-secondary" data-trigger="clear"> \
{{ reset_button_text }} \
</button> \
@ -120,18 +125,18 @@
}
/*
* Get popover range template
* Get popover number range template
*/
FilterWidget.prototype.getPopoverNumberRangeTemplate = function () {
return ' \
<form> \
<input type="hidden" name="scopeName" value="{{ scopeName }}" /> \
<div id="controlFilterPopoverNum" class="control-filter-popover control-filter-number-popover --range"> \
<div id="controlFilterPopoverNum" class="control-filter-popover control-filter-box-popover --range"> \
<div class="filter-search loading-indicator-container size-input-text"> \
<div class="field-number"> \
<div class="right-align"> \
<input \
type="text" \
type="number" \
name="number" \
value="{{ number }}" \
class="form-control align-right" \
@ -142,7 +147,8 @@
<div class="field-number"> \
<div class="right-align"> \
<input \
type="text" \
type="number" \
{{ maxNumber }} \
name="number" \
value="{{ number }}" \
class="form-control align-right" \
@ -171,8 +177,8 @@
data = $.extend({}, data, {
filter_button_text: this.getLang('filter.numbers.filter_button_text'),
reset_button_text: this.getLang('filter.numberss.reset_button_text'),
number_placeholder: this.getLang('filter.numberss.number_placeholder', 'Number')
reset_button_text: this.getLang('filter.numbers.reset_button_text'),
number_placeholder: this.getLang('filter.numbers.number_placeholder', 'Number')
})
data.scopeName = scopeName
@ -205,7 +211,7 @@
// Destroy any popovers already bound
$scope.data('oc.popover', null)
console.log(data);
$scope.ocPopover({
content: Mustache.render(this.getPopoverNumberRangeTemplate(), data),
modal: false,
@ -235,30 +241,23 @@
defaultValue = data.numbers[index] ? data.numbers[index] : ''
}
if (!isRange) {
defaults.onSelect = function () {
self.filterByNumber()
}
}
numberinput.value = '' !== defaultValue ? defaultValue : '';
})
}
FilterWidget.prototype.updateScopeNumberSetting = function ($scope, numbers) {
var $setting = $scope.find('.filter-setting'),
dateRegex =/\d*/,
numberRegex =/\d*/,
reset = false
if (numbers && numbers.length) {
numbers[0] = numbers[0] && numbers[0].match(dateRegex) ? numbers[0] : null
numbers[0] = numbers[0] && numbers[0].match(numberRegex) ? numbers[0] : null
if (numbers.length > 1) {
numbers[1] = numbers[1] && numbers[1].match(dateRegex) ? numbers[1] : null
numbers[1] = numbers[1] && numbers[1].match(numberRegex) ? numbers[1] : null
if(numbers[0] || numbers[1]) {
var min = numbers[0] ? numbers[0] : '',
var min = numbers[0] ? numbers[0] : '',
max = numbers[1] ? numbers[1] : '∞'
$setting.text(min + ' → ' + max)

View File

@ -101,39 +101,7 @@
}
}
> .filter-scope-date {
display: inline-block;
padding: (@padding-standard / 2);
.filter-label {}
.filter-setting {
display: inline-block;
.transition(color 0.6s);
}
&:after {
font-size: 14px;
.icon(@angle-down);
}
&.active {
.filter-setting {
padding-left: 5px;
padding-right: 5px;
color: #FFF;
background-color: @color-filter-bg-active;
.border-radius(4px);
.transition(~'color 1s, background-color 1s');
}
}
&:hover {
color: #000;
.filter-label { color: @color-filter-text; }
&.active .filter-setting { background-color: darken(@color-filter-bg-active, 5%); }
}
}
> .filter-scope-number {
> .filter-has-popover {
display: inline-block;
padding: (@padding-standard / 2);
.filter-label {}
@ -248,36 +216,7 @@
li.animate-enter { .animation(fadeInDown .5s); }
}
&.control-filter-date-popover {
min-width: 190px;
.filter-buttons {
margin: 0;
padding: 0;
&:after {
content: "";
display: block;
clear: both;
}
.btn {
float: left;
width: 100%;
margin: 0;
border-radius: 0;
text-align: center;
}
}
&.--range {
.filter-buttons .btn {
width: 50%;
}
}
}
&.control-filter-number-popover {
&.control-filter-box-popover {
min-width: 190px;
.filter-buttons {