Фильтрация элементов
Скрипты позволяют ограничивать список доступных вариантов значений для полей типа Справочник или Форма. Для этого необходимо подписаться на изменение необходимых полей формы через onChange и вызвать одну из функций установки фильтра: setFilter или setFilterAsync.
Фильтрация элементов справочника
При работе с полем типа Справочник функция фильтрации должна вернуть объект с полем values, содержащим список значений первой колонки справочника.
interface form {
onChange(
fieldNames: string[],
executeOnLoad: boolean = false
): ChangeHandler
}
interface ChangeHandler {
setFilter(
fieldName: string,
calcFilter: (state: FormState) => {
values: string[]
} | null
)
setFilterAsync(
fieldName: string,
calcFilterAsync: (state: FormState) => Promise<{
values: string[]
} | null>
)
}
Если справочник большой, передайте в getCatalog параметр filters, чтобы получить только подходящие элементы. Например, можно запросить города выбранного региона вместо всего списка городов.
Рассмотрим пример: когда оператор выбирает в форме регион, в поле Город должны быть доступны только города из этого региона, а не общий список городов.

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

Чтобы фильтровать список городов по выбранному региону, добавим в скрипты формы следующий блок кода:
// ↓ Название поля со справочником «Регионы»
form.onChange(["Регион"])
// ↓ Название поля со справочником «Города»
.setFilterAsync("Город", async state => {
const [region] = state.changes;
if (!region?.columns)
return null;
// Получаем значение колонки «Регион» из выбранного
// элемента справочника «Регионы»
const regionCol = region.columns["Регион"];
// Получаем только города выбранного региона
const catalogItems = await form.getCatalog('Города по регионам', [
{ columnName: 'Регион', value: regionCol, useWildcard: false }
]);
const filtered = catalogItems.map(item => item.columns['Город']);
/*
* В переменной filtered сохранится список городов выбранного региона.
* Например, для региона «Тульская область»:
* ["Алексин", "Богородицк", "Тула", ...]
*
* Это ключи для фильтрации справочника «Города» (поле «Город»),
* соответствующие первой (ключевой) колонке данного справочника.
*/
return { values: filtered }
});
Метод getCatalog возвращает только значения выбранного региона, а setFilterAsync оставляет в поле «Город» только те значения, которые соответствуют выбранному региону. Если совпадений нет, возвращается { values: [] } — пустой список допустимых значений. Значение null в этом примере используется, только когда регион не выбран.
Фильтрация в поле типа Форма
Чтобы ограничить список вариантов в поле типа Форма, функция фильтрации должна вернуть объект с полем filters. В этом поле содержится список условий фильтрации по значениям полей связанной формы.
interface form {
onChange(
fieldNames: string[],
executeOnLoad: boolean = false
): ChangeHandler
}
interface ChangeHandler {
setFilter(
fieldName: string,
calcFilter: (state: FormState) => {
filters?: FormLinkFilter[]
} | null
)
setFilterAsync(
fieldName: string,
calcFilterAsync: (state: FormState) => Promise<{
filters?: FormLinkFilter[]
} | null>
)
}
interface FormLinkFilter {
fieldId?: number;
fieldName?: string;
fieldCode?: string;
value: FieldValue;
}
Каждое условие фильтрации FormLinkFilter включает идентификатор поля связанной формы (fieldId или fieldName или fieldCode) и значение поля.
Рассмотрим пример: при изменении поля «manager» будем фильтровать список задач в поле «contragent», показывая только те задачи связанной формы, в которых в поле «Менеджер» указан тот же пользователь, что и в поле «manager» исходной формы.
form.onChange(["manager"], true)
.setFilter("contragent", state => {
const [manager] = state.changes;
if (!manager?.person_id) return null;
return {
filters: [{
fieldName: "Менеджер",
value: manager.person_id
}]
}
});
Если в связанной форме фильтрация выполняется по полю типа Справочник, значение передаётся в другом формате — массивом с объектом, в котором указан идентификатор элемента справочника: value: [{ Id: item_id }].
Например, в поле Название проекта нужно показывать только те проекты, в которых в поле Клиент (поле типа Справочник) выбран тот же клиент, что и в поле Клиент исходной формы.
form.onChange(["Клиент"], true)
.setFilterAsync("Название проекта", async state => {
const [clientField] = state.changes;
// Если клиент не выбран — показываем все проекты
if (!clientField || !clientField.item_id) {
return null;
}
const clientItemId = clientField.item_id;
// Возвращаем фильтр
return {
filters: [
{
fieldCode: "ClientFieldCode",
value: [{ Id: clientItemId }], //формат для справочника
}
]
};
});
Формат значений в условиях фильтра
В условиях фильтра значения задаются в собственном формате, который отличается от описанного в статье Формат значений полей. Формат зависит от типа поля связанной формы, по которому выполняется фильтрация. Например, для поля типа Выбор нужно передать не объект { choice_id: 2 }, а массив [2].
| Тип поля связанной формы | Формат value | Какие задачи останутся в списке |
|---|---|---|
| Текст | Строка: "Москва" | Значение поля начинается с указанной строки |
| Число, Деньги | Число: 1500 | Значение поля равно указанному числу |
| Галочка | true | В поле поставлена галочка |
| Выбор | Массив с идентификатором варианта: [2] | В поле выбран указанный вариант |
| Выбор с множественным выбором | Массив с идентификатором варианта: [2] | Среди выбранных в поле вариантов есть указанный |
| Сотрудник | Идентификатор сотрудника: manager.person_id | В поле указан этот сотрудник |
| Справочник | Массив с объектом: [{ Id: item_id }] | В поле выбран указанный элемент справочника |
Идентификатор варианта (choice_id) можно узнать одним из способов:
- В консоли браузера. Когда в поле типа Форма выбрана задача, в значении поля, которое получает скрипт, есть объект
fieldsсо значениями полей этой задачи. Для поля типа Выбор в нём указаныchoice_idsиchoice_names. Выведите значение в консоль с помощью методаconsole.log(подробнее — в статье Отладка), откройте форму и выберите в поле задачу, в которой отмечен нужный вариант. - Через API. Варианты поля перечислены в свойстве
optionsв описании формы, которое возвращает метод GET /forms/{form-id}. Подробнее — в статье Поля форм.
Пример скрипта, который выводит в консоль значения полей задачи, выбранной в поле «Проект»:
form.onChange(["Проект"])
.validate("Проект", state => {
const [project] = state.changes;
// Например: { "Статус проекта": { choice_ids: [2], choice_names: ["В работе"] }, ... }
console.log(project?.fields);
});
После того как вы узнали идентификатор, удалите этот блок из скрипта.
Если в форме несколько условий, в списке останутся только задачи, которые подходят под все условия сразу.
Фильтрация по галочке
Рассмотрим пример: в поле «Подрядчик» нужно показывать только задачи связанной формы, в которых стоит галочка «Договор подписан». Фильтр включается, только если в исходной форме отмечена галочка «Только с договором».
form.onChange(["Только с договором"], true)
.setFilter("Подрядчик", state => {
const [onlySigned] = state.changes;
// Галочка не отмечена — показываем все задачи
if (!onlySigned?.checked) return null;
return {
filters: [{
fieldName: "Договор подписан",
value: true
}]
};
});
Фильтрация по полю Выбор
Рассмотрим пример: если в исходной форме отмечена галочка «Только активные», в поле «Проект» нужно показывать только проекты в статусе «В работе». В связанной форме этому варианту поля «Статус проекта» соответствует идентификатор 2.
form.onChange(["Только активные"], true)
.setFilter("Проект", state => {
const [onlyActive] = state.changes;
if (!onlyActive?.checked) return null;
return {
filters: [{
fieldName: "Статус проекта",
value: [2] // choice_id варианта «В работе»
}]
};
});
Так же задаётся фильтр по полю Выбор с множественным выбором. Например, если в связанной форме в поле «Направления» можно отметить несколько вариантов, условие value: [2] оставит в списке задачи, в которых среди отмеченных вариантов есть вариант с идентификатором 2.
Фильтр можно комбинировать с полями исходной формы. Например, чтобы показывать только проекты в статусе «В работе» и только выбранного менеджера, передайте в filters два условия:
form.onChange(["manager"], true)
.setFilter("Проект", state => {
const [manager] = state.changes;
const filters = [{
fieldName: "Статус проекта",
value: [2] // choice_id варианта «В работе»
}];
if (manager?.person_id)
filters.push({ fieldName: "Менеджер", value: manager.person_id });
return { filters };
});
Ограничения
- Только одно значение в условии. Если в
valueдля поля типа Выбор передать несколько идентификаторов, например[2, 5], учитывается только первый из них. Отобрать задачи, в которых выбран вариант «2» или «5», с помощью фильтра нельзя. - Нельзя отобрать незаполненные поля. Условия с пустым значением (
false,null,0, пустая строка) не применяются. Например, нельзя оставить в списке только задачи, в которых галочка не поставлена или поле Выбор не заполнено. - Неверные условия пропускаются без ошибки. Если поле с указанным
fieldName,fieldIdилиfieldCodeне найдено в связанной форме или значение передано в неверном формате, условие не применяется и список не фильтруется по этому полю. Если фильтр не срабатывает, проверьте название поля и формат значения по таблице выше. - Поля без доступа не учитываются. Если у пользователя нет доступа к полю связанной формы, условие по этому полю не применяется.