Перейти к содержанию

PageableLookup#

PageableLookup - элемент управления, позволяющий выбирать значения из постраничных справочников.

Свойства#

id#

Идентификатор контрола.

Отнаследовано от Control

hint#

Всплывающая подсказка, которая появляется при наведении на контрол.

отнаследовано от Control

tags#

Позволяет объединять контролы в группы, возвращает массив имен.

Отнаследовано от Control

denyRoles#

Список ролей без прав на данный элемент.

Отнаследовано от Control

readRoles#

Список ролей на чтение данных.

Отнаследовано от Control

writeRoles#

Список ролей на изменение данных.

Отнаследовано от Control

bind#

тип значение по умолчанию допустимые значения
string -

Свойство, к которому биндится контрол

value#

тип значение по умолчанию допустимые значения
string -

Задает значение контрола

captionWidth#

Ширина заголовка в колонках (для Bootstrap-верстки).

Отнаследовано от Control

editorWidth#

Ширина контрола в колонках (для Bootstrap-верстки).

отнаследовано от Control

captionTextAlign#

тип значение по умолчанию допустимые значения
string left left, right

Выравнивание текста заголовка контрола (доступно с версии 3.26.0)

visible#

Видимость контрола.

Отнаследовано от Control

width#

Ширина контрола.

Отнаследовано от Control

caption#

тип значение по умолчанию допустимые значения
string -

Заголовок контрола

bindingMode#

тип значение по умолчанию допустимые значения
string object object, multiple

Режим биндинга

popupWindowType#

тип значение по умолчанию допустимые значения
string simple

Тип окна выпадающего списка. Доступно только одно значение: simple

viewMode#

тип значение по умолчанию допустимые значения
string standard standard, extended

Режим отображения контрола.

Описание смотри у контрола Lookup

valueMember#

тип значение по умолчанию допустимые значения
string VCode

Имя свойства, являющегося кодом объекта

displayMember#

тип значение по умолчанию допустимые значения
string Name

Имя свойства, являющегося наименованием объекта

enabled#

тип значение по умолчанию допустимые значения
bool true true/false

Доступность контрола для редактирования

newDocButtonVisibility#

тип значение по умолчанию допустимые значения
bool true true/false

Видимость кнопки создания нового документа (для управления видимостью необходимо задать свойство formDefiner)

codeBoxWidth#

тип значение по умолчанию допустимые значения
number 50

Ширина поля с кодом

showValueMember#

тип значение по умолчанию допустимые значения
bool true true/false

Отображение поля с кодом

showDisplayMember#

тип значение по умолчанию допустимые значения
bool true true/false

Отображение поля с наименованием

valueMemberColumnText#

тип значение по умолчанию допустимые значения
string Код

Заголовок колонки с кодом

valueMemberColumnWidth#

тип значение по умолчанию допустимые значения
int -

Ширина колонки с кодом.

Если не задано, то вычисляется автоматически

displayMemberColumnWidth#

тип значение по умолчанию допустимые значения
int -

Ширина колонки с наименованием.

Если не задано, то вычисляется автоматически

valueMemberColumnText#

тип значение по умолчанию допустимые значения
string Наименование

Заголовок колонки с наименованием

filterCondition#

тип значение по умолчанию допустимые значения
string contains contains, starts_with, equal

Тип фильтрации

readOnly#

тип значение по умолчанию допустимые значения
bool false true/false

Режим "только для чтения"

rowsCount#

тип значение по умолчанию допустимые значения
int 9

Количество отображаемых строк

topCount#

тип значение по умолчанию допустимые значения
int 100

Количество выводимых значений в списке.

dataSource#

тип значение по умолчанию допустимые значения
string -

Источник данных грида

topCount#

тип значение по умолчанию допустимые значения
int 100

Количество записей при постраничном выводе данных

boundaryKeyName#

тип значение по умолчанию допустимые значения
string VCode

Имя поля данных, возвращаемых запросом, по которому данные делятся на страницы.

Если свойство не указано, то берется valueMember

clearButtonVisible#

тип значение по умолчанию допустимые значения
bool true true/false

Видимость кнопки очистки значения.

События#

valueChanged#

Возникает при смене значения

параметр тип описание
s PageableLookup экземпляр класса контрола
1
2
3
s = PageableLookup {
    ... // экземпляр класса PageableLookup
}
Пример
<PageableLookup ... valueChanged='test' />
1
2
3
test(s) {
    console.log(s, s)
}

Коллбэки#

validator#

gridCellPainter#

Частичная загрузка и серверная фильтрация#

На модели:#

Постраничный лукап на модели поддерживает встроенный механизм серверной фильтрации.

На запросе:#

Для использования встроенных механизмов частичной загрузки и серверной фильтрации необходимо:

  • Установить у лукапа свойство topCount
  • Запрос, поддерживающий параметры для частичной загрузки, установки по коду и серверной фильтрации

