Компоненты genericFilter
Вы можете установить конфигурацию genericFilter как во время выполнения, так и во время разработки. В этом разделе приведены примеры конфигураций genericFilter времени разработки с использованием каждого из трех предопределенных компонентов фильтра:
| Вы также можете создать собственный компонент фильтра и использовать его как часть genericFilter. Подробности смотрите в разделе Регистрация компонента фильтра. | 
propertyFilter
propertyFilter добавляет условие фильтрации на основе конкретного свойства сущности.
| Этот компонент также можно использовать независимо. Подробности смотрите в разделе propertyFilter. | 
И декларативная, и программная конфигурации, представленные в этом разделе, создают следующий фильтр в экране:
 
Декларативная конфигурация
Конфигурация genericFilter может быть задана декларативно, внутри XML-дескриптора экрана. Смотрите следующий пример конфигурации с propertyFilter:
<layout>
    <genericFilter dataLoader="customerDl"
                   id="genericFilterProperty"> (1)
        <properties include=".*"/>
        <configurations>
            <configuration id="propertyConfiguration"
                           default="true"
                           name="PropertyFilter">
                <propertyFilter property="age"
                                operation="GREATER_OR_EQUAL"
                                operationEditable="true"/> (2)
            </configuration>
        </configurations>
    </genericFilter>
</layout>| 1 | Объявление компонента genericFilter, привязанного к загрузчику данных. | 
| 2 | propertyFilter, указывающий условие на основе свойстваage. | 
Программная конфигурация
Другой способ определения приведенной выше конфигурации - программно, в контроллере экрана:
@Autowired
private UiComponents uiComponents;
@ViewComponent
private GenericFilter pfdtcGenericFilter;
@Autowired
private SingleFilterSupport singleFilterSupport;
@Subscribe
public void onInit(final InitEvent event) {
    DesignTimeConfiguration javaDefaultConfigurationPF =
            pfdtcGenericFilter.addConfiguration("javaDefaultConfiguration",
                    "PropertyFilter configuration"); (1)
    DataLoader dataLoaderPF = pfdtcGenericFilter.getDataLoader();
    PropertyFilter<Integer> agePropertyFilter =
            uiComponents.create(PropertyFilter.class); (2)
    agePropertyFilter.setConditionModificationDelegated(true);
    agePropertyFilter.setDataLoader(dataLoaderPF);
    agePropertyFilter.setProperty("age");
    agePropertyFilter.setOperation(PropertyFilter.Operation.GREATER_OR_EQUAL);
    agePropertyFilter.setOperationEditable(true);
    agePropertyFilter.setParameterName(PropertyConditionUtils.generateParameterName(
            agePropertyFilter.getProperty()));
    agePropertyFilter.setValueComponent(singleFilterSupport.generateValueComponent(
            dataLoaderPF.getContainer().getEntityMetaClass(),
            agePropertyFilter.getProperty(),
            agePropertyFilter.getOperation())); (3)
    javaDefaultConfigurationPF.getRootLogicalFilterComponent()
            .add(agePropertyFilter); (4)
    pfdtcGenericFilter.setCurrentConfiguration(javaDefaultConfigurationPF); (5)
}| 1 | Добавляет конфигурацию времени разработки. Метод принимает два параметра: idконфигурации и название конфигурации. | 
| 2 | Создает экземпляр PropertyFilterи устанавливает его свойства. | 
| 3 | Генерирует компонент для этого фильтра на основе metaClass,propertyиoperation. | 
| 4 | Добавляет фильтр в конфигурацию. LogicalFilterComponentявляется корневым элементом конфигурации. | 
| 5 | Устанавливает текущую конфигурацию. | 
jpqlFilter
jpqlFilter позволяет выполнять фильтрацию на основе JPQL-запроса. Он изменяет JPQL-запрос загрузчика данных, добавляя необязательное предложение join и обязательное предложение where и, следовательно, уточняя результаты поиска.
И декларативная, и программная конфигурации, представленные в этом разделе, создают следующий фильтр в экране:
 
