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

Lookup#

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

Свойства#

bind#

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

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

bindingMode#

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

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

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

  • object. В режиме объекта контрол относится к данным как к объекту, выбрать в списке можно только 1 значение, возвращает объект, список значений загружается при фокусе не контроле.
  • primitive. В режиме примитивных типов контрол требует добавление источника данных в коллекцию кэшей данных формы и возвращает примитивный тип данных (valueMember). При использовании привязки к данным формы (используя свойство bind) в привязанном поле будет храниться примитивное значение.
  • multiple. В режиме множественного выбора у контрола отключается работа с данными формы (bind к свойству модели) и сохранение выбранных пользователем значений необходимо контролировать отдельно. В данном режиме value - массив, содержащий выбранные записи.

viewMode#

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

Режим отображения контрола. Значение extended доступно только для bindingMode = 'multiple'.

Пример отображения:

Примечание

Режим extended не рекомендуется использовать для лукапа в гриде.

caption#

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

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

valueMemberPlaceholder#

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

Вспомогательный текст в поле valueMember контрола

placeholder#

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

Вспомогательный текст в поле displayMember контрола

captionWidth#

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

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

codeBoxWidth#

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

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

captionTextAlign#

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

Выравнивание текста заголовка контрола

доступно с версии 3.26.0

dataSource#

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

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

denyRoles#

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

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

displayMember#

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

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

displayMemberColumnText#

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

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

displayMemberColumnWidth#

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

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

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

editorWidth#

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

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

enabled#

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

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

formDefinerEnabled#

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

Доступность создания нового документа

newDocButtonVisibility#

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

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

filterCondition#

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

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

hint#

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

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

id#

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

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

linkedDocument#

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

Имя формы из units.

Если задано, то отображается кнопка для перехода в документ. Идентификатор документа определяется по выбранному значению в лукапе.

Пример
<Lookup ... formDefiner="getUserFormPromise" linkedDocument = "userForm" />
getUserFormPromise () {
    return new Promise((resolve, reject) => {
        this.services.dialog.confirm('какую форму использовать?', 'NewUserForm', 'UserForm')
            .done(() => resolve({
                FormClass: NewUserForm,
                customData: { text: 'Этот текст передан с помощью customData' },
                initData: { Email: 'из Основной Формы' },
                caption: 'test'
            }))
            .fail(() => resolve({ FormClass: UserForm, customData: { counter: ++this._counter }, caption: 'test' }))
    })
}

modelProperties#

