Qlik Community

Ask a Question

Qlik Design Blog

All about product and Qlik solutions: scripting, data modeling, visual design, extensions, best practices, etc.

Francis_Kabinoff
Employee
Employee

You may be familiar with the search functionality in the Qlik Sense client, and also available through the "CurrentSelections" object with the App API using app.getObject(<elementID>, "CurrentSelections"). But it's also possible to build your own custom search using methods in the App API of Qlik Sense 2.2, in particular the searchResults() method and the selectAssociations() method.

note - if you have a version of Qlik Sense earlier than 2.2, the searchResults() method is not available to you. However, the searchAssociations() method can be used instead.

The first method we need to be familiar with, the searchResults() method, does basically what you think it would. It takes an array of terms to search for, has a few useful options that can be passed to it, and has a callback which provides results. An example below

app.searchResults(

  ["it"],  //array of search terms

  {qOffset: 0, qCount: 15}, //how many results to return, and offset

  {qSearchFields: 'Case Owner Group', qContext: 'CurrentSelections'}, //options object

function(reply) {

     //do something with reply here

});

The array of search terms and number of results are relatively straightforward. The options object gives you the ability to define which fields to search (leaving this out will search all fields) and what context to search in, including the ability to search through values not excluded by current selections, or searching through all values, regardless of selections.

The next method you want to be familiar with is the selectAssociations() method. This method makes selections based on an array of search terms, and the position of the result. An example below

app.selectAssociations(

     0,  //position of result to select

     ["it"],  //array of search terms

     {qSearchFields: 'Case Owner Group', qContext: 'CurrentSelections'} //options object

);

So in the above, the first result (index of 0) would be selected from the results returned from searching the "Case Owner Group" field for the search term "it" in the context of current selections.

There's a million cool ways that these methods could be used, but I'm going to walk through a really super basic example by creating an input box and using the input to search through all fields in the app in the context of current selections, and display results which you can make selections from.

The first step is simply to create a container for the input field and the results div, as well as the the input field and results div themselves in HTML

<div class="qs-search-container">

     <input class="qs-search" type="text" placeholder="Search">

     <div class="qs-search-results"></div>

</div>

The next step is to listen for input in the input field using javascript

$(".qs-search").keyup(function() {

     //the rest of our code will go in here

});

Now comes the bulk of the code. I'm going to include it below, along with comments

// Use value of input field as search term in searchResults method

app.searchResults([$(this).val()],

  {qOffset: 0, qCount: 15},

  {qContext: 'CurrentSelections'},

function(reply) {

//assign searchGroupArray of results to variable named searchResults for readability

var searchResults = reply.qResult.qSearchGroupArray;

  // clear any old results

  $(".qs-search-results").html("");

  // append new list to hold results

  $(".qs-search-results").append("<ul>");

  //loop through results and add to dom

  searchResults.forEach(function (result, i) {

    result.qItems.forEach(function (item) {

     //append list element for result

      $(".qs-search-results ul").append("<li data-index='" + i + "'>");

     //append identifier to result list element

      $(".qs-search-results ul li:last-child")

      .append("<div class='qs-search-item-identifier'>" + item.qIdentifier + "</div>");

     //initialize string for matches

      var matchString = "";

     //loop through matches

      item.qItemMatches.forEach(function (match) {

       //add match to match string

        matchString += match.qText;

      });

     //add match string to result list element

      $(".qs-search-results ul li:last-child").append("<div class='qs-search-item-string'>" + matchString + "</div>");

    });

  });

  //Add click handler to each result list item that will make selection

  $(".qs-search-results li").click(function() {

    app.selectAssociations($(this).data("index"), [$(".qs-search").val()], {qContext: 'CurrentSelections'});

   //clear results after selection is made since old results are no longer valid

    $(".qs-search").val("");

    $(".qs-search-results").html("");

  });

});

With a little added CSS, we should end up with something like below.

2016-04-15 17_50_02-Qlik Sense Mashup.png

That's the basic idea. Obviously, the example above could be taken a lot further, but this is a decent starting point for creating your own custom search functionality with the Capability APIs.

some useful links -

searchResults method ‒ Qlik Sense

selectAssociations method ‒ Qlik Sense

Code for the example created above is attached, and can be downloaded and put into the extensions folder of your Qlik Sense Desktop installation to play around with.

2 Comments
ikomlyakov1929
Partner
Partner

Hi Francis,

Thank you for this tutorial! I would like to note one thing:

qSearchFields should be an Array. So

{qSearchFields: 'Case Owner Group', qContext: 'CurrentSelections'}

should be

{qSearchFields: ['Case Owner Group'], qContext: 'CurrentSelections'}.

0 Likes
881 Views
dannyy81
Contributor III
Contributor III

from analyzing the qsearchResaults i didnt find alternatuve results (results that are not possible due to current selections) any idea how could i get the alternative results? (with the indication its alternative )

0 Likes
623 Views