mercredi 1 juillet 2015

visualsearch (faceted query search) using Sencha ExtJS 5

I've been trying to implemented a faceted search autocomplete using Sencha ExtJS 5. Something similar to the "visualsearch" plugin developed using JQuery.

This is what I'd like to do:

http://ift.tt/1Nxugd0

So far, this is what I have:

Ext.define('App.custom.SearcherWidget', {
extend: 'Ext.form.field.ComboBox',
alias: 'widget.searcher',
emptyText: 'Select Entity',

isKeySelected: false,

currSelectedKey: null,

facetedQuery: null,

initComponent: function() {
    var me = this;
    me.store = me.retrieveKeys();//TODO: To be changed
    me.queryMode = 'local';
    me.displayField = 'description';
    me.valueField = 'code';
    me.typeAhead = true;
    me.minChars = 1;
    me.enableKeyEvents = true;
    me.triggerAction = 'query';
    me.hideTrigger = true;

    me.on({
        change: me.fixChange,
        beforeselect: me.fixBeforeSelect,
        beforequery: me.fixBeforeQuery,
        keypress: me.checkKeyPressed,
        scope: me
    });

    me.callParent(arguments);
},

checkKeyPressed: function(combo, e, eOpts) {
    var me = this,
        selectedValue = combo.getValue(),
        comboStore = combo.store;

    if (selectedValue && selectedValue.length > 0) {
        //Not the first time, check if is key or value
        if (this.isKeySelected) {
            //Is a key
            comboStore.loadData(me.retrieveKeys());
        } else {
            //Is a value and a key is current selected
            comboStore.loadData(me.retrieveValuesBasedOnKeys(me.currSelectedKey));
        }
        comboStore.load();
    } else {
        //It is empty, so we should check key
        comboStore.loadData(me.retrieveKeys());
        comboStore.load();
    }

},

fixChange: function(combo, newVal, oldVal, eOpts) {
    var selectedValue = combo.getValue();

    if (!(selectedValue && selectedValue.length > 0)) {
        combo.collapse();
    } else {

    }

},

fixBeforeSelect: function(combo, record, index, eOpts) {
    var me = this,
        selectedValue = combo.getValue(),
        terms = selectedValue.split( /,\s*/ );

    if (record && record.get('type') === 'key') {
        isKeySelected = true;
        me.currSelectedKey = record.get('description');
        terms.pop();
        terms.push(me.currSelectedKey);
        terms.push('');
        combo.setValue(terms.join( ': ' ));
        combo.collapse();
    } else {
//          terms.pop();
//          terms.push(record.get('description'));
//          terms.push('');
//          combo.setValue(terms.join( ', ' ));
//          combo.collapse();
    }

    return false;
},

fixBeforeQuery: function(queryPlan, eOpts) {
     var terms = queryPlan.query.split( /,\s*/ );
     queryPlan.query = terms[terms.length - 1];
     return (queryPlan.query && queryPlan.query.length > 0);
},

retrieveKeys: function() {
    return Ext.create('Ext.data.ArrayStore', {
        fields: [{name: 'code'},
                 {name: 'description'},
                 {name: 'type'}],
        data: [
               [1, 'domain', 'key'],
               [2, 'instance', 'key'],
               [3, 'attribute', 'key'],
               [4, 'relation', 'key']
        ]
    });
},

retrieveValuesBasedOnKeys: function(key) {
    var me = this,
        rawData = me.retrieveMockValues(),
        dataBasedOnKey = [];

    for (var i = 0; i < rawData.length; i++) {
        var currElement = rawData[i];
        if (currElement.type === key) {
            dataBasedOnKey.push(currElement);
        }
    }

    return Ext.create('Ext.data.ArrayStore', {
        fields: [{name: 'code'},
                 {name: 'description'},
                 {name: 'type'}],
        data: dataBasedOnKey
    });
},

retrieveMockValues: function() {
    return [{'code': 1, 'description': 'verizon', 'type': 'domain'},
            {'code': 2, 'description': 'terremark', 'type': 'domain'},
            {'code': 3, 'description': 'sencha', 'type': 'domain'},
            {'code': 4, 'description': 'microsoft', 'type': 'domain'},
            {'code': 5, 'description': 'oracle', 'type': 'domain'},
            {'code': 6, 'description': 'dev1', 'type': 'instance'},
            {'code': 7, 'description': 'dev2', 'type': 'instance'},
            {'code': 8, 'description': 'dev3', 'type': 'instance'},
            {'code': 9, 'description': 'dev4', 'type': 'instance'},
            {'code': 10, 'description': 'dev5', 'type': 'instance'},
            {'code': 11, 'description': 'dev6', 'type': 'instance'},
            {'code': 12, 'description': 'dev7', 'type': 'instance'},
            {'code': 13, 'description': 'dev8', 'type': 'instance'},
            {'code': 14, 'description': 'red', 'type': 'attribute'},
            {'code': 15, 'description': 'white', 'type': 'attribute'},
            {'code': 16, 'description': 'black', 'type': 'attribute'},
            {'code': 17, 'description': 'blue', 'type': 'attribute'},
            {'code': 18, 'description': 'one-to-many', 'type': 'relation'},
            {'code': 19, 'description': 'many-to-many', 'type': 'relation'},
            {'code': 20, 'description': 'one-to-one', 'type': 'relation'}
            ];
},

retrieveEntities: function() {
    return Ext.create('Ext.data.ArrayStore', {
        fields: [
          {name: 'code'},
          {name: 'type'},
          {name: 'description'}
        ],
        data  : [
          [1,'Domain','AT&T'],
          [2,'Domain','Altria Group Inc'],
          [3,'Domain','American Express Company'],
          [4,'Domain','Bellcorp'],
          [5,'Domain','Claro'],
          [6,'Domain','Dell'],
          [7,'Domain','E&E'],
          [8,'Domain','Farenheit'],
          [9,'Domain','Garman'],
          [10,'Domain','Hell'],
          [11,'Domain','Intel'],
          [12,'Domain','Jasper'],
          [13,'Domain','Halmington'],
          [14,'Domain','LLL Corp'],
          [15,'Domain','Verizon'],
          [5,'Instance','American Express Company']
        ]
      });
}

});

I tried to adapt the "visualsearch" of JQuery to the ExtJS code... but no success at all... I wonder if somebody could give me a clue or a hand on this.

Any help is appreciated. Thanks in advance.

Aucun commentaire:

Enregistrer un commentaire