Декларативная конфигурация
Конфигурация genericFilter может быть задана декларативно, внутри XML-дескриптора экрана. Смотрите следующий пример конфигурации с jpqlFilter:
<layout>
    <genericFilter dataLoader="customerDl"
                   id="genericFilterJpql"> (1)
        <properties include=".*"/>
        <configurations>
            <configuration id="jpqlConfiguration"
                           default="true"
                           name="JpqlFilter">
                <jpqlFilter parameterClass="java.lang.String"
                            label="City name is">
                    <condition>
                        <jpql>
                            <join>join {E}.city c</join> (2)
                            <where>c.name = ?</where> (3)
                        </jpql>
                    </condition>
                </jpqlFilter>
            </configuration>
        </configurations>
    </genericFilter>
</layout>| 1 | Объявление компонента genericFilter, привязанного к загрузчику данных. | 
| 2 | Необязательное предложение join. | 
| 3 | Обязательное предложение where.?указывает параметр, который вводится пользователем. | 
Программная конфигурация
Другой способ определения приведенной выше конфигурации - программно, в контроллере экрана:
@Autowired
private UiComponents uiComponents;
@Autowired
private SingleFilterSupport singleFilterSupport;
@ViewComponent
private GenericFilter jfdtcGenericFilter;
@Autowired
private JpqlFilterSupport jpqlFilterSupport;
@Subscribe
public void onInit(final InitEvent event) {
    DesignTimeConfiguration javaDefaultConfigurationJF =
            jfdtcGenericFilter.addConfiguration("javaDefaultConfiguration", "JpqlFilter configuration"); (1)
    DataLoader dataLoaderJF = jfdtcGenericFilter.getDataLoader();
    JpqlFilter<String> jpqlFilter =
            uiComponents.create(JpqlFilter.class); (2)
    jpqlFilter.setConditionModificationDelegated(true);
    jpqlFilter.setDataLoader(dataLoaderJF);
    jpqlFilter.setCondition("c.name = ?", "join {E}.city c");
    jpqlFilter.setParameterClass(String.class);
    jpqlFilter.setLabel("City name is");
    jpqlFilter.setParameterName(jpqlFilterSupport.generateParameterName(
            String.valueOf(jpqlFilter.getId()),
            jpqlFilter.getParameterClass().getSimpleName()));
    jpqlFilter.setValueComponent(singleFilterSupport.generateValueComponent(
            dataLoaderJF.getContainer().getEntityMetaClass(),
            jpqlFilter.hasInExpression(),
            jpqlFilter.getParameterClass())); (3)
    javaDefaultConfigurationJF.getRootLogicalFilterComponent()
            .add(jpqlFilter); (4)
    jfdtcGenericFilter.setCurrentConfiguration(javaDefaultConfigurationJF); (5)
}Фильтр без параметра
jpqlFilter позволяет создать условие, которое только позволяет пользователю выбирать, применять его или нет. С точки зрения пользователя, он не принимает параметров, так как задается непосредственно в запросе.
Например, задайте название города непосредственно в предложении where. Затем пользователи смогут выбирать, показывать ли только клиентов из этого города:
 
<layout>
    <genericFilter id="noParameterFilter"
            dataLoader="customerDl">
        <properties include=".*"/>
        <configurations>
            <configuration id="jpqlConfigurationNoParams"
                           name="JpqlFilter No parameters">
                <jpqlFilter label="Show customers from London"
                            parameterClass="java.lang.Void"
                            defaultValue="true"> (1)
                    <condition>
                        <jpql>
                            <join>join {E}.city c</join>
                            <where>c.name = 'London'</where> (2)
                        </jpql>
                    </condition>
                </jpqlFilter>
            </configuration>
        </configurations>
    </genericFilter>
