Migrating to Ember Tables on Open Event Frontend – Part 3: Search module

This blog article will continue the discussions about setting up ember tables on open event frontend. The implementation and design of the search module of the ember tables will be discussed.

Open event server supports searching, using filter queries offered by flask-rest-json-api 

Leveraging the refreshModel property of the queryParams, we can bind the value of a potential search query of a user to a queryParam. As the user types the query, the queryParam will change, which in turn will refresh the model, and send a new request to the server, giving the impression of a basic search.

An icon input field with a search icon is placed on the top right corner of the table wrapped in its own separate component, search-box. The component is rendered within the default table component, which acts as a base for all other tables in the app.

Here, searchQuery is binded to the param search defined in the controller mixin for ember tables.

<div class="ui small icon input">
  {{input type="text" value=searchQuery placeholder="Search ..." }}
  <i class="search icon"></i>
</div>

Now in order to generate the query string which will result in a search involves complex array filter manipulations, hence the logic was abstracted into the route mixin to avoid it’s repetition across various routes.

Flast-rest-json api’s filters follow the following format for a  basic like styled sql filter:

GET /events?filter=[
  {
    "name": "event",
    "op": "ilike",
    "val": searchQuery  }
] HTTP/1.1
Accept: application/vnd.api+json

There are several other query combinations available for comparison, dates and other data-types or for relationships themselves. They needed to be appended to the filter portion of a query and then removed.

When the search param is null, the query string has the following form:

let queryString = {
      include        : 'tickets,user',
      filter         : filterOptions,
      'page[size]'   : params.per_page || 10,
      'page[number]' : params.page || 1
    };

filterOptions are other filters already present, for instance for listing orders on the basis of a dynamic status parameter,  filterOptions can be defined as follows.

 filterOptions = [
        {
          name : 'status',
          op   : 'eq',
          val  : params.orders_status
        }
      ];

Since filterOptions are an array, new filters are either added or appended to the array.

 applySearchFilters(options, params, searchField) {
    searchField = kebabCase(searchField);
    if (params.search) {
      options.pushObject({
        name : searchField,
        op   : 'ilike',
        val  : `%${params.search}%`
      });
    } else {
      options.removeObject({
        name : searchField,
        op   : 'ilike',
        val  : `%${params.search}%`
      });
    }
    return options;
  }

Thus a method called applySearchFilters is defined in the ember-table-router mixin.

It takes three arguments:

  • options
  • params
  • searchField

Options is the filter array, discussed above, params contains the value of the current search param, and the searchField is the target of the search which is defined in the route’s model hook itself. The open-event-api server, expects the name of fields in kebab case, where as the front-end uses camelCase, hence the searchField is explicitly converted into a kebab-case string before manipulating the filter array. If params are present, it appends the filter object to the queryString, else this function will remove the very filter it added to the query string.

Finally in the route’s model hook itself, queryString is passed to this function, and the filters get applied to it.

    queryString = this.applySortFilters(queryString, params);

Semantic UI has a dedicated class for search input fields, which has been used in the template. As a future goal, a slight delay can be introduced in the update cycle of the search queryParam, currently a network request is sent on each keystroke of the user’s input which can be taxing for the server. Introducing a slight delay or alternatively cancelling a request no longer needed will improve latency and response time of the API server, until elastic search is introduced.

Resources 

CosmicCoder96

GSOC 17 @ FOSSASIA | Full Stack Developer | Swimmer

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.