0

In my Drupal 7 site I have a product overview page built with Views. On that page I have a number of checkboxes that can be clicked on in any order. For each checkbox clicked a corresponding tag is copied into an input text field. This text field is then used as a search field for the jQuery Quicksearch plugin. (I borrowed the idea from here, but I use the new plugin version from deuxhuithuit).

As these checkboxes can be clicked in any order, the tags in the search field are being added in any order.

I then have a big number of divs containing products, where each product have a tag text field, where a number of tag terms can be entered separated only with a space, depending on the characteristics of the products.

Is there any way to make the Quicksearch plugin accept these terms in any order with the help of the options prepareQuery and/or testQuery? If so, how is it done? I have spent many hours trying to find examples for how to do this.

If that is not a possibility, I guess the only option is to build a function that will sort the tags in a certain fixed order in the search field, and then always enter the tag terms in the right order for each product...

Anyhow this is how the setup looks like right now:

$('#searchfield').quicksearch('.views-column .views-field-field-soktaggar', {
        'delay': 100,
        'selector': 'div.searchtags',
        'loader': 'span.loading',
        'noResults': '#noresults',
        'bind': 'keyup',
        'show': function () {
                $(this).parent('.views-column').removeClass('hide');
            $(this).parent('.views-column').addClass('show');
        },
        'hide': function () {
            $(this).parent('.views-column').removeClass('show');
                    $(this).parent('.views-column').addClass('hide');

        },
        'prepareQuery': function (val) {
            return new RegExp(val, "i");
        },
        'testQuery': function (query, txt, _row) {
                console.log('query: ' + query + ' txt: ' + txt + ' _row: ' + _row);
            return query.test(txt);
        }
    });
TBJ
  • 407
  • 4
  • 19

1 Answers1

0

In the end I came up with a solution myself. The trick was to sort the query in the same order as the tags are stated for each product. For that end I used a sorting function with a reference array (also the tags must be entered in this order in each product's tag field).

The next problem was that matches were found only when the matching tags were positioned next to each other. For example if the product's tag string were infrared logger ntc and the query was infrared ntc no match was possible. So, in this case the tag logger had to be removed from the tag string.

This is the complete working function now:

$('#searchfield').quicksearch('.views-column .views-field-field-soktaggar', {
        'delay': 100,
        'selector': 'div.searchtags',
        'loader': 'span.loading',
        'noResults': '#noresults',
        'bind': 'keyup',
        'show': function () {
                $(this).parent('.views-column').removeClass('hide');
            $(this).parent('.views-column').addClass('show');
        },
        'hide': function () {
            $(this).parent('.views-column').removeClass('show');
                    $(this).parent('.views-column').addClass('hide');

        },
        'prepareQuery': function (val) {
                // turn query into array in order to allow sorting
                var q = String(val).match(/("[^"]+"|[^"\s]+)/g);
                // sort the tags in the query in the same order as in the reference array
                var reference_array = [ 'ir', 'lowtemp', 'hightemp', 'logger', 'tek', 'tet', 'tes', 'tej', 'pt100', 'ntc', 'livs', 'fastighet' ];
                if(q != null){
                    var result = q.sort(function(a, b) {
                        return reference_array.indexOf(a) - reference_array.indexOf(b);
                    });
                    var str = result.join(' ');
                }
            return new RegExp(str, "i");
        },
        'testQuery': function (query, txt, _row) {
                // remove tags in txt that are not used in query
                if(txt != ''){ // only process items with tags
                    // turn txt (tags from items) into array
                    var t = String(txt).match(/("[^"]+"|[^"\s]+)/g);
                    // remove leading '/' and trailing '/i' in query
                    var str = String(query).replace(/^\/|\/i$/g, '');
                    // turn query into array
                    var q = String(str).match(/("[^"]+"|[^"\s]+)/g);
                    // only show matching tags in txt, otherwise matching is not always possible
                    var res = t.filter(element => q.includes(element));
                    //turn tags array into string
                    var _txt = res.join(' ');
                    // use this alternative tag string from items
                    return query.test(_txt);
                }

            return query.test(txt);
        }
    });
TBJ
  • 407
  • 4
  • 19