Обязательные параметры, которые должны быть описаны в запросе:

  • TopCount - количество записей, загружаемый при частичной загрузке.
  • PrimaryKeyBoundary - значение первичного ключа, с которого начинается/продолжается считывание указанное количество записей(TopCount).
  • filter - значение, введеное в лукап для фильтрации записей.
  • UniqueId - значение, введенное в поле valueMember для установки значения в лукап по коду.

Сам запрос должен быть приведен к следующему виду:

Пример
IF (@UniqueId is not null)
    BEGIN
    SELECT [поля результирующего селекта для отображения в лукапе]
    FROM [имя таблицы]
    WHERE [valueMember] = @UniqueId
    END
ELSE
    BEGIN
    SELECT TOP (@TopCount) [поля результирующего селекта для отображения в лукапе]
    FROM [имя таблицы]
    WHERE ([valueMember] >= isnull(@PrimaryKeyBoundary, [valueMember])
        AND ([valueMember] LIKE isnull(@filter, '%%') OR [Поле1] LIKE isnull(@filter, '%%') OR [Поле2] LIKE isnull(@filter, '%%')))
    ORDER BY [valueMember]
    END

Выражения

Пример
1
2
3
SELECT TOP (@TopCount)
[valueMember] >= isnull(@PrimaryKeyBoundary, [valueMember]
ORDER BY [valueMember]

обеспечивают частичную загрузку данных, где [valueMember] - это имя поля колонки таблицы, указанное в лукапе в качестве свойства valueMember.

Условие

Пример
1
2
3
[valueMember] LIKE isnull(@filter, '%%') OR 
[Поле1] LIKE isnull(@filter, '%%') OR 
[Поле2] LIKE isnull(@filter, '%%'))

обеспечивает серверную фильтрацию, где [valueMember] - это имя поля колонки таблицы, указанное в лукапе в качестве свойства valueMember, а [Поле1], [Поле2] - поля грида лукапа. В это условие для каждой колонки грида лукапа, по которой ведется поиск, дописывается выражение вида

Пример
[ПолеГридаЛукапа] LIKE isnull(@filter, '%%').

Пример запроса:

Пример
if (@UniqueId is not null)
    BEGIN
    SELECT [VCode], [Name]
    FROM [Position]
    WHERE [VCode] = @UniqueId
    END
ELSE
    BEGIN
    SELECT TOP (@TopCount) [VCode], [Name]  
    FROM [Position]  
    WHERE ([VCode] >= isnull(@PrimaryKeyBoundary, [VCode]) AND       
    ([VCode] LIKE isnull(@filter, '%%') OR [Name] LIKE isnull(@filter, '%%')))
    ORDER BY [VCode]
    END

Сортировка#

В постраничном лукапе на запросе можно реализовать постраничный вывод и фильтрацию с учетом сортировки.

Пример реализации.

Напишем запрос, который возвращает имена контрагентов отсортированными в зависимости от указанного фильтра в следующем порядке:

  • Cначала выводятся записи, наименования контрагента в которых начинается со значения, равного введенному значению фильтра,
  • Далее выводятся записи, в наименовании контрагента которых встречается значение, равное введенному значению фильтра.

Обязательные параметры, которые должны быть описаны в запросе:

  • TopCount - количество записей, загружаемый при частичной загрузке.
  • PrimaryKeyBoundary - значение ключа, с которого начинается/продолжается считывание указанное количество записей(TopCount). Название параметра не изменилось для обратной совместимости.
  • filter - значение, введеное в лукап для фильтрации записей.
  • UniqueId - значение, введенное в поле valueMember для установки значения в лукап по коду.

Запрос имеет следующий вид:

Пример
declare @filter1 varchar(1000)
select @filter1 = replace(@filter,'%','')

if (@UniqueId is not null)
    begin
    -- для установки значения по значению, введенному в поле valueMember
    select  VCode, 
            Name, 
            FullName, 
            INN, 
            KPP
    from VContractor
    where VCode = @UniqueId
    end
else
    begin
    -- для постраничного вывода с сортировкой
    select top (@TopCount) *
    from (
        select  ROW_NUMBER() OVER(order by (case when Name like @filter1+'%' then 0 else 1 end), Name, VCode) AS OrderKey, 
                VCode, 
                Name, 
                FullName, 
                INN, 
                KPP
        from VContractor 
        where ( Name like isnull(@filter, '%%')
        OR convert(varchar(255),VCode) like isnull(@filter,'%%')
        OR INN like isnull(@filter, '%%'))
    ) as t
    where t.OrderKey >= isnull(@PrimaryKeyBoundary, OrderKey)
    end

