Components

The Blaze components provide you with an input, the results view, logic to add loading spinners and more. Those are also customizable and should be sufficient for most use cases. The components can be used in the easy:search package which wraps the core and easysearch:components into one. This article assumes you have read the Getting started page beforehand.

List of components

All the components require you to add an index parameter which is the index instance that it should act on. Certain components allow you to specify an array of indexes to pass in. You can also specify a name when you want to have multiple components of an index on the same page.

Input

Renders an <input> tag that searches the specified index(es). It searches through all the configured fields on your index. Allows to use multiple indexes.


{{> EasySearch.Input index=myIndex}}

Parameters

FieldInput

Is the same as EasySearch.Input, but lets you search in a specified field. Allows to use multiple indexes.


{{> EasySearch.FieldInput field="name" index=myIndex}}

Parameters

Each

Loops through the found documents if any are found.


{{#EasySearch.Each index=myIndex}}
  <div class="result">{{someField}}</div>
{{/EasySearch.Each}}

IfInputEmpty

Renders the content when the input that’s associated with the index is empty. Allows multiple indexes.


{{#EasySearch.IfInputEmpty index=myIndex}}
  <div>Start searching!</div>
{{/EasySearch.IfInputEmpty}}

Parameters

IfNoResults

Renders the content when there are no results found. Allows multiple indexes.


{{#EasySearch.IfNoResults index=myIndex}}
  <div>No results found!</div>
{{/EasySearch.IfNoResults}}

Parameters

IfSearching

Renders the content when the associated input is being searched. Allows multiple indexes.


{{#EasySearch.IfSearching index=myIndex}}
  <div>Searching...</div>
{{/EasySearch.IfSearching}}

Parameters

LoadMore

Renders a <button> tag that loads more documents if there are more than currently displayed.


{{> EasySearch.LoadMore index=myIndex content="Load more content"}}

Parameters

Pagination

Renders an unordered list that displays pages to navigate through if there are more documents than current displayed.


{{> EasySearch.Pagination index=myIndex maxPages=10}}

Parameters

Retrieving component values

You can retrieve component values, such as the current search string by using the index method getComponentDict.

// Assuming you either use EasySearch.Input or EasySearch.FieldInput inside your app
Template.searchBox.helpers({
  searchCount: () => {
    // index instanceof EasySearch.index
    let dict = index.getComponentDict(/* optional name */)

    // get the total count of search results, useful when displaying additional information
    return dict.get('count')
  }
})

The components use the dictionary themselves to store reactive state. You can retrieve following values through the dictionary.

Using multiple indexes

If you want to work with multiple indexes on your components, you can simply specify indexes instead of index on the component. This is where the logic parameter that each if component has becomes helpful.

import { Index } from 'meteor/easy:search'

const indexOne = new Index({
  ...
})
const indexTwo = new Index({
  ...
})

Template.searchBox.helpers({
  searchIndexes: () => [indexOne, indexTwo],
  indexOne: () => indexOne,
  indexTwo: () => indexTwo,
})

<template name="searchBox">
  {{> EasySearch.Input indexes=searchIndexes }}

  {{#EasySearch.IfNoResults indexes=searchIndexes logic="AND" }}
    <div>No search results found</div>
  {{/EasySearch.IfNoResults}}

  {{#EasySearch.IfSearching indexes=searchIndexes logic="OR" }}
    <div>Indexes are searching...</div>
  {{/EasySearch.IfSearching}}

  {{#EasySearch.Each index=indexOne }}
    ...
  {{/EasySearch.Each}}

  {{#EasySearch.Each index=indexTwo }}
    ...
  {{/EasySearch.Each}}
</template>

This is a basic example using multiple indexes. Note how all components except EasySearch.Each use indexes as it’s parameter. This is because EasySearch.Each does only associate documents of one index, because otherwise there would be some merging logic between different document structure which would be quite nasty. The logic parameter decides how to apply the logic across the given indexes. For example when searching it displays the Indexes are searching… content when one of the indexes searches, whereas the No search results found is only showed when all of the indexes have no results.

Using component methods

Components use component methods that contain the core logic, such as searching with an input and so on. The index method getComponentMethods exposes them as a public Javascript API and makes it possible to add custom logic to your app.

Template.filterBox.events({
  'change select': (e) => {
    // index instanceof EasySearch.index
    index.getComponentMethods(/* optional name */)
      .addProps('countryFilter', $(e.target).val())
  },
})

This code adds a custom property that is called countryFilter and the value of a country code. Everytime somebody executes a search (by either searching through an EasySearch.Input or calling the search method itself with the component methods) this countryFilter prop can be used to filter the searchable documents. See the docs for more information.

Extensibility

The components are written with Blaze Components which offer a great way to re-use functionality by using ES2015 classes and its power of reusability while still keeping the simplicity of Blaze.

Let’s say you want to create a <select> component that sets custom properties when you change an option. With pure blaze you would use the getComponentMethods method that’s on the index.

<template name="MySelectFilter">
    <select>
      <option value="awesome">Awesome</option>
      <option value="not-so-awesome">Not so awesome</option>
    </select>
</template>
Template.MySelectFilter.events({
  'change select': function () {
    // myIndex instanceof EasySearch.Index
    myIndex.getComponentMethods()
      .addProps('awesomeFilter', $(e.target).val().trim())
  },
})

The above example would be useable by just calling {{> MySelectFilter}} in your code. With Blaze Components you could create a component that is useable for every index that supports the awesomeFilter.

class MySelectFilterComponent extends EasySearch.BaseComponent {
  events() {
    return [{
      'change select' : function (e) {
        const selectedValue = $(e.target).val().trim()

        this.eachIndex((index, name) => {
          index.getComponentMethods(name)
            .addProps('awesomeFilter', selectedValue)
        })
      },
    }]
  }
}

MySelectFilterComponent.register('MySelectFilter')

This could be used by calling {{> MySelectFilter index=index}} or with multiple indexes.