vendredi 30 décembre 2016

Add facet & value programmatically with VisualSearch.js in Ember JS

I'm using VisualSearch.js. Works great out of the box but my interface has a graph which shows the different statuses. When user clicks on one of the status I want to add a facet & value (i.e. status:open) to the search box and trigger the search.

I have two different components one contains graph and another contains visual search code.

How can I add facet from first component which contain graph?

**vsbase.js  #mixin** 

import Ember from 'ember'

export default Ember.Mixin.create({
init(){
    this._super(...arguments);
    this.set('role', this.get('rfpSession.currentUser.role'));
    if(this.globals.isSupplierUser(this.role)){
        this.set('validCampaignStates', this.globals.getCampaignStatusArray().getEach('id').toString());
    }
},
sendFilterAction: function(q){
    Ember.run.schedule('actions', this, function() {
        this.sendAction('gridFilter', q, this); //eslint-disable-line no-invalid-this
    });
},
sortByLabel: function(obj1, obj2){
    let name1 = obj1.label;
    let name2 = obj2.label;
    return name1.localeCompare(name2);
},
filterTypes: ['like', 'eq', 'gte', 'gt', 'lte', 'lt', 'not'],
prependFilterTypeOptions(filterTypes, searchTerm, ajaxMatches){
    if(filterTypes && Array.isArray(filterTypes) && searchTerm !== ''){
        filterTypes.forEach( type => {              
            let listItem = {value: searchTerm};
            switch( type ){
            case 'like' : {
                listItem.label = `Contains: "${searchTerm}"`;
                listItem.type  = type;
                break;
            }
            case 'gte' : {
                listItem.label = `>= "${searchTerm}"`;
                break;
            }
            case 'gt' : {
                listItem.label = `>  "${searchTerm}"`;
                break;
            }
            case 'lte' : {
                listItem.label = `<= "${searchTerm}"`;
                break;
            }
            case 'lt' : {
                listItem.label = `< "${searchTerm}"`;
                break;
            }
            case 'not' : {                  
                listItem.label = `Not "${searchTerm}"`;
                break;
            }
            default : {
                break;
            } 
            }
            ajaxMatches.unshift(listItem);
        });
    }
},
getResult(rowAttr, column){
    let result = {type : 'eq'};
    switch(column){
    case 'Makegoods': {
        result.label = rowAttr ? 'Yes' : 'No';  
        result.value = rowAttr.toString();  
        break;
    }       
    default: {
        result.label = rowAttr;
        result.value = rowAttr;  
        break;
    }
    }
    return result;      
},
vsQueryToDbFilter(facetModels, columns){
    console.log('vsQueryToDbFilter');
    //GM - START helper functions used further down
    let labelToFilterField = function(label){
        console.log('label -' + label);
        let filterField;
        columns.find((col) => {
            if(col.label === label){
                if(col.include){
                    filterField = `${col.include}.${col.column}`;
                } else {
                    filterField = col.column;
                }                   
                return true;
            }
            return false;
        });
        console.log('filterField -- '+filterField);
        return filterField;
    };
    //GM - END helper functions

    let dbFilters = {};
        console.log('facetModels.length -- '+facetModels.length);
    if( facetModels.length){            
        facetModels.forEach(function(vsFilter){
            let columnLabel = vsFilter.attributes.category;
            let filterField = labelToFilterField(columnLabel);
            let filterKey = (vsFilter.attributes.filterVal).replace(',', '\\,');
            let filterType = vsFilter.attributes.filterType;

            if(filterType !== 'eq'){                    
                if(!dbFilters[filterType]){
                    dbFilters[filterType] = {};
                }
                if(!dbFilters[filterType][filterField]){
                    dbFilters[filterType][filterField] = filterKey;
                } else {
                    dbFilters[filterType][filterField] = dbFilters[filterType][filterField] + ',' + filterKey;
                }
            //GM filter[col]
            } else { //this will be a regular equvilence filter
                if(!dbFilters[filterField]){
                    dbFilters[filterField] = filterKey;
                } else {
                    dbFilters[filterField] = dbFilters[filterField] + ',' + filterKey;
                }

            }   
        }, this);           
    }
    console.log('dbFilters -- ' )
    console.dir(dbFilters);     
    return dbFilters;   
}
});

visual-search.js #component

import Ember from 'ember';
import moment from 'moment';
import VSBaseMixin from 'rfp-client/mixins/vs-base';
const _0 = 0;
const _1 = 1;

export default Ember.Component.extend(VSBaseMixin, {
    ajax: Ember.inject.service(),
columnNames: [],
complexResults: false,
containsDropdownItem(results, newItem){
    for(let i = _0; i < results.length; i++){           
        if(results[i].label === newItem.label){
            return true;
        }
    }
    return false;
},
didInsertElement: function () {
    let self = this;

    Ember.run.scheduleOnce('afterRender', this, function() {            
        var visualSearch = VS.init({
            context: this, 
            container: self.$('#' + self.get('vsID')),
            query: '',
            preserveOrder: true,                
            showFacets: true,
            callbacks: {
                search: function(query, searchCollection) {
                    let dbFilter = self.vsQueryToDbFilter(searchCollection.models, self.get('columns'));
                    self.sendFilterAction(dbFilter);  
                },
                facetMatches: function(callback) { //fired when user first interacts with filters
                    let cols = self.get('columns').map(function(value) {                            
                        return value.label;                         
                    });
                    callback(cols);

                },
                valueMatches: function(facet, searchTerm, callback) {  //fired when user selects a column to filter
                    this.gridData = self.get('vsData'); 
                    self.get('columns').find((column) => {

                        this.matchTerm = column.label;

                        if(this.matchTerm === facet){

                            let dropdownResults = [];
                            this.gridData.forEach(function(instance){
                                let dropdownItem = instance.get(column.column);
                                let dropdownResult = self.getResult(dropdownItem, this.matchTerm);
                                if(!self.containsDropdownItem(dropdownResults, dropdownResult)){                                                                                
                                    dropdownResults.push(dropdownResult);                                       
                                }
                            }, this);
                            dropdownResults.sort(self.sortByLabel);
                            self.prependFilterTypeOptions(column.filterTypes, searchTerm, dropdownResults);
                            callback(dropdownResults, {preserveMatches: false});
                            return true;

                        } else { //eslint-disable-line no-else-return
                            return false;
                        }
                    }, this);

                }
            }
        });

    });
}
});




Aucun commentaire:

Enregistrer un commentaire