Filtering options

Cloud Pyrus
Cloudless Pyrus

Scripts can limit the options available in Catalog and Form fields. To do this, subscribe to changes in the form fields you need with onChange and call one of the filter methods: setFilter or setFilterAsync.

Filtering catalog items

For a Catalog field, the filter function must return an object with the values field containing a list of values from the first column of the catalog.

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>
    )
}

To learn how to get catalog items with getCatalog and see an example of filtering cities by the selected state, see Catalogs.

Filtering a Form field

To limit the options available in a Form field, the filter function must return an object with the filters field. This field contains a list of conditions on field values of the linked form.

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;
}

Each FormLinkFilter condition includes a field of the linked form (fieldId, fieldName, or fieldCode) and the field value.

For example, when the manager field changes, the script filters the list of tasks in the contragent field and shows only the tasks of the linked form in which the Manager field contains the same user as the manager field of the original form.

form.onChange(["manager"], true)
  .setFilter("contragent", state => {
    const [manager] = state.changes;

    if (!manager?.person_id) return null;

    return {
      filters: [{
        fieldName: "Manager",
        value: manager.person_id
      }]
    }
  });

If you filter by a Catalog field of the linked form, pass the value in a different format: an array with an object that contains the catalog item ID — value: [{ Id: item_id }].

For example, the Project name field should show only the projects in which the Client field (a Catalog field) contains the same client as the Client field of the original form.

form.onChange(["Client"], true)
  .setFilterAsync("Project name", async state => {
    const [clientField] = state.changes;

    // If no client is selected, show all projects
    if (!clientField || !clientField.item_id) {
      return null;
    }

    const clientItemId = clientField.item_id;

    // Return the filter
    return {
      filters: [
        {
          fieldCode: "ClientFieldCode",
          value: [{ Id: clientItemId }], // format for catalog fields
        }
      ]
    };
  });

Value formats in filter conditions

Filter conditions use their own value format, which differs from the one described in Field value formats. The format depends on the type of the linked form field you filter by. For example, for a Multiple choice field, pass the array [2], not the object { choice_id: 2 }.

Linked form field typevalue formatTasks that remain in the list
TextString: "Boston"The field value starts with the specified string
Number, MoneyNumber: 1500The field value equals the specified number
Check MarktrueThe box is checked
Multiple choiceArray with the option ID: [2]The specified option is selected
Multiple choice with multiple selectionArray with the option ID: [2]The specified option is among the selected options
ContactUser ID: manager.person_idThe field contains this user
CatalogArray with an object: [{ Id: item_id }]The specified catalog item is selected

You can find the option ID (choice_id) in one of the following ways:

  • In the browser console. When a task is selected in a Form field, the value that the script receives contains the fields object with the field values of that task. For a Multiple choice field, it includes choice_ids and choice_names. Print the value to the console with console.log (see Debugging), open the form, and select a task in which the option you need is selected.
  • Using the API. The field options are listed in the options property of the form description returned by GET /forms/{form-id}. For details, see Form fields.

Here is a script that prints the field values of the task selected in the Project field to the console:

form.onChange(["Project"])
  .validate("Project", state => {
    const [project] = state.changes;

    // For example: { "Project status": { choice_ids: [2], choice_names: ["In progress"] }, ... }
    console.log(project?.fields);
  });

Once you've found the ID you need, remove this debugging block from the script.

If you set several conditions, only the tasks that match all of them remain in the list.

Filtering by a check mark

For example, the Contractor field should show only the tasks of the linked form in which the Contract signed box is checked. The filter applies only if the Signed contracts only box is checked in the original form.

form.onChange(["Signed contracts only"], true)
  .setFilter("Contractor", state => {
    const [onlySigned] = state.changes;

    // The box is not checked — show all tasks
    if (!onlySigned?.checked) return null;

    return {
      filters: [{
        fieldName: "Contract signed",
        value: true
      }]
    };
  });

Filtering by a Multiple choice field

For example, if the Active only box is checked in the original form, the Project field should show only the projects with the In progress status. In the linked form, this option of the Project status field has the ID 2.

form.onChange(["Active only"], true)
  .setFilter("Project", state => {
    const [onlyActive] = state.changes;

    if (!onlyActive?.checked) return null;

    return {
      filters: [{
        fieldName: "Project status",
        value: [2] // choice_id of the "In progress" option
      }]
    };
  });

A filter by a Multiple choice field that allows multiple selection works the same way. For example, if several options can be selected in the Areas field of the linked form, the condition value: [2] leaves the tasks in which the option with the ID 2 is among the selected options.

You can combine the filter with fields of the original form. For example, to show only the projects with the In progress status that belong to the selected manager, pass two conditions in filters:

form.onChange(["manager"], true)
  .setFilter("Project", state => {
    const [manager] = state.changes;

    const filters = [{
      fieldName: "Project status",
      value: [2] // choice_id of the "In progress" option
    }];

    if (manager?.person_id)
      filters.push({ fieldName: "Manager", value: manager.person_id });

    return { filters };
  });

Limitations

  • One value per condition. If you pass several IDs in value for a Multiple choice field, for example [2, 5], only the first one is used. You can't use a filter to select the tasks in which option 2 or option 5 is selected.
  • You can't filter by empty fields. Conditions with an empty value (false, null, 0, an empty string) are not applied. For example, you can't leave only the tasks in which a box is not checked or a Multiple choice field is empty.
  • Invalid conditions are skipped without an error. If the field specified in fieldName, fieldId, or fieldCode isn't found in the linked form, or the value has the wrong format, the condition is not applied and the list is not filtered by this field. If a filter doesn't work, check the field name and the value format against the table above.
  • Fields without access are ignored. If the user doesn't have access to a field of the linked form, the condition on this field is not applied.

Was this article helpful?