В этом запросе подселект выводит все данные с учетом сортировки по значению фильтра, при этом порядковый номер строк записывается в поле OrderKey. Внешний селект выводит данные постранично по полю OrderKey.

В дизайнере постраничный лукап настраивается как обычно, добавляется свойство data-lx-boundaryKeyName со значением поля, по которому ведется постраничный вывод, в данном примере OrderKey.

Поведение#

Серверная фильтрация#

  • Значение, введённое в поле наименования, будет использовано для фильтрации источника данных через 1 секунду после окончания ввода. Если в течение этой секунды ввод текста повторяется, то отложенная предыдущая фильтрация будет отменена
  • Введённое значение используется для фильтрации источника данных по всем видимым колонкам, представленным в лукапе

Постраничная загрузка#

  • При получении фокуса лукапом выполнятеся проверка необходимости загрузки данных. Если загрузка данных уже осуществлялась, коллекция объектов выпадающего списка не грузится. В ином случае происходит загрузка первой порции объектов
  • В нижней части окна выпадающего списка располагается кнопка с надписью "Загрузить ещё N" (где N - значение свойства topCount лукапа). При нажатии на эту кнопку производится загрузка следующей порции объектов
    • Если нажатие на кнопку "Загрузить ещё N" происходит при наличии применённого серверного фильтра, загрузка следующей порции объектов выполнится с учётом текущего фильтра
  • После окончания загрузки части коллекции среди значений ключевых свойств загруженных объектов (имя ключевого свойства указывается в свойстве valueMember лукапа) ищется максимальное значение, которое будет использовано при загрузке следующей порции объектов в качестве нижней границы обрабатываемого диапазона значений кодов загружаемых объектов
  • Если при загрузке очередной порции данных обнаруживается, что количество загруженных объектов меньше значения свойства topCount, кнопка "Загрузить ещё" скрывается

Сброс серверного фильтра и постраничных параметров#

Сброс серверного фильтра и постраничных параметров вызывается следующими действиями:

  • Выбор значения в лукапе
  • Переход фокуса на другой элемент управления

Загрузка объекта по коду#

  • При загрузке объекта по коду (вызванной введением кода искомого объекта в поле ввода кода) происходит загрузка источника данных с со следующими постраничными параметрами: количество ожидаемых объектов равно единице, нижняя граница обрабатываемого диапазона значений кодов объекта равна коду загружамеого объекта. Если возвращается объект с иным кодом, значит, объект с искомым кодом не существует

Использование обозревателя аналитик#

Для того, чтобы в лукапе появилась возможность выбирать объекты из обозревателя аналитик, необходимо:

  • Создать форму обозревателя аналитик (читай статью UniAnalyt)
  • Выполнить требования из статьи UniAnalyt в разделе "использование в лукапе".
  • Вложить в постраничный лукап контрол UniAnalytWindow
  • Установить значение свойства boundaryKeyName = OrderKey
  • Использовать в качестве источника данных (свойство dataSource) специальный запрос, который описан ниже в этом разделе
Пример
1
2
3
4
5
    <PageableLookup id="lu1" boundaryKeyName="OrderKey"
            valueMember="VCode" displayMember="Name"
            dataSource="../../queries/uniAnalyt/loadData.query.json">
            <UniAnalytWindow topNode="города" analyticsType="Город" readOnly="false"/>
    </PageableLookup>

Доступ к экземпляру UniAnalytWindow осуществляется следующим образом:

Пример
//this - ссылка на экземпляр формы
this.controls.pageableLookup.uniAnalytWindow

Запрос для загрузки данных#

Параметры, которые должны быть описаны в запросе:

  • TopCount - количество записей, загружаемый при частичной загрузке.
  • PrimaryKeyBoundary - значение ключа, с которого начинается/продолжается считывание указанное количество записей(TopCount). Название параметра не изменилось для обратной совместимости.
  • filter - значение, введеное в лукап для фильтрации записей.
  • UniqueId - значение, введенное в поле valueMember для установки значения в лукап по коду.
  • topNode - задает стартовую вершину дерева. Параметр берется из настроек контрола UniAnalytWindow
  • analyticsType - задает фильтр по типу аналитики. Параметр берется из настроек контрола UniAnalytWindow