</layout>| 1 | parameterClass="java.lang.Void"указывает, что условие не ожидает ввода значения параметра;defaultValue=trueозначает, что условие применяется. | 
| 2 | Значение названия города зафиксировано как Londonи не может быть изменено во время выполнения. | 
Это также можно сделать в контроллере экрана:
@Autowired
private UiComponents uiComponents;
@Autowired
private SingleFilterSupport singleFilterSupport;
@ViewComponent
private GenericFilter jfdtcGenericFilterNoParameter;
@Autowired
private JpqlFilterSupport jpqlFilterSupport;
@Subscribe
public void onInit(final InitEvent event) {
    DesignTimeConfiguration javaConfiguration = jfdtcGenericFilterNoParameter
            .addConfiguration("javaConfiguration", "No-parameter JpqlFilter configuration");
    DataLoader dataLoaderNoParam = jfdtcGenericFilterNoParameter.getDataLoader();
    JpqlFilter<Boolean> jpqlFilterNoParameter = uiComponents.create(JpqlFilter.class);
    jpqlFilterNoParameter.setConditionModificationDelegated(true);
    jpqlFilterNoParameter.setDataLoader(dataLoaderNoParam);
    jpqlFilterNoParameter.setCondition("c.name = 'London'", "join {E}.city c");
    jpqlFilterNoParameter.setParameterClass(Void.class);
    jpqlFilterNoParameter.setLabel("Show customers from London");
    jpqlFilterNoParameter.setParameterName(jpqlFilterSupport
            .generateParameterName(
                    String.valueOf(jpqlFilterNoParameter.getId()),
                    jpqlFilterNoParameter.getParameterClass().getSimpleName()));
    jpqlFilterNoParameter.setValueComponent(singleFilterSupport
            .generateValueComponent(dataLoaderNoParam.getContainer().getEntityMetaClass(),
                    jpqlFilterNoParameter.hasInExpression(),
                    jpqlFilterNoParameter.getParameterClass()));
    jpqlFilterNoParameter.setValue(true);
    javaConfiguration.setFilterComponentDefaultValue(
            jpqlFilterNoParameter.getParameterName(),
            jpqlFilterNoParameter.getValue());
    jfdtcGenericFilterNoParameter.setCurrentConfiguration(javaConfiguration);
    javaConfiguration.getRootLogicalFilterComponent()
            .add(jpqlFilterNoParameter);
}groupFilter
Компонент groupFilter объединяет несколько условий в группу. Условия в группе применяются на основе логического оператора (AND или OR). И декларативная, и программная конфигурации, представленные в этом разделе, создают следующий фильтр в экране:
 
Декларативная конфигурация
Конфигурация genericFilter может быть задана декларативно, внутри XML-дескриптора экрана. Смотрите следующий пример конфигурации с groupFilter, объединяющей два компонента propertyFilter:
<genericFilter id="genericFilterGroup"
        dataLoader="customerDl">
    <properties include=".*"/>
    <configurations>
        <configuration id="groupFilter"
                       name="groupFilter"
                       default="true">
            <groupFilter operation="OR"> (1)
                <propertyFilter property="rewardPoints"
                                operation="GREATER_OR_EQUAL"
                                operationEditable="true"/>
                <propertyFilter property="hobby"
                                operation="EQUAL"
                                operationEditable="true"/>
            </groupFilter>
        </configuration>
    </configurations>
