mydomain
No ADS
No ADS

FlutterArtist Multi Sort ex1

  1. Structure of the example
  2. BestSelling52aSortModelBuilder
  3. BestSelling52aShelf
  4. BreadcrumbSortPanel
Multi-sort is the process of sorting data based on multiple criteria in a defined priority order. In this process, users can specify a primary sorting criterion, followed by secondary criteria, and additional sorting levels if needed.
For example, suppose you have a list of the best-selling items in a month with information such as category name, item name, quantity, and total amount. You can perform multi-sort by sorting first by category name, then by item name, and continue by other criteria such as quantity or total amount if necessary.
In this article, we will look at an example that uses BreadcrumbSortPanel, which allows users to select multiple sorting criteria. BreadcrumbSortPanel is a built-in widget in FlutterArtist.
BreadcrumbSortPanel also supports drag-and-drop to rearrange the priority order of the sorting criteria.
Note: If you are new to the concept of sorting in FlutterArtist, you may want to start with the article below for a more detailed explanation of the basic concepts.

1. Structure of the example

2. BestSelling52aSortModelBuilder

In this example, BestSellingData is a data model that represents information about a best-selling product in a month.
BestSellingData
class BestSellingData { 
  int categoryId; 
  String categoryName; 
  int productId; 
  String productName; 
  String? productImageName; 
  double unitsTotal; 
  double amountTotal; 
  double taxAmountTotal;
}  
In FlutterArtist, SortModelBuilder is a class used to define sorting criteria and the sorting rules on the client side. SortModelBuilder is used by a Block to create two SortModel objects for client-side sorting and server-side sorting.
Block (*)
SortModel<ITEM>? get clientSideSortModel;

SortModel<ITEM>? get serverSideSortModel;
No ADS
best_selling52_sort_model_builder.dart
class BestSelling52aSortModelBuilder extends SortModelBuilder<BestSellingData> {
  BestSelling52aSortModelBuilder({
    required super.clientSideSortMode,
    required super.serverSideSortMode,
  });

  @override
  SortModelStructure defineSortModelStructure() {
    return SortModelStructure(
      sortCriterionDefs: [
        SortCriterionDef(
          criterionName: 'categoryName',
          text: 'Category Name',
          translationKey: "bestSelling.categoryName",
          serverSideConfig: SortCriterionConfig(directionalSelectionOnly: true),
          clientSideConfig: SortCriterionConfig(directionalSelectionOnly: true),
        ),
        SortCriterionDef(
          criterionName: 'productName',
          text: 'Product Name',
          translationKey: "bestSelling.productName",
        ),
        SortCriterionDef(
          criterionName: 'unitsTotal',
          text: 'Total',
          translationKey: "bestSelling.unitsTotal",
        ),
        SortCriterionDef(
          criterionName: 'amountTotal',
          text: 'Amount',
          translationKey: "bestSelling.amountTotal",
        ),
      ],
    );
  }

  @override
  Comparable? getComparisonValue({
    required BestSellingData item,
    required String criterionName,
  }) {
    if (criterionName == "categoryName") {
      return item.categoryName;
    } else if (criterionName == "productName") {
      return item.productName;
    } else if (criterionName == "unitsTotal") {
      return item.unitsTotal;
    } else if (criterionName == "amountTotal") {
      return item.amountTotal;
    }
    return null;
  }

  @override
  String? getTranslationText({required String translationKey}) {
    return null;
  }
}

3. BestSelling52aShelf

