Для того чтобы настроить ограничения на списках, компонент flexberry-objectlistview
включает в себя следующие инструменты:
- фильтрация списков
- наложение ограничения (метод
objectListViewLimitPredicate
) - поиск по атрибутам
Настройка фильтрации на списке
Для того чтобы на списковой форме реализовать возможность фильтрации необходимо:
- Указать свойства поиска в шаблоне списковой формы.
- При необходимости переопределить предикаты в роуте списковой формы.
По умолчанию отфильтровать можно не только по кнопке обновления списка, но и по клавише Enter
. Также по умолчанию доступна фильтрация по подстроке при незаданной операции сравнения.
Настройка шаблона формы
В шаблоне формы необходимо указать для компонента flexberry-objectlistview
следующие свойства:
{{flexberry-objectlistview
enableFilters=true
filters=filters
applyFilters=(action "applyFilters")
resetFilters=(action "resetFilters")
// ...
}}
Настройка контроллера формы
Контроллер формы должен наследоваться от ListFormController
или EditFormController
:
import ListFormController from 'ember-flexberry/controllers/list-form';
export default ListFormController.extend({
});
Можно переопределить доступне условия фильтрации, и компоненты используемые для ввода значений:
import ListFormController from 'ember-flexberry/controllers/list-form';
export default ListFormController.extend({
actions: {
/**
@method actions.conditionsByType
@param {String} type The type name.
@param {Object} attribute An object with an attribute description.
@return {Array} An array with items for `flexberry-dropdown` component.
*/
conditionsByType(type, attribute) {
return ['eq', 'neq'];
},
/**
@method actions.componentForFilter
@param {String} type The type name.
@param {Boolean} relation If this is a relation, then `true`.
@param {Object} attribute An object with an attribute description.
@return {Object} An object with component description.
*/
componentForFilter(type, relation, attribute) {
switch (type) {
case 'decimal':
return { name: 'flexberry-textbox', properties: { class: 'compact fluid' } };
default:
return {};
}
},
},
});
{{flexberry-objectlistview
componentForFilter=(action "componentForFilter")
conditionsByType=(action "conditionsByType")
// ...
}}
Настройка роута формы
Роут формы должен наследоваться от ListFormRoute
или EditFormRoute
:
import ListFormRoute from 'ember-flexberry/routes/list-form';
export default ListFormRoute.extend({
});
Переопределив метод predicateForFilter
в роуте, можно изменить логику создания предиката для фильрации:
import ListFormRoute from 'ember-flexberry/routes/list-form';
export default ListFormRoute.extend({
/**
@method predicateForFilter
@param {Object} filter An object with filter description.
@return {BasePredicate} The predicate or null.
*/
predicateForFilter(filter) {
if (filter.type === 'string' && filter.condition === 'like') {
return new StringPredicate(filter.name).contains(filter.pattern);
}
if (filter.type === 'decimal') {
return new SimplePredicate(filter.name, filter.condition, filter.pattern ? Number(filter.pattern) : filter.pattern);
}
return this._super(...arguments);
},
});
Фильтрация по датам без учета времени
Если нужно фильтровать поля с датами не учитывая время, то нужно в роуте в методе predicateForFilter
добавить условие:
predicateForFilter(filter) {
if (filter.type === 'date') {
return new DatePredicate(filter.name, filter.condition, filter.pattern, true);
}
return this._super(...arguments);
},
Пользовательские функции для фильтров
Если на прикладном уровне нужны специфические фильтры, то можно использовать функцию predicateForAttribute
. Данная функция получает на вход атрибут, по которому происходит фильтрация, значение, по которому фильтровать, условие фильтра и возвращает предикат, по которому затем формируется параметр $filter
в OData-запросе.
Операции “пусто” и “не пусто”
Если существует необходимость использовать операции, не требующие заполнения значения, то можно настроить соответствующую операцию для предиката в контроллере формы. Например
// ...
case 'string':
return ['eq', 'neq', 'like'];
return ['eq', 'neq', 'like', 'empty'];
// ...
Далее в роуте задать соответствующее условие. Например,
// ...
if (filter.type === 'string' && filter.condition === 'empty') {
return new SimplePredicate(filter.name, 'eq', null);
}
// ...
Наложение ограничений
Особенности наложения ограничений на Flexberry Objectlistview связаны с тем, что данные для контрола вычитываются в роуте. Соответственно, чтобы не допустить вычитывания данных без наложенного ограничения, ограничение должно быть определено, когда выполняется хук model
в роуте формы.
Таким образом, чтобы наложить ограничение, необходимо переопределить метод objectListViewLimitPredicate
в роуте прикладной списковой формы, чтобы он возвращал предикат для ограничения.
Например, есть форма limit-function-example
. Eсли на странице отображается чётное количество записей, необходимо вывести записи, у которых в поле “address” есть буква “S”. При нечетном количестве - имеющие в поле “address” букву “п”.
Переопределяем метод objectListViewLimitPredicate
в роуте соответствующей прикладной списковой формы.
import Ember from 'ember';
import ListFormRoute from 'ember-flexberry/routes/list-form';
import { StringPredicate } from 'ember-flexberry-data/query/predicate';
export default ListFormRoute.extend({
objectListViewLimitPredicate(options) {
let methodOptions = Ember.merge({
modelName: undefined,
projectionName: undefined,
params: undefined
}, options);
if (methodOptions.modelName === this.get('modelName') &&
methodOptions.projectionName === this.get('modelProjection')) {
let currentPerPageValue = methodOptions.params ? methodOptions.params.perPage : undefined;
let limitFunction = (currentPerPageValue && currentPerPageValue % 2 === 0) ?
new StringPredicate('address').contains('S') :
new StringPredicate('address').contains('п');
return limitFunction;
}
return undefined;
}
});
Настройка поиска по всем атрибутам для стандартного списка
Для того чтобы на списковой форме реализовать возможность поиска по всем атрибутам необходимо:
- Указать свойства поиска в шаблоне списковой формы.
- При необходимости переопределить предикаты в роуте списковой формы.
Настройка шаблона формы для поиска
Настройка шаблона формы осуществляется следующим образом:
{{flexberry-objectlistview
filters=filters
applyFilters=(action "applyFilters")
resetFilters=(action "resetFilters")
filterButton=true
filterText=filter
filterByAnyWord=filterByAnyWord // поиск по некоторым словам
filterByAllWords=filterByAllWords // поиск по всем словам
filterByAnyMatch=(action 'filterByAnyMatch')
// ...
}}
filterByAnyWord
- в результате будут выданы все строки, в которых указано заданное в поиске слово/несколько слов.
filterByAllWords
- в результате будут выданы только те строки, в которых указано заданное слово/словосочетание.
По-умолчанию поиск осуществляется по подстроке.
Реализация отображена на ember-стенде
filterByAnyWord
и filterByAllWords
нельзя использовать вместе, если не реализованы дополнительные элементы тулбара (кнопки) для включения/отключения типа поиска.Настройка роута формы для поиска
Переопределить, как будет строится предикат, можно следующим образом:
predicateForAttribute(attribute, filter) {
switch (attribute.type) {
case 'boolean':
let yes = ['TRUE', 'True', 'true', 'YES', 'Yes', 'yes', 'ДА', 'Да', 'да', '1', '+'];
let no = ['FALSE', 'False', 'false', 'NO', 'No', 'no', 'НЕТ', 'Нет', 'нет', '0', '-'];
if (yes.indexOf(filter) > 0) {
return new SimplePredicate(attribute.name, 'eq', 'true');
}
if (no.indexOf(filter) > 0) {
return new SimplePredicate(attribute.name, 'eq', 'false');
}
return null;
default:
return this._super(...arguments);
}
},
Настройка предиката необходима для корректного поиска значений, имеющих два признака истина/ложь.
Для flexberry-simpleolve настройки аналогичны.
Настройка списка, отображаемого в лукапе
В LookUp показывается компонент flexberry-objectlistview. Параметры для этого компонента можно задавать через событие getLookupFolvProperties
в контроллере формы. Данная настройка описана в статье Настройка поднимаемой по лукапу формы в п. “Настройка фильтрации и количества элементов на странице”.