mydomain
No ADS
No ADS

FlutterArtist FilterModelStructure ex3

  1. registerFilterModelStructure()
  2. specifyDefaultValueForMultiOptTildeCriterion()
Note: The article you are viewing is Example Demo59c, a slight variation of Example Demo59a. To ensure everything proceeds smoothly, you should review Example Demo59a first, as some concepts there will not be explained again in this example.
Unlike Demo59a, in this example, we configure both department~1 and department~2 to be children of a single parent criterion, company~. Furthermore, department~1 is set to automatically assign a default value whenever company~ changes, instead of waiting for user input.
Field-Based JSON
{
    "connector": "AND",
    "conditions": [
        {
            "field": "searchText",
            "operator": "containsIgnoreCase",
            "value": null
        },
        {
            "field": "companyId",
            "operator": "equalTo",
            "value": 2
        },
        {
            "connector": "OR",
            "conditions": [
                {
                    "field": "departmentId",
                    "operator": "equalTo",
                    "value": 4
                },
                {
                    "field": "departmentId",
                    "operator": "equalTo",
                    "value": 6
                }
            ]
        }
    ]
}

1. registerFilterModelStructure()

FilterPanel interface.
No ADS
First, let's look at the FilterModelStructure defined in this example.
defineFilterModelStructure()
@override
FilterModelStructure defineFilterModelStructure() {
  return FilterModelStructure(
    criteriaStructure: FilterCriteriaStructure(
      simpleCriterionDefs: [
        SimpleFilterCriterionDef<String>(criterionBaseName: "searchText"),
      ],
      multiOptCriterionDefs: [
        // Multi Options Single Selection Criterion.
        MultiOptFilterCriterionDef<CompanyInfo>.singleSelection(
          criterionBaseName: "company",
          fieldName: 'companyId',
          toFieldValue: (CompanyInfo? rawValue) {
            return SimpleVal.ofInt(rawValue?.id);
          },
          children: [
            // Multi Options Single Selection Criterion.
            MultiOptFilterCriterionDef<DepartmentInfo>.singleSelection(
              criterionBaseName: "department",
              fieldName: 'departmentId',
              toFieldValue: (DepartmentInfo? rawValue) {
                return SimpleVal.ofInt(rawValue?.id);
              },
              tildeCriterionConfigs: [
                TildeCriterionConfig(
                  suffix: '~1',
                  parentMatchSuffix: "~",
                  defaultSettingPolicy: DefaultSettingPolicy.onEveryLoad,
                ),
                TildeCriterionConfig(
                  suffix: '~2',
                  parentMatchSuffix: "~",
                  defaultSettingPolicy: DefaultSettingPolicy.onInitialOnly,
                ),
              ],
            ),
          ],
        ),
      ],
    ),
    conditionStructure: FilterConditionStructure(
      connector: FilterConnector.and,
      conditionDefs: [
        FilterConditionDef.simple(
          tildeCriterionName: "searchText~",
          operator: FilterOperator.containsIgnoreCase,
        ),
        FilterConditionDef.simple(
          tildeCriterionName: "company~",
          operator: FilterOperator.equalTo,
        ),
        FilterConditionDef.group(
          groupName: 'G2',
          connector: FilterConnector.or,
          conditionDefs: [
            FilterConditionDef.simple(
              tildeCriterionName: "department~1",
              operator: FilterOperator.equalTo,
            ),
            FilterConditionDef.simple(
              tildeCriterionName: "department~2",
              operator: FilterOperator.equalTo,
            ),
          ],
        ),
      ],
    ),
  );
}
FilterCriteriaStructure
With the above definition of FilterCriteriaStructure, you will have a criteria structure similar to the illustration below. In this structure, FilterCriteria("department") is a child of FilterCriteria("company").
No ADS
tildeCriterionConfigs
By default, the system links department~xxx with company~xxx. To force both ~1and ~2 to accept company~ as their parent, we use parentMatchSuffix: "~".
MultiOptTildeCriterionDef<DepartmentInfo>
MultiOptFilterCriterionDef<DepartmentInfo>.singleSelection(
  criterionBaseName: "department",
  fieldName: 'departmentId',
  toFieldValue: (DepartmentInfo? rawValue) {
    return SimpleVal.ofInt(rawValue?.id);
  },
  tildeCriterionConfigs: [
    TildeCriterionConfig(
      suffix: '~1',
      parentMatchSuffix: "~",
      defaultSettingPolicy: DefaultSettingPolicy.onEveryLoad,
    ),
    TildeCriterionConfig(
      suffix: '~2',
      parentMatchSuffix: "~",
      defaultSettingPolicy: DefaultSettingPolicy.onInitialOnly,
    ),
  ],
),
DefaultSettingPolicy.onEveryLoad
Whenever company~ changes, department~1 data reloads and is always assigned a new default value.
DefaultSettingPolicy.onInitialOnly
department~2 will only take a default value upon its initial appearance. In subsequent parent changes, it remains empty or awaits user selection.
See more examples of defaultSettingPolicy:
  • FlutterArtist FilterModelStructure ex2 (***)

2. specifyDefaultValueForMultiOptTildeCriterion()

After the data is loaded for each MultiOptTildeFilterCriterion, determining a default value is decided by the specifyDefaultValueForMultiOptTildeCriterion() method:
specifyDefaultValueForMultiOptTildeCriterion()
@override
OptValueWrap? specifyDefaultValueForMultiOptTildeCriterion({
  required String multiOptTildeCriterionName,
  required String multiOptCriterionBaseName,
  required Object? parentMultiOptTildeCriterionValue,
  required SelectionType selectionType,
  required XData multiOptTildeCriterionXData,
}) {
  if (multiOptCriterionBaseName == "company") {
    var xList = multiOptTildeCriterionXData as ListXData<int, CompanyInfo>;
    CompanyInfo? companyInfo = xList.items.firstOrNull;
    return OptValueWrap.single(companyInfo);
  } else if (multiOptCriterionBaseName == "department") {
    var xList = multiOptTildeCriterionXData as ListXData<int, DepartmentInfo>;
    DepartmentInfo? departmentInfo = xList.items.firstOrNull;
    return OptValueWrap.single(departmentInfo);
  }
  return null;
}
No ADS
No ADS