In the previous step, you created the BestSelling52aSortModelBuilder class. Next, you need to declare it as a component of the BestSelling52aBlock.
best_selling52a_shelf.dart
class BestSelling52aShelf extends Shelf {
  @override
  ShelfStructure defineShelfStructure() {
    return ShelfStructure(
      filterModels: {},
      blocks: [
        BestSelling52aBlock(
          name: BestSelling52aBlock.blkName,
          description: null,
          config: BlockConfig(
            pageable: Pageable(pageSize: 100),
            clientSideSortStrategy: SortStrategy.modelBased,
          ),
          filterModelName: null,
          formModel: null,
          childBlocks: [],
          // SortModelBuilder:
          sortModelBuilder: BestSelling52aSortModelBuilder(
            clientSideSortMode: SortMode.multi,
            serverSideSortMode: SortMode.single,
          ),
        ),
      ],
    );
  }

  BestSelling52aBlock findBestSelling52aBlock() {
    return findBlock(BestSelling52aBlock.blkName) as BestSelling52aBlock;
  }
}
No ADS
BlockConfig.clientSideSortStrategy
The BlockConfig.clientSideSortStrategy parameter defines how the Block handles client-side sorting.
BlockConfig(
  ...
  clientSideSortStrategy: SortStrategy.modelBased,
),
The BlockConfig.clientSideSortMode parameter accepts one of the following values:
none
With this configuration, this Block will not support client-side sorting (including manual sorting) and block.clientSideSortModel will always return null.
modelBased
With this configuration, Block will apply sorting on the client side if you provide it with a SortModelBuilder, then block.clientSideSortModel will be guaranteed to be non-null.
manual
With this configuration, Block accepts manual arrangement of its ITEM(s) via drag and drop on the interface. In this case block.clientSideSortModel will always be null.
Examples of manual sorting on the client side by dragging and dropping on the interface.

4. BreadcrumbSortPanel

In FlutterArtist, SortPanel is a base widget used to create a user interface component that allows users to select sorting criteria.
You can create custom SortPanel widgets by extending the SortPanel class, or simply use the prebuilt widgets provided by FlutterArtist.
In this example, we use BreadcrumbSortPanel, and the following snippet shows its basic usage.
if (bestSelling52aBlock.serverSideSortModel != null)
  BreadcrumbSortPanel.simple(
    sortModel: bestSelling52aBlock.serverSideSortModel!,
  ),

if (bestSelling52aBlock.clientSideSortModel != null)
  BreadcrumbSortPanel.simple(
    sortModel: bestSelling52aBlock.clientSideSortModel!,
  ),
Multi-Sort
Configuration for enabling Multi-Sort:
ShelfStructure (Multi-Sort)
ShelfStructure(
  filterModels: {},
  blocks: [
    BestSelling52aBlock(
      name: BestSelling52aBlock.blkName,
      description: null,
      config: BlockConfig(
        pageable: Pageable(pageSize: 100),
        clientSideSortStrategy: SortStrategy.modelBased,
      ),
      filterModelName: null,
      formModel: null,
      childBlocks: [],
      // SortModelBuilder:
      sortModelBuilder: BestSelling52aSortModelBuilder(
        clientSideSortMode: SortMode.multi, // <-----------
        serverSideSortMode: SortMode.multi, // <-----------
      ),
    ),
  ],
);
With the Multi-Sort configuration, you can select sorting directions (ascending or descending) for multiple criteria simultaneously.
No ADS
Single-Sort
Configuration for Single-Sort:
ShelfStructure (Single-Sort)
ShelfStructure(
  filterModels: {},
  blocks: [
    BestSelling52aBlock(
      name: BestSelling52aBlock.blkName,
      description: null,
      config: BlockConfig(
        pageable: Pageable(pageSize: 100),
        clientSideSortStrategy: SortStrategy.modelBased,
      ),
      filterModelName: null,
      formModel: null,
      childBlocks: [],
      // SortModelBuilder:
      sortModelBuilder: BestSelling52aSortModelBuilder(
        clientSideSortMode: SortMode.single, // <---------
        serverSideSortMode: SortMode.single, // <---------
      ),
    ),
  ],
);
With the Single-Sort configuration, when you choose a sorting direction for one criterion, the other criteria will automatically be reset to a non-direction state.
Single-Sort
No ADS
No ADS