</genericFilter>Программная конфигурация
Другой способ определения приведенной выше конфигурации - программно, в контроллере экрана:
@Autowired
private UiComponents uiComponents;
@Autowired
private SingleFilterSupport singleFilterSupport;
@ViewComponent
private GenericFilter gfdtcGenericFilter;
@Subscribe
public void onInit(final InitEvent event) {
    DesignTimeConfiguration javaDefaultConfigurationGF =
            gfdtcGenericFilter.addConfiguration("javaDefaultConfiguration",
                    "GroupFilter configuration"); (1)
    DataLoader dataLoaderGF = gfdtcGenericFilter.getDataLoader();
    GroupFilter groupFilter =
            uiComponents.create(GroupFilter.class); (2)
    groupFilter.setConditionModificationDelegated(true);
    groupFilter.setDataLoader(dataLoaderGF);
    groupFilter.setOperation(LogicalFilterComponent.Operation.OR); (3)
    PropertyFilter<Integer> rewardsPropertyFilter =
            uiComponents.create(PropertyFilter.class);
    rewardsPropertyFilter.setConditionModificationDelegated(true);
    rewardsPropertyFilter.setDataLoader(dataLoaderGF);
    rewardsPropertyFilter.setProperty("rewardPoints");
    rewardsPropertyFilter.setOperation(PropertyFilter.Operation.GREATER_OR_EQUAL);
    rewardsPropertyFilter.setOperationEditable(true);
    rewardsPropertyFilter.setParameterName(PropertyConditionUtils
            .generateParameterName(rewardsPropertyFilter.getProperty()));
    rewardsPropertyFilter.setValueComponent(singleFilterSupport.generateValueComponent(
            dataLoaderGF.getContainer().getEntityMetaClass(),
            rewardsPropertyFilter.getProperty(),
            rewardsPropertyFilter.getOperation()));
    groupFilter.add(rewardsPropertyFilter); (4)
    PropertyFilter<String> hobbyPropertyFilter =
            uiComponents.create(PropertyFilter.class);
    hobbyPropertyFilter.setConditionModificationDelegated(true);
    hobbyPropertyFilter.setDataLoader(dataLoaderGF);
    hobbyPropertyFilter.setProperty("hobby");
    hobbyPropertyFilter.setOperation(PropertyFilter.Operation.EQUAL);
    hobbyPropertyFilter.setOperationEditable(true);
    hobbyPropertyFilter.setParameterName(PropertyConditionUtils
            .generateParameterName(hobbyPropertyFilter.getProperty()));
    hobbyPropertyFilter.setValueComponent(singleFilterSupport.generateValueComponent(
            dataLoaderGF.getContainer().getEntityMetaClass(),
            hobbyPropertyFilter.getProperty(),
            hobbyPropertyFilter.getOperation()));
    groupFilter.add(hobbyPropertyFilter); (5)
    javaDefaultConfigurationGF.getRootLogicalFilterComponent()
            .add(groupFilter); (6)
}| 1 | Добавляет конфигурацию времени разработки. Метод принимает два параметра: idконфигурации и название конфигурации. | 
| 2 | Создает компонент GroupFilterи устанавливает его свойства. | 
| 3 | Устанавливает логическую операцию OR, определяющую, как применяются условия группы. | 
| 4 | Добавляет PropertyFilter, который фильтрует клиентов по бонусным баллам, в качестве первого условия этой группы. | 
| 5 | Добавляет PropertyFilter, который фильтрует клиентов по их хобби, в качестве второго условия этой группы. | 
| 6 | Добавляет созданную группу условий в конфигурацию. | 
Регистрация компонента фильтра
Для создания и регистрации компонента UI-фильтра в фреймворке необходимы следующие объекты:
- 
Класс компонента, представляющий UI-компонент, который будет отображаться внутри компонента genericFilter.
- 
Класс модели для хранения неперсистентного состояния этого компонента. Этот класс будет использоваться для сохранения состояния компонента в базе данных и отражения этого состояния во время выполнения. Такой класс должен расширять класс FilterCondition. В качестве примера такого класса рассмотрите классPropertyFilterConditionво фреймворке.
- 
Класс конвертера для преобразования между компонентом и моделью. Такой класс должен реализовывать интерфейс FilterConverter.
- 
Экран деталей модели. Его идентификатор может быть опционально указан с помощью метода withDetailViewId. Если идентификатор не указан, то идентификатор будет равен имени модели, полученному изJmixEntity, сViewRegistry.DETAIL_VIEW_SUFFIX.
Рассмотрим пример регистрации PropertyFilter:
@Bean("flowui_PropertyFilterRegistration")
public FilterComponentRegistration registerPropertyFilter() {
    return FilterComponentRegistrationBuilder.create(PropertyFilter.class,
                    PropertyFilterCondition.class,
                    PropertyFilterConverter.class)
            .build();
}Все зарегистрированные компоненты фильтра становятся доступными для использования в качестве элементов в меню Create диалогового окна Add condition.
Вы можете заменить компонент фильтра, зарегистрированный во фреймворке Jmix, своей собственной реализацией. Чтобы определить приоритет реализации, используйте аннотацию @Order на бине FilterComponentRegistration.
Атрибуты
| Просматривайте и редактируйте атрибуты компонента, используя инспектор Jmix UI. | 
Атрибуты propertyFilter
Смотрите Атрибуты propertyFilter.
Атрибуты jpqlFilter
id - classNames - colspan - defaultValue - enabled - errorMessage - hasInExpression - helperText - invalid - label - labelVisible - parameterClass - readOnly - required - requiredIndicatorVisible - requiredMessage - tabIndex - themeNames - visible - width
Атрибуты groupFilter
id - classNames - colspan - enabled - operation - operationTextVisible - summaryText - visible
Обработчики
Обработчики propertyFilter
Смотрите Обработчики propertyFilter.
Обработчики jpqlFilter
validator
Добавляет экземпляр валидатора к компоненту.