Cold_Class
Cold_Class

Reputation: 3504

How to filter nested sap.m.Lists with a SearchField?

I created a list which has two more lists inside of it.
Here's the rough structure (working example at the end of the question):

// Data structure
results: [{
  group: "1",
  children: [{
    group: "foo1",
    children: [{
      value1: "foo1.1",
      value2: "bar1.1"
    }, {
      value1: "foo1.2",
      value2: "bar1.2"
    }],
  }],
}]
// Element structure
List({
  items: {
    path: "/results",
    template: CustomListItem({
      content: List({
        path: "children",
        template: CustomListItem({
          content: List({
            path: "children",
            template: StandardListItem({
              title: "{value1}",
              info: "{value2}",
            })
          })
        })
      })
    })
  }
})

Now I want to filter the items in the last lists and I don't understand how to do it.

For a single list I got it:

onSearch: function(oEvent) {
  var sQuery = oEvent.getSource().getValue();
  var oFilter = new sap.ui.model.Filter({
    filters: [
      new sap.ui.model.Filter("value1", sap.ui.model.FilterOperator.Contains, sQuery),
      new sap.ui.model.Filter("value2", sap.ui.model.FilterOperator.Contains, sQuery)
    ],
    and: false
  });
  var oBinding = this.byId("list-id").getBinding("items");
  oBinding.filter(oFilter, sap.ui.model.FilterType.Application);
}

But in my case the value1 and value2 arent directly in the "list-id" list, but two levels below.

Here's a link to the minimal example: https://jsfiddle.net/54xzbvsp/

Upvotes: 0

Views: 649

Answers (2)

Richard
Richard

Reputation: 1995

It will not work with the standard filter on json model.

You should look into a tree if u have a 3 layer Hierarchie.

Upvotes: 1

Cold_Class
Cold_Class

Reputation: 3504

As the comment suggested as well, I couldn't find a solution using the Filter object, so I filtered the data manually and it worked like this:

onSearch: function(oEvent) {
    let sQuery = oEvent.getSource().getValue();
    let originalModel = this.getView().getModel();
    let originalDataCopy = JSON.parse(JSON.stringify(originalModel.oData));
    let filtered = originalDataCopy.results.filter(topGroup => {
      // Filter second level groups
      let filteredMidGroups = topGroup.children.filter(midGroup => {
        // Filter last Level
        let filteredSingleElements = midGroup.children.filter(singleElement => {
          let search = sQuery.toLowerCase();
          let valueFound = (
            singleElement.value1.toLowerCase().includes(search) ||
            singleElement.value2.toLowerCase().includes(search)
          );
          return valueFound;
        });
        midGroup.children = filteredSingleElements;
        return (filteredSingleElements.length > 0);
      });
      topGroup.children = filteredMidGroups;
      return (filteredMidGroups.length > 0);
    });
    let oModel = new sap.ui.model.json.JSONModel({
      results: filtered
    });
    this.getView().setModel(oModel, "filtered");
}

Here the full minimal working example: https://jsfiddle.net/kh1fep3z/2/

Upvotes: 0

Related Questions