Build List / Grid Searchfield

Donnerstag, 20. Februar 2014
I want you to show a little tutorial how to create a searchfield to filter a list, grid or something else which has a relation to a store. I want to show this to you by using a list.

If you need you can download the Architect 3 project from here: https://mega.co.nz/#!9NFyRCLL!98dkUmISgGO_p0crDI8YExINmf5ORCglkDrWjuRyu7Y


First we create a Store with a model and some data in it. If you want to take a look, you'll have a link here: https://gist.github.com/difa1/9115899

Second we need to create a simple list in a panel:

Ext.define('MyApp.view.MyPanel', {
    extend: 'Ext.Panel',
    requires: [
        'Ext.dataview.List',
        'Ext.XTemplate'
    ],
    config: {
        layout: 'vbox',
        items: [
            {
                xtype: 'list',
                flex: 1,
                itemTpl: ['{name}, {namelast}'],
                store: 'persons'
            }
        ]
    }
});

Third we would like to implement the searchfield. You can place it however you want.

Ext.define('MyApp.view.MyPanel', {
    extend: 'Ext.Panel',
    requires: [
        'Ext.field.Search',
        'Ext.dataview.List',
        'Ext.XTemplate'
    ],
    config: {
        layout: 'vbox',
        items: [
            {
                xtype: 'searchfield',
                docked: 'top',
                itemId: 'storeSearchField',
                label: 'Field'
            },
            {
                xtype: 'list',
                flex: 1,
                itemId: 'mylist',
                itemTpl: ['{name}, {namelast}'],
                store: 'persons'
            }
        ]
    }
});

Now that the basics a build we build a new controller where all the logic is stored. So lets go to Step 4 and create the controller with 2 listeners: keyup and clearicontap:

Ext.define('MyApp.controller.logicController', {
    extend: 'Ext.app.Controller',
    config: {
        control: {
            "searchfield#storeSearchField": {
                clearicontap: 'onStoreSearchFieldClearicontap',
                keyup: 'onStoreSearchFieldKeyup'
            }
        }
    },
    onStoreSearchFieldClearicontap: function(textfield, e, eOpts) {
        // Logic
    },
    onStoreSearchFieldKeyup: function(textfield, e, eOpts) {
        // Logic
    }
});

The logic for the clearicontap is pretty simple... All we want is to clear all filters. All we need is the clearfilter method :

    onStoreSearchFieldClearicontap: function(textfield, e, eOpts) {
        Ext.getStore('persons').clearFilter();
    }


The keyup is a bit more tricky, why I like to use a basic function for it. I tried to explain all steps in the coding itself. If anything were unclear, you could contact me on Google+ ;)

onStoreSearchFieldKeyup: function(textfield, e, eOpts) {
    this.filterList(textfield, Ext.getStore('persons'));
},

filterList: function(textfield, store) {
    // Get the searchfield content
    var value = textfield.getValue();

    // Clear previous filters
    store.clearFilter();

    // Check for search value, if not present we don't need to to anything...
    if (value) {

        // Split search value: Space --> 2 custom values!
        var searches = value.split(' '),
        regexps = [],
        i;

        // Loop search values and build regex
        for (i = 0; i < searches.length; i++) {

            // Ignore spaces
           if (!searches[i]) continue;

           // Regex array
           regexps.push(new RegExp(searches[i], 'i'));
            
       }

       // Filter the store
       store.filter(function(record) {

           // Clear matches first
           var matched = [];

           // Loop all regex expressions
           for (i = 0; i < regexps.length; i++) {
               var search = regexps[i];
               var didMatch;

              didMatch = record.get('name').match(search) ||
                         record.get('namelast').match(search);
                    // You can add as many model fields as you want! --> record.get('city1').match(search) ||


              // Write match to array
              matched.push(didMatch);
          }

          // Nothing found? Do not return anything ;)
          if (regexps.length > 1 && matched.indexOf(false) != -1) {

               return false;

          } else {

               // Found something? Just return to store ;)
               return matched[0];

          }
     });

     // Finally load store
     store.load();
}