Setting up the user interface

This page of the Cloud Search tutorial shows how to set up a custom search application using the embeddable search widget. To start from the beginning of this tutorial, refer to Cloud Search getting started tutorial

Installing dependencies

Change your working directory to the cloud-search-samples/end-to-end/search-interface directory and run the following command to download the required dependencies for running the web server:

npm install

Creating the search application credentials

The connector requires service account credentials to call the Cloud Search APIs. To create the credentials:

  1. Go to the Create OAuth client ID page in the developer console.

    Go to the Create OAuth client ID page

  2. Select Web application as the Application type.
  3. Enter tutorial as the Name.
  4. Enter http://localhost:8080 in Authorized JavaScript origins.
  5. Press Create.

Note the Client ID for the newly created client. The value is used to identify the application when requesting user authorization with OAuth2. The secret is not required for this implementation.

Creating the search application

Next, create a search application in the admin console. The search application is a virtual representation of the search interface and it's default configuration.

  1. Go to the search applications page in the admin console.

    Go to the Search applications page

  2. Press the + button.
  3. Enter tutorial as the Display name.
  4. Press Create.
  5. Press Add to create the data source.
  6. Press the pencil icon next to the newly created data source
  7. Press the on the Datasources row.
  8. Find your datasource in the list and press the switch to enable it.
  9. Press display options to select operators for faceting
  10. Check all the displayed operators.
  11. Press Save
  12. Press Done

Note the Application ID for the newly created data source.

Configuring the web application

After creating the credentials and search app, update the application configuration to include these values as follows:

  1. Open the public/app.js file with a text editor
  2. Find the searchConfig variable at the top of the file.
  3. Replace [client-id] with the OAuth client ID created earlier.
  4. Replace [application-id] with the ID of the search application created in the previous section.
  5. Save the file

Running the application

Start the application by running the command:

npm run start

Querying the index

To query the index using the search widget: 1. Open your browser and navigate to http://localhost:8080. 1. Press the Log in button to authorize the app to query Cloud Search on your behalf. 1. Enter a query such as the word 'test' in the search box and press enter. The page shoud display the query results along with facets and pagination controls to navigate the results.

Understanding the code

Loading the widget

The widget and related libraries are loaded in two phases. First, the bootstrap script is loaded:

index.html
<script src="https://apis.google.com/js/api.js?mods=enable_cloud_search_widget&onload=onLoad" async defer></script>

Second, the onLoad callback is called once the script is ready. It then loads the Google API client, Google Sign-in, and the Cloud Search widget libraries.

/**
 * Load the cloud search widget & auth libraries. Runs after
 * the initial gapi bootstrap library is ready.
 */
function onLoad() {
  gapi.load('client:auth2:cloudsearch-widget', initializeApp)
}

The remaining initialization of the app is handled by initializeApp once all the required libraries are loaded.

Handling authorization

Users must authorize the app to query on their behalf. While the widget can prompt users to authorize, you can achieve a better user experience by handling authorization yourself.

For the search interface, the app presents two different views depending on the sign-in state of the user.

index.html
<div class="content">
  <div id="app" hidden>
    <div id="header">
      <button id="sign-out">Sign-out</button>
    </div>
    <!-- Markup for widget...-->
  </div>
  <div id="welcome" hidden>
    <h1>Cloud Search Tutorial</h1>
    <p>Sign in with your Google account to search.</p>
    <button id="sign-in">Sign-in</button>
  </div>
</div>

During initialization the correct view is enabled and the handlers for sign-in and sign-out events are configured:

/**
 * Initialize the app after loading the Google API client &
 * Cloud Search widget.
 */
async function initializeApp() {
  await gapi.auth2.init({
      'clientId': searchConfig.clientId,
      'scope': 'https://www.googleapis.com/auth/cloud_search.query'
  });

  let auth = gapi.auth2.getAuthInstance();

  // Watch for sign in status changes to update the UI appropriately
  let onSignInChanged = (isSignedIn) => {
    document.getElementById("app").hidden = !isSignedIn;
    document.getElementById("welcome").hidden = isSignedIn;
    if (resultsContainer) {
      resultsContainer.clear();
    }
  }
  auth.isSignedIn.listen(onSignInChanged);
  onSignInChanged(auth.isSignedIn.get()); // Trigger with current status

  // Connect sign-in/sign-out buttons
  document.getElementById("sign-in").onclick = (e) =>  auth.signIn();
  document.getElementById("sign-out").onclick = (e) => auth.signOut();

  // ...

}

Creating the search interface

The search widget requires a small amount of HTML markup for the search input and to hold the search results:

index.html
<div id="search_bar">
  <div>
    <div id="suggestions_anchor">
      <input type="text" id="search_input" placeholder="Search for...">
    </div>
  </div>
</div>
<div id="facet_results" ></div>
<div id="search_results" ></div>

The widget is initialized and bound to the input and container elements during initialization:

gapi.config.update('cloudsearch.config/apiVersion', 'v1');
resultsContainer = new gapi.cloudsearch.widget.resultscontainer.Builder()
  .setSearchApplicationId(searchConfig.searchAppId)
  .setSearchResultsContainerElement(document.getElementById('search_results'))
  .setFacetResultsContainerElement(document.getElementById('facet_results'))
  .build();

const searchBox = new gapi.cloudsearch.widget.searchbox.Builder()
  .setSearchApplicationId(searchConfig.searchAppId)
  .setInput(document.getElementById('search_input'))
  .setAnchor(document.getElementById('suggestions_anchor'))
  .setResultsContainer(resultsContainer)
  .build();

Congratulations, you've successfully completed the tutorial! Continue on for clean up instructions.

Previous Next

Send feedback about...

Cloud Search
Cloud Search