Tutorial: Getting started

Getting started

Basic usage

Invenio-Search-Js help you easily display results from the Invenio REST API.

The angular module has been split in different directives which each one is responsible for a specific action on the app.

Initialize the app

<script src="path/to/angular.js"></script>
<script src="path/to/invenio-search-js.js"></script>
<script>
  // Bootstrap the angular app to the specific `div` with id `search`
  angular.element(document).ready(function() {
    angular.bootstrap(
      document.getElementById("search"), ['invenioSearch']
    );
  });
</script>

Example only with only search results

We have the following API and we'd like to display the results with the invenio-search-js.

$ curl /api/super/cities

{
  hits: {
    total: 2
  },
  data: [
    {
      "name": "Harley Quinn",
      "city": "Midway"
    },
    {
      "name": "Jessica Jones",
      "city": "New York"
    }
  ]
}

For this example we'll use the <invenio-search-results> directive for displaying the results.

<div id="search">
  <invenio-search search-endpoint="/api/super/cities">
    <invenio-search-results template="results.html"></invenio-search-results>
  </invenio-search>
</div>

The results.html will look like this:

<ul>
  <li ng-repeat="hero in vm.invenioSearchResults.data track by $index">
    <h5>{{ hero.name }}</h5>
    <p>{{ hero.city }}</p>
  </li>
</ul>

Note: the vm.invenioSearchResults contains the response of the API hence we use vm.invenioSearchResults.data to iterate the results.

A more complex example

We have the following API and we'd like to display the results with the invenio-search-js and include number of results, pagination and loading message.

$ curl /api/super/cities

{
  hits: {
    total: 6
  },
  data: [
    {
      "name": "Harley Quinn",
      "city": "Midway"
    },
    {
      "name": "Jessica Jones",
      "city": "New York"
    },
    {
      "name": "Luke Cage",
      "city": "New York"
    },
    {
      "name": "Batman",
      "city": "Gotham"
    },
    {
      "name": "Iron Man",
      "city": "New York"
    },
    {
      "name": "Flash",
      "city": "Central"
    }
  ]
}
<div id="search">
  <invenio-search search-endpoint="/api/super/cities">
    <!-- search bar -->
    <invenio-search-bar template="searchBar.html" placeholder="Start typing"></invenio-search-bar>
    <!-- number of results -->
    <invenio-search-count template="count.html"></invenio-search-count>
    <!-- loading message -->
    <invenio-search-loading template="loading.html" message="Loading"></invenio-search-loading>
    <!-- search results -->
    <invenio-search-results template="results.html"></invenio-search-results>
    <!-- search pagination -->
    <invenio-search-pagination template="pagination.html"></invenio-search-pagination>
  </invenio-search>
</div>

searchBar.html

<input placeholder="{{ placeholder }}" ng-model="vm.userQuery" />

Note: ng-model="vm.userQuery" is important for mapping the user input to the application.

Also the request parameter for search will always be q. For example if user types Harley the API request will be GET /api/super/cities/?q=Harley

count.html

<p>{{ vm.invenioSearchResults.hits.total }}</p>

Note: vm.invenioSearchResults.hits.total is returned by the server.

loading.html

<div ng-show="vm.invenioSearchLoading">{{ loadingMessage }}</div>

You have access to vm.invenioSearchLoading which indicates if there is any ongoing request, you can use it in any template inside the app.

results.html

<ul>
  <li ng-repeat="hero in vm.invenioSearchResults.data track by $index">
    <h5>{{ hero.name }}</h5>
    <p>{{ hero.city }}</p>
  </li>
</ul>

Note: the vm.invenioSearchResults contains the response of the API hence we use vm.invenioSearchResults.data to iterate the results.

pagination.html

<ul class="pagination" ng-if="vm.invenioSearchResults.hits.total">
  <li ng-show="showGoToFirstLast" ng-class="paginationHelper.getFirstClass()">
    <a href="#" ng-click="paginationHelper.changePage(1)" aria-label="First">
      <span aria-hidden="true"><<<span>
    </a>
  </li>
  <li ng-class="paginationHelper.getPrevClass()">
    <a href="#" ng-click="paginationHelper.changePage(paginationHelper.previous())" aria-label="Previous">
      <span aria-hidden="true"><</span>
    </a>
  </li>
  <li ng-class="paginationHelper.getPageClass(page.value)" ng-repeat="page in paginatePages">
    <a href="#" ng-click="paginationHelper.changePage(page.value)" alt="{{ page.title }}">{{ page.value }}</a>
  </li>
  <li ng-class="paginationHelper.getNextClass()">
    <a href="#" ng-click="paginationHelper.changePage(paginationHelper.next())" aria-label="Next">
      <span aria-hidden="true">></span>
    </a>
  </li>
  <li ng-show="showGoToFirstLast" ng-class="paginationHelper.getLastClass()">
    <a href="#" ng-click="paginationHelper.changePage(paginationHelper.total())" aria-label="Last">
      <span aria-hidden="true">>></span>
    </a>
  </li>
</ul>

The app provides for pagination helper functions.