Описание запроса:
{
    "rights": {    
        "read": ["super"]
    },
    "select": {
        "text": "./loadData.sql",
        "parameters": ["TopCount", "PrimaryKeyBoundary", "filter", "UniqueId", "topNode", "analyticsType"]
    },
    "parameters": {
        "TopCount": "bigint",
        "PrimaryKeyBoundary": "bigint",
        "filter": "string",
        "UniqueId": "bigint",
        "topNode": "string",
        "analyticsType": "string"
    }
}
Текст запроса:
    DECLARE @filter1 VARCHAR(1000), @topNodeCode bigint;

    DECLARE @table table(Original bigint);

    SET @filter1 = Replace(@filter, '%', '');

    SET @topNodeCode =
    (SELECT TOP 1 Analytics
    FROM UniAnalytSettings
    WHERE Name = @topNode);

    WITH tree (VCode, PCode, Original) AS
    (SELECT VCode,
            PCode,
            ISNULL(Original, VCode) AS Original
    FROM UnianAlyt
    WHERE (@topNode IS NOT NULL
            AND VCode = @topNodeCode)
        OR (@topNode IS NULL
            AND Isnull(PCode, 0) = 0)
    UNION ALL SELECT u.VCode,
                        u.PCode,
                        ISNULL(u.Original, u.VCode) AS Original
    FROM tree t
    INNER JOIN UniAnalyt u ON isnull(t.Original, t.VCode) = u.PCode
    )
    INSERT @table
    SELECT Original
    FROM tree
    GROUP BY original

    SELECT TOP (@TopCount) VCode = t.Original,
                        t.Name,
                        t.Type,
                        t.OrderKey
    FROM
    (SELECT Row_number() OVER(
                                ORDER BY (CASE
                                            WHEN u.Name LIKE @filter1+'%' THEN 0
                                            ELSE 1
                                        END) , u.Name, u.VCode) AS OrderKey,
            t.Original,
            u.Name,
            u.[Type]
    FROM @table t
    INNER JOIN UniAnalyt u ON t.Original = u.VCode
    WHERE ((@UniqueId IS NULL
            AND (u.Name LIKE Isnull(@filter, '%%')
                    OR u.VCode LIKE Isnull(@filter, '%%')))
            OR (@UniqueId IS NOT NULL
                AND u.VCode = @UniqueId))
        AND u.[Type] = Isnull(@analyticsType, u.[Type])) AS t
    WHERE t.OrderKey >= Isnull(@PrimaryKeyBoundary, OrderKey)

    SELECT * FROM demo."loadData"(:TopCount, :PrimaryKeyBoundary, :filter, :UniqueId, :topNode, :analyticsType)
SQL-объект:
    CREATE OR REPLACE FUNCTION demo."loadData"(topcount bigint, primarykeyboundary bigint, filter character varying, uniqueid bigint, topnode character varying, analyticstype character varying)
    RETURNS TABLE("VCode" bigint, "Name" text, "Type" text, "OrderKey" bigint)
    LANGUAGE plpgsql
    AS $function$

    DECLARE filter1 character varying;
    DECLARE topNodeCode bigint;
    BEGIN
        SELECT s."Analytics"
        INTO topNodeCode
        FROM "UniAnalytSettings" s
        WHERE s."Name" = topNode
        LIMIT 1;

        CREATE TEMP TABLE treetable ON COMMIT DROP AS
        WITH RECURSIVE tree ("VCode", "PCode", "Original") AS (
            SELECT u."VCode", u."PCode", COALESCE(u."Original", u."VCode") AS "Original"
            FROM "UniAnalyt" u
            WHERE (topNode IS NOT NULL AND u."VCode" = topNodeCode)
                OR (topNode IS NULL AND COALESCE(u."PCode", 0) = 0)
            UNION ALL
            SELECT u."VCode", u."PCode", COALESCE(u."Original", u."VCode") AS "Original"
            FROM tree t
                INNER JOIN "UniAnalyt" u ON COALESCE(t."Original", t."VCode") = u."PCode"
        )
        SELECT "Original"
        FROM tree
        GROUP BY "Original";

        RETURN QUERY
        SELECT
            t."Original" AS "VCode",
            t."Name",
            t."Type",
            t."OrderKey"
        FROM

        (SELECT ROW_NUMBER() OVER(
                                    ORDER BY (CASE
                                                WHEN u."Name" ~~* (filter1 || '%') THEN 0
                                                ELSE 1
                                            END) , u."Name", u."VCode") AS "OrderKey",
                tr."Original",
                u."Name",
                u."Type"
        FROM treetable tr
                INNER JOIN "UniAnalyt" u ON tr."Original" = u."VCode"
        WHERE ((uniqueId IS NULL
                AND (u."Name" ~~* COALESCE(filter, '%%')
                        OR CAST(u."VCode" AS text) ~~* COALESCE(filter, '%%')))
                OR (uniqueId IS NOT NULL
                    AND u."VCode" = uniqueId))
            AND u."Type" = COALESCE(analyticsType, u."Type")) AS t

        WHERE t."OrderKey" >= COALESCE(primaryKeyBoundary, t."OrderKey")
        LIMIT topCount;
    END;

    $function$

Примечание: имя таблицы обозревателя аналитик (в примере используется UniAnalyt) и настроечной таблицы (в примере используется UniAnalytSettings) может отличаться на вашем проекте. В этом случае в запросе нужно заменить имена таблиц на те, которое используются у вас.