тип значение по умолчанию допустимые значения
string [string/#declared]

Поля для загрузки данных модели в Lookup. Для перечисления нужно использовать запятую.

Если ограничение загрузки свойств не требуется, можно не указывать этот признак, в этом случае будут загружаться все свойства модели.

Для загрузки полей, уже указанных на форме, используется значение #declared. Оно необходимо, чтоб не требовалось дублировать описание в нескольких местах. В этом случае загружаются поля, указанные в displayMember и все поля в дочерних столбцах лукапа. Для корректной загрузки поле, указанное в valueMember, загружается всегда.

Примечание

Работает только для модели!

Пример
<Lookup id="lu1" caption="Model" rowsCount="5" modelProperties='#declared, Description'
    valueMember="VCode" displayMember="Name" dataSource="../basic/city.model.json">

popupWindowType#

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

Тип окна выпадающего списка.

  • simple. Простой список в виде гриде.
  • tree. Список с древовидной иерархией. Далее необходимо указать какие свойства объектов коллекции использовать в качестве ключевого поля (keyProperty) и поля, хранящего ключ родительской записи (parentKeyProperty). Для данного режима реализован также специальный метод labelRenderer, который позволяет обрабатывать и формировать отображаемые в контроле значения полей, используемых в качестве информационных (displayMember). В древовидном режиме отображения данных контрол поддерживает также работу в режиме привязки на примитивных значениях (см. bindingMode режим primitive).

keyProperty#

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

Имя свойства, являющегося ключом построения иерахии (тип свойства не должен быть объектом). Используется при popupWindowType='tree'.

parentKeyProperty#

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

Имя свойства, содержащего значение иерархического ключа родительского элемента (тип свойства не должен быть объектом). Используется при popupWindowType='tree'.

readOnly#

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

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

readRoles#

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

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

rowsCount#

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

Количество строк, отображаемое в выпадающем списке

showDisplayMember#

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

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

showValueMember#

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

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

sortBy#

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

Поле сортировки в выпадающем списке по умолчанию

sortOrder#

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

Порядок сортировки

tags#

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

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

value#

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

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

valueKey#

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

Значение свойства выбранного объекта, которое указано в качестве свойства valueMember

valueMember#

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

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

valueMemberColumnText#

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

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

valueMemberColumnWidth#

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

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

visible#

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

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

width#

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

Отнаследовано от Control По умолчанию значение 100%

writeRoles#

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

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

clearButtonVisible#

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

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

Методы#

focus#

Устанавливает фокус на контрол.

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

getDataSourceParameters#

Возвращает текущие применённые параметры загрузки источника данных

setDataSourceParameters#

Устанавливает объект в качестве словаря параметров загрузки источника данных.

После установки параметров фокусировка вызовет обновление источника данных с учетом заданных параметров

Пример
1
2
3
4
this.controls.Lookup1.setDataSourceParameters({
    parameter1: value1,
    parameter2: value2
});

resetLoadedData#

Сбрасывает кэш.

Сбрасывает кэш загруженных данных выпадающего списка и обозревателя аналитик (для постраничного лукапа)

setColumnsVisibility#

Устанавливает видимость для дополнительных колонок в выпадающем списке.

Принимает массив объектов:

параметр тип описание
dataField string dataField колонки
value bool видимость колонки
this.controls.Lookup1.setColumnsVisibility([{ dataField: 'c1', value: false }])

Не работает для колонок valueMember и displayMember (для них есть свойство showValueMember и showDisplayMember).

setColumnsWidth#

Устанавливает ширину для дополнительных колонок в выпадающем списке.

Принимает массив объектов:

параметр тип описание
dataField string dataField колонки
value bool размер колонки
this.controls.Lookup1.setColumnsWidth([{ dataField: 'c1', value: 100 }])

setColumnsIndexes#

Устанавливает индекс для дополнительных колонок в выпадающем списке.

Принимает массив объектов:

параметр тип описание
dataField string dataField колонки
index number индекс колонки
this.controls.Lookup1.setColumnsIndexes([{ dataField: 'c1', index: 0 }])

getVisibleColumns#

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

getHiddenColumns#

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

События#

valueChanged (onchage)#

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

Callback#

filter#

Используется для фильтрации коллекции объектов выпадающего списка.

Эта функция последовательно вызывается для всех элементов коллекции. Если функция возвращает true, элемент появится в итоговой коллекции.

filter(s, e)
Принимает параметры
параметр тип описание
s Lookup ссылка на контрол
e object
e.args object аргументы события
e.args.item object ссылка на текущий обрабатываемый объект
e.args.data object ссылка на текущий обрабатываемый объект (В случае древовидного лукапа)
e.args.getParent object метод для получения родительского элемента (В случае древовидного лукапа)
e.args.getChildren object метод для получения дочернего элемента (В случае древовидного лукапа)
//функция класса формы
filter(s, e) {
//если функция вернёт true, объект попадёт в коллекцию выпадающего списка
var currentContractor = this.data.Contractor(),
    contractContractor = e.item.Contractor;

if (currentContractor && contractContractor) {
    //в коллекцию попадут объекты, код контрагента которых совпадает
    //с кодом выбранного контрагента
    return currentContractor.VCode == contractContractor.VCode;
}
}

Клиентская фильтрация применяется для отсеивания элементов коллекции выпадающего списка и при установке значения лукапа по коду. Если попытаться выбрать в лукапе по коду объект, который не проходит условие клиентской фильтрации, значение лукапа очистится (станет равным null). Тем не менее, любая программная установка текущего значения производится в обход клиентской фильтрации.

labelRenderer#

Используется для вывода значения displayMember древовидного лукапа и колонки грида.

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

labelRenderer(e);
Принимает объект со свойствами
параметр тип описание
data Lookup объект, содержащий все свойства выбранного объекта
e object
e.args object аргументы события
e.args.getParent object метод для получения родительского элемента
e.args.getChildren object метод для получения дочернего элемента
//функция класса формы
labelRenderer(e) {
    var parent = e.getParent();
    if(parent){
        return parent.data.Имя + ' > ' + e.data.Имя;
    }
    else{
        return e.data.Имя;
    }
}

validator#

Используется для проверки выбранного значения.

Используется для ограничения выбора объекта в лукапе из выпадающего списка и обозревателя аналитик (для PageableLookup), а также при установке значения по коду. Выбранный объект установится в качестве значения лукапа в том случае, если функция вернет true. При программной установке значения присваиваемый объект не проверяется.

validator(value)
Пример
параметр тип описание
value Lookup ссылка на объект, выбранный пользователем
1
2
3
4
5
6
//функция класса формы
validator(value) {
    if(value.Type == "Материал") {
        return true;
    }
}

formDefiner#

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

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

Допустимые возвращаемые значения:

  • Класс формы,
  • Объект, содержащий следующие свойства:
    • FormClass - класс формы,
    • customData* - объект, который будет передан в новый документ как customData,
    • initData* - объект, свойства которого будут установлены как начальные данные формы (должны совпадать со свойствами модели).
    • width* - ширина всплывающего окно (задается в пикселях px, либо в процентах %).
    • height* - высота всплывающего окно (задается в пикселях px, либо в процентах %).
    • caption* - имя заголовка (по умолчанию Новый документ).
  • jquery Deffered или Promise, которые в случае удачного выполнения должны передавать класс формы или объект из предыдущего пункта. Случаи выполнения с ошибкой будут игнорироваться.

'* не обязательные свойства.'

Информация

Класс формы будет использоваться для создания нового документа из лукапа. Свойство нельзя использовать вместе с обозревателем аналитик.

Примеры
FormByAnalyticType () {
    const currType = this.analyticType
    if (currType === 'тип1') {
        return FormClass1
    } else if (currType === 'тип2') {
        return {
        FormClass: FormClass2,
        customData: { text: 'текст' }
        }
    } else if (currType === 'тип3') {
        return {
        FormClass: FormClass3,
        customData: { text: 'текст' },
        initData: { Name: 'Имя' }
        }
    }
}
getFormPromise () {
    return new Promise((resolve, reject) => {
        this.defferedFunc() // функция возвращающая Deferred
        .done(() => resolve({
            FormClass: FormClass3,
            customData: { text: 'текст' },
            initData: { Name: 'Имя' }
        }))
        .fail(() => resolve(FormClass1))
    })
}
getFormDeffered () {
    const result = $.Deferred()
    this.defferedFunc() // функция возвращающая Deferred
        .done(() => result.resolve({
            FormClass: FormClass3,
            customData: { text: 'текст' },
            initData: { Name: 'Имя' }
        }))
        .fail(() => result.resolve(FormClass1))
    return result
}

linkedDocumentDefiner#

Позволяет осуществить переход в документ. Идентификатор документа определяется по выбранному значению в лукапе.

Если это свойство задано, то в лукапе появится новая кнопка. Функция должна вернуть имя формы из units(в эту форму будет осуществляться переход)

Пример
1
2
3
``` xml 
<Lookup ... linkedDocumentDefiner = "linkedDocumentDefiner" />
```
1
2
3
4
5
``` javascript
linkedDocumentDefiner () {
    return 'testForm'
}
```
1
2
3
4
5
6
7
8
9
``` javascript
linkedDocumentDefiner () {
    if (this.controls.Lookup.valueKey == 1) {
        return 'testForm1'
    } else {
        return 'testForm2'
    }
}
```

gridCellPainter#

Позволяет раскрасить ячейку таблицы в выпадающем списке.

gridCellPainter(s, e)
параметр тип описание
s object ссылка на экземпляр лукапа
e object объект, содержащий информацию о текущей ячейке
e.row object номер строки
e.column string имя колонки
e.value object значение в ячейке
e.data object значение в строке

Функция должна вернуть имя цвета из палитры, указанной в объекте Colors, либо объект со свойствами:

  • backgroundColor - цвет фона (нужно использовать имя цвета из Colors)
  • fontColor - цвет текста (нужно использовать имя цвета из Colors)
  • fontStyle - задает начертание шрифта (доступное значение: 'italic' - курсив)
  • fontWeight - задает насыщенность шрифта (доступное значение: 'bold' - жирный)
Пример 1

Строки с чётными номерами жёлтые, с нечётными - зелёные

<Lookup id='Lookup1' ... gridCellPainter='Lookup1_cellPainter' />
1
2
3
4
5
import { Colors } from 'ecosoft-lexema8'
//...
Lookup1_cellPainter (s, { column, data, row, value } = {}) {
    return row % 2 ? Colors.green : Colors.yellow;
}
Пример 2
<Lookup id='Lookup1' ... gridCellPainter='Lookup1_cellPainter' />
import { Colors } from 'ecosoft-lexema8'
//...
Lookup1_cellPainter (s, { column, data, row, value } = {}) {
    return {
        backgroundColor: Colors.green,
        fontStyle: 'italic',
        fontWeight: 'bold',
        fontColor: Colors.red
    }
}

Виды#

  • обычный лукап:
    • загрузка источника данных при фокусе
    • биндинг на объект
  • примитивный лукап
    • нужно загружать источник данных при открытии формы (реализуется с помощью кэшей данных)
    • биндинг на примитивный тип
  • постраничный лукап
    • загрузка части источника данных при фокусе
    • биндинг на объект
  • древовидный лукап
    • загрузка источника данных при фокусе
    • биндинг на объект
  • примитивный древовидный лукап
    • нужно загружать источник данных при открытии формы
    • биндинг на примитивный тип
  • лукап с множественным выбором
    • загрузка источника данных при фокусе
    • без биндинга

Поля кода и наименования#

Контрол Lookup обладает двумя текстовыми полями (для кода и наименования выбранного объекта) и кнопкой, нажатие на которую открывает выпадающий список, содержащий объекты, доступные для выбора.

  • Имя свойства, являющегося кодом объекта, устанавливается с помощью свойства valueMember контрола.
  • Имя свойства, являющегося наименованием объекта, устанавливается с помощью свойства displayMember контрола.
  • Видимость поля кода настраиваться с помощью свойства контрола showValueMember.
  • Ширина поля кода настраивается с помощью свойства codeBoxWidth.
  • Ширину поля наименования настроить с помощью свойство нельзя. Она зависит от ширины контрола и ширины поля кода.
  • Удаление текста в поле наименования приводит к очищению значения контрола.
  • Удаление текста в поле код аналогично приводит к очищению значения контрола.

Выпадающий список#

Выпадающий список содержит таблицу с настраиваемым набором колонок.

  • Колонки с кодом и наменованием добвляются автоматически
  • Открывается при нажатии на кнопку Lookup'а (т.н. выпадающий список), клавиши вниз или при вводе текста в поле наименования
  • При щелчке мышью по строке таблицы или нажатии клавиши "Enter" происходит закрытие окна, а выбранный объект отображается в Lookup'е
  • При нажатии клавиш вверх и вниз выбирается значение в выпадающем списке
  • При нажатии клавиши 'ESC' выпадающий список закрывается
  • При вводе текста в поле наименования строки выпадающего списка фильтруются по всем видимым колонкам
  • При получении фокуса окном выпадающего списка не должно вызываться событие потери фокуса лукапом и его полями ввода (это необходимо для корректного поведения эдитора - в гриде и реализации возможности взаимодействия с дополнительными элементами управления окна выпадающего списка)

Добавление дополнительных колонок#

Для добавления колонки в выпадающий список необходимо в разметке(xml) формы добавить в Lookup дочерний элемент Column.

Примечание

Привязки колонок (свойство datafield) должны быть уникальными и не должны совпадать с valueMember и displayMember.

Решение

Контрол по умолчанию поддерживает изменение размера выпадающего списка путём перетаскивания его границ указателем мыши.

Пример
1
2
3
4
5
<Lookup ... >
    <Column datafield="Email" width="200" text="EMail">
        <TextBox/>
    </Column>
</Lookup>

Загрузка данных#

Загрузка источника данных лукапа осуществляется с учётом параметров, которые могут быть заданы с помощью метода setDataSourceParameters.

Отложенная#

Источник данных Lookup'а загружается при получении фокуса контролом.

Простая#

В случае, если Lookup работает в режиме биндинга primitive, коллекцию объектов выпадающего списка необходимо загружать перед созданием формы. Как это сделать читайте в статье

Переопределение источника данных#

Имеется возможность переопределять источника данных dataSource в lookup на проекте динамически

Пример с dataSource, заданным через model
    <Lookup id="lu1" ... dataSource="../basic/city.model.json"/>
1
2
3
4
    import client from '../basic/client.model.json'
    test () {
        this.controls.lu1.dataSource = client
    }
Пример с dataSource, заданным через query
    <Lookup id="lu2" ... dataSource="./lookupDataSource.query.json"/>
1
2
3
4
    import lookupDataSource from './lookupDataSource2.query.json'
    test () {
        this.controls.lu1.dataSource = lookupDataSource
    }

Параметры источника данных#

  • Получить текущие параметры источника данных можно с помощью метода getDataSourceParameters().
  • Задать параметры источнику данных можно с помощью метода setDataSourceParameters( ).

Получение и установка выбранного объекта#

Доступ к текущему значению Lookup'а осуществлятся посредством свойств value и valueKey.

Свойство value#

Возвращает / устанавливает объект, выбранный в Lookup'е. При присваивании свойству Lookup объекта необходимо, чтобы в данном объекте присутствовали свойства, названия которых указаны в значениях свойств valueMember и displayMember контрола.

Свойство valueKey#

Возвращает значение свойства выбранного объекта, которое указано в качестве свойства valueMember. При установке значения свойству valueKey в коллекции объектов выпадающего списка ищется объект, значение свойства valueMember которого совпадает с присваиваемым значением. Если объект найден, он устанавливается в качестве значения свойства value объекта и отображается как выбранный объект в Lookup'е.

Пример
L8.View.Lookup1.value = { VCode: 123, name: "qwe" };
console.log(L8.View.Lookup2.valueKey); //123

Лукап с множественным выбором#

Для включения множественного выбора необходимо установить значение bindingMode = multiple.

Предупреждение

Не работает в древовидном лукапе.

Биндинг#

Не реализовано. В связи с этим выбранные значения сохраняться не будут.

Значение лукапа#

Значение представляет собой массив выбранных объектов.

Отображение выбранных значений#

Коды и наименования отображаются через запятую.

Выбор значения с помощью клавиатуры#

С помощью стрелок вверх и вниз переходим по строкам грида. Клавишой enter выбираем или отменяем выбор значения. Esc закрывает выпадающий список

Выбор значения с помощью мыши#

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

Установка значения по введенному коду в поле valueMember#

В поле valueMember вводится значение. При нажатии enter происходит поиск объекта, с указанным кодом. Найденный код устанавливается в качестве значения лукапа. Если в источнике данных объекта с таким кодом нет, то устанавливается значение null. Вводить через запятую сразу несколько кодов нельзя.

Использование в гриде#

Если грид биндится на модель, то в свойстве datafield лукап колонки необходимо указывать свойство модели у которого не задано DbName, но задано ViewName (При создании модели с таким свойством оно автоматически не создается при обновлении БД. Необходимо добавить вручную).

Создание нового документа#

Для того, чтобы у пользователя появилась возможность создания нового документа из лукапа для этого необходимо задать свойство-коллбэк formDefiner. Если свойство задано, то у лукапа появляется дополнительная кнопка, которая открывает всплывающее окно с заданной в коллбэке формой.

Окно содержит документ, кнопки "Сохранить" и "Отмена". При нажатии на кнопку "Сохранить" у документа вызывается метод save. Если при сохранении документа ошибок не возникло, то окно закроется и у лукапа сбросятся загруженные данные (в выпадающем списке), а в качестве выбранного значения (у лукапа) установится новый сохраненный документ.

Примечание

Если у пользователя не будет прав на модель (прав на create и read) и на форму, то при нажатии на кнопку создания нового документа пользователю будет отказано в выполнении данного действия.

Предупреждение

  • Не отображается toolbar.
  • Пользователь не сможет воспользоваться кнопками, которые были добавлены в toolbar.
  • Нельзя обращаться к контролу toolbar, т.к. объектная модель этого контрола не создается. При обращении возникнет ошибка.
  • Если документ имеет расчетную дату, то она не будет передаваться в документ. Сохранение документа без расчетной даты не отображается в реестре. Для решения этой проблемы прикладной программист может в конструкторе формы в качестве расчетной даты задавать текущую дату.
  • Если в документе используется другой метод сохранения (с другим именем), то в этом случае код, который написан внутри этого метода не будет выполнен, т.к. сохранение производится вызовом метода save.

Обновление источника данных#

Иногда возникает ситуация, когда необходимо обновить источник данных лукапа при создании нового документа, чтобы этот документ можно было выбрать в выпадающем списке лукапа. Если новый документ создается из лукапа, то у него автоматически сбрасываются загруженные данные. Загрузка новых данных с сервера произойдет при фокусировке контрола. Если на форме несколько лукапов, которые имеют один источник данных, либо документ создается из реестра, то в этом случае необходимо вручную сбрасывать загруженные данные лукапа (если это требуется). Для этого нужно использовать событие saved сервиса Document.

Пример
    import UserModel from '../basic/user.model.json'

    export default class CustomDocument extends Document {
            constructor (args) {
                    super(args)
                    // подписываемся на событие saved
                    const handler = this.services.document.saved.add(({ binding, isNew }) => {
                    // проверяем на сохранение нового документа, у которого 
                    // в качестве источника данных используется модель UserModel
                    if (UserModel === binding && isNew) {
                            // дополнительные флаги для того, чтобы можно было
                            // сбросить загруженные данные лукапов в гриде
                            this._resetLoadedDataForColumn1 = true
                            this._resetLoadedDataForColumn2 = true
                            // сбрасываем загруженные данные для соответствующих лукапов
                            this.controls.lookup1.resetLoadedData()
                            this.controls.lookup2.resetLoadedData()
                    }
                    })
                    // при удалении формы необходимо удалить подписку на событие
                    this.destroyed.add(() => {
                    handler.detach()
                    })
            }
            // подписываемся на событие editorPrepared для колонок грида, в которых
            // используются лукапы, где необходимо сбросить загруженные данные. В данном примере
            // используются две колонки. Для первой колонки используем функцию column1EditorPrepared,
            // для второй колонки column2EditorPrepared.
            column1EditorPrepared (lookup) {
                    // проверяем значение флага
                    if (this._resetLoadedDataForColumn1) {
                    // сброс загруженных данных лукапа
                    lookup.resetLoadedData()
                    // сброс значения флага
                    this._resetLoadedDataForColumn1 = false
                    }
            }
            column2EditorPrepared (lookup) {
                    // проверяем значение флага
                    if (this._resetLoadedDataForColumn2) {
                    // сброс загруженных данных лукапа
                    lookup.resetLoadedData()
                    // сброс значения флага
                    this._resetLoadedDataForColumn2 = false
                    }
            }   
    }

Ввод с клавиатуры#

Функционал контрола Lookup поддерживает работу с клавиатурой. При фокусировке на контрол с помощью клавиш со стрелками можно переключаться между кодовым полем (valueMember) и поле наименования (displayMember), а также открывать выпадающий список и переходить в нём по доступным значениям. Выбрать нужное значение можно с помощью клавиши Enter.

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

Примеры#

Лукап на модели#

Пример
<Lookup caption="На модели" id="Lookup1" dataSource="./client.model.json" rowsCount="5" valueMember="VCode" displayMember="Name" />

Лукап на запросе#

Пример
<Lookup caption="На запросе" id="Lookup1" dataSource="../lookups/lookupDataSource.query.json" valueMember="VCode" displayMember="Name" />

Лукап на запросе с параметрами#

Зачастую запросы в системе реализуются с целью выполнения расчетов на основе их входных параметров. Подобные запросы можно использовать в качестве источника данных для Lookup. Для таких ситуаций у контрола Loookup реализованы методы для получения и установки параметров загрузки источника данных: getDataSourceParameters и setDataSourceParameters.

Пример
1
2
3
4
5
6
<Lookup caption="на запросе" id="lookupOnQueryWithParameters"
    dataSource="./Contractor.query.json"
    valueMemberColumnText="Код" valueMember="VCode"
    displayMember="Наименование" displayMemberColumnText="Наименование" 
    editorWidth="2" captionWidth="1" width="100%" 
    />
1
2
3
4
setQueryParameters () {
    const code = this.controls.queryParameter.value
    this.controls.lookupOnQueryWithParameters.setDataSourceParameters({ code })
}
{
    "select": {
        "text": "./Contractor.sql",
        "parameters": ["code"]
    },
    "parameters": {
        "code": "bigint"
    },
    "rights": {
        "read": ["super"]
    }
}

Лукап на DataAdapter#

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

Пример
<Lookup caption="На DataAdapter" id="Lookup1" dataSource="../systemUsers" valueMember="VCode" displayMember="Name" />

Лукап с множественным выбором#

Создадим список городов, с возможностью выбора нескольких значений. Тип привязки настраивается свойством bindingMode.

Пример
1
2
3
4
    <Lookup caption="Множественный выбор" id="lumultiple7" 
        dataSource="./client.model.json"
        valueMember="VCode" displayMember="Name" 
        bindingMode="multiple" />

Лукап с примитивной привязкой#

В примере создаём список типов документов, ключевое поле - TDoc. Тип привязки настраивается свойством bindingMode.

Пример
1
2
3
4
<Lookup caption="Примитив" id="Lookup1" 
    valueMember="TDoc" displayMember="Name"
    dataSource="./docTypes.model.json"
    bindingMode="primitive"/>
1
2
3
4
5
6
7
8
import docTypes_model from '/docTypes.model.json'

export default class MyForm extends Form {
    ...
    static get dataCaches() {
            return [docTypes_model];
    }
}

Лукап с выпадающим списком древовидной структуры#

Пример.
1
2
3
4
5
<Lookup caption="Стандарт" id="lutree8" 
    sortBy="VCode"
    valueMember="VCode" displayMember="Name"
    dataSource="../lookups/treeForLookup.query.json" 
    parentKeyProperty="PCode" keyProperty="VCode" popupWindowType="tree" />

С переопределённым полем вывода#

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

Пример
1
2
3
4
5
6
7
<Lookup caption="Стандарт" id="lutree8" 
    sortBy="VCode"
    valueMember="VCode" displayMember="Name"
    dataSource="../lookups/treeForLookup.query.json" 
    parentKeyProperty="PCode" keyProperty="VCode" popupWindowType="tree" 
    labelRenderer="labelRenderer"
/>
1
2
3
4
5
6
7
8
labelRenderer (e) {
    let parentNode = e.getParent()
    if (parentNode) {
        return `${parentNode.data.Name} > ${e.data.Name}`
    } else {
        return e.data.Name
    }
}

С примитивным источником#

В древовидном режиме отображения данных контрол поддерживает также работу в режиме привязки на примитивных значениях (в примере: контрол с id lutree8). Для такого режима также, как и при обычном режиме отображения данных, требуется использовать кэши данных. В данном случае используется адаптер:

Пример
1
2
3
4
5
6
7
8
<Lookup caption="Стандарт" id="lutree8" 
    sortBy="VCode"
    valueMember="VCode" displayMember="Name"
    dataSource="./treeAdapter.js" 
    parentKeyProperty="PCode" keyProperty="VCode" popupWindowType="tree" 
    labelRenderer="labelRenderer" 
    bindingMode="primitive"
/>
import { DataAdapter } from 'ecosoft-lexema8'
import $ from 'jquery'

export default class TreeAdapter extends DataAdapter {
    load () {
        return $.Deferred().resolve([
            { VCode: 'Goal', Name: 'Ворота', PCode: null },
            { VCode: 'Pole', Name: 'Столб', PCode: 'Goal' },
            { VCode: 'Field', Name: 'Поле', PCode: null }
        ])
    }
}

В случае если к полю построенному на примитивном лукапе необходимо добавить foreign key, добавьте к полю в модели linkedModel

Пример
1
2
3
4
5
    "NumberInput1": {
            "dbName": "NumberInput1",
            "type": "bigint",
            "linkedModel": "../folder/model2.model.json"
    }

Предупреждение

type поля обязательно должен совпадать с типом в подключаемом файле модели

Фильтрация данных#

Lookup поддерживает возможность фильтрации коллекции отображаемых записей на стороне клиента. Для её использования необходимо определить метод формы, в котором будут описаны условия фильтрации, и использовать его в свойстве filter контрола

Макет формы
<Group caption="Фильтры">
    <Lookup id="lu373" caption="обычный" rowsCount="5" valueMember="VCode" displayMember="Name"
        dataSource="./client.model.json"
        filter="customFilter" />
    <Lookup id="lu7954" caption="Примитив" dataSource="./city.model.json"
        valueMemberColumnText="код" displayMemberColumnText="имя"
        valueMember="VCode" displayMember="Name" captionWidth="1"
        bindingMode="primitive" filter="customFilter" />
    <Lookup id="lutreeFilter6" caption="tree" rowsCount="5" valueMemberColumnText="код"
        displayMemberColumnText="имя" valueMember="VCode" displayMember="Name"
        dataSource="../lookups/treeForLookup.query.json" codeBoxWidth="100"
        parentKeyProperty="PCode" keyProperty="VCode" popupWindowType="tree"
        filter="treeCustomFilter" />
    <Lookup id="lumultiple2" caption="Множественный выбор" rowsCount="5" valueMemberColumnText="код"
        displayMemberColumnText="имя"
        valueMember="VCode" displayMember="Name" dataSource="./client.model.json"
        bindingMode="multiple" filter="customFilter" />
    <CheckBox id="even" caption="Чётные" value="true" />
    <Lookup id="lu3732" caption="Чёт / нечёт" rowsCount="5" valueMember="VCode"
        displayMember="Name" dataSource="./client.model.json"
        filter="isEvenFilter" />
    </Group>

Методы фильтрации могут иметь разнообразную логику. Но стоит помнить о производительности и том, что метод будет вызываться для каждой записи в коллекции данных контрола. Примеры методов фильтрации:

Реализация фильтрации
treeCustomFilter (s, e) {
    e.item.getChildren()
    if (e.item.data.VCode % 2 === 0) {
        return true
    }
}

isEvenFilter (s, e) {
    return Number(!this.controls.even.value) === (e.item.VCode % 2)
}

customFilter (s, e) {
    if (e.item.VCode % 2 === 0) {
        return true
    }
}

Сортировка данных#

Для установки сортировки в контроле по умолчанию можно использовать свойства sortBy и sortOrder. В первом указывается нужное поле источника данных, во втором - порядок сортировки (asc или desc).

Пример
1
2
3
4
5
<Lookup caption="Lookup sortByName" id="lu" 
    rowsCount="5" valueMember="VCode" displayMember="Name" 
    dataSource="./client.model.json"
    sortBy="Name" sortOrder="desc"
    />

Проверка выбранного значения#

Для проверки выбранного пользователем значения можно использовать свойство validator. С его помощью можно определить метод, в котором будет осуществляться проверка выбранного значения на соответствие нужным условиям.

Пример
<Group caption="Валидация">
    <Lookup caption="обычный" id="luValid" 
        rowsCount="5" valueMember="VCode" displayMember="Name" 
        dataSource="./client.model.json" 
        validator="lookupValidator"
        />
    <Lookup caption="Древо" id="lutreeValid" 
        valueMember="VCode" displayMember="Name" 
        dataSource="../lookups/treeForLookup.query.json" 
        codeBoxWidth="100" parentKeyProperty="PCode" keyProperty="VCode" popupWindowType="tree" 
        validator="lookupValidator"
        />
</Group>

Метод, используемый для проверки значения:

1
2
3
lookupValidator (value) {
    return value.Name === 'officer'
}

Настройка внешнего вида (несколько колонок)#

Добавим три колонки в выпадающий список.

Пример
<PageableLookup caption="Модель (постраничный)" 
    valueMember="VCode" displayMember="Name" 
    dataSource="./client.model.json" 
    rowsCount="5" topCount="1" >
    <Column datafield="Email" text="covfefe" width="200" hint="Колонка 1">
        <TextBox maxLength="5"/>
    </Column>
    <Column datafield="Email2" hint="Колонка 2"/>
    <Column datafield="Email3" hint="Колонка 3"/>
</PageableLookup>

Для этого в шаблоне формы необходимо добавить вложенные в Lookup элементы Column (аналогично работе с контролом Grid). Для сохранения возможности работы с различными типами данных в элементах колонок необходимо использовать соответствующие контролы.

Если в шаблоне не указывать контрол колонки, то по умолчанию платформой используется TextBox. Также колонкам можно задавать ширину с помощью их свойства width.