Tutorial: Manage the empty state of a widget

Display a list of popular items to the user before any search terms are entered.

Before you begin

Role required: admin or sp_admin

About this task

Because no search has been executed when the widget initializes, the server input variable is undefined. This empty state may cause confusion when a user first interacts with the widget. To solve this issue, give your widget something to display when the input variable is empty. This initial data can guide your users when initially interacting with your widget.

Procedure

  1. From the Widget Editor, open the Quick Order widget.
  2. Replace the existing server script with the following script:
    (function() {
    	if (input.keywords != null && input.keywords != '')
    		data.items = getCatalogItems(input.keywords);
    	else data.items = getPopularItems();
    
    	function getCatalogItems(keywords) {
    		var sc = new GlideRecord('sc_cat_item');
    		sc.addActiveQuery();
    		sc.addQuery('123TEXTQUERY321', keywords);
    		sc.addQuery('sys_class_name', 'NOT IN', 'sc_cat_item_wizard,sc_cat_item_content');
    		sc.addQuery('sc_catalogs', '0d08b13c3330100c8b837659bba8fb4');
    		sc.setLimit(100);
    		sc.orderByDesc("ir_query_score");
    		sc.query();
    		var results = [];
    		while (sc.next()) {
    			if (!$sp.canReadRecord(sc))
    				continue;
    
    			var item = {};
    			$sp.getRecordDisplayValues(item, sc, 'name,price,sys_id');
    			item.category = sc.getValue('category');
    			results.push(item);
    		}
    		return results;
    	}
    	
    	function getPopularItems() {
    		var items = [];
    		var count = new GlideAggregate('sc_req_item');
    		count.addAggregate('COUNT','cat_item');
    		count.groupBy('cat_item');
    		count.addQuery('cat_item.sys_class_name', 'NOT IN', 'sc_cat_item_guide,sc_cat_item_wizard,sc_cat_item_content');
    		count.addQuery('cat_item.sc_catalogs', '0d08b13c3330100c8b837659bba8fb4');
    		count.orderByAggregate('COUNT', 'cat_item');
    		count.query();
    		while (count.next() && items.length < 9) {
    			if (!$sp.canReadRecord("sc_cat_item", count.cat_item.sys_id.getDisplayValue()))
    				continue; // user does not have permission to see this item
    
    			var item = {};
    			item.name = count.cat_item.name.getDisplayValue();
    			item.category = count.cat_item.category.toString();
    			item.price = count.cat_item.price.getDisplayValue();
    			item.sys_id = count.cat_item.sys_id.getDisplayValue();
    			items.push(item);
    		}
    		return items;
    	}
    })();
    

    This script introduces a new function getPopularItems() to query the database and return popular items when the input variable is empty.

  3. Replace the HTML template with the following script:
    <div class="panel panel-primary">
      <div class="panel-heading">Request an item from the catalog</div>
      <div class="panel-body">
        <input class="form-control" type="search" placeholder="Start typing here to search the list of catalog items" ng-model="c.data.keywords" ng-change="c.server.update()" ng-model-options="{debounce: 250}" />
        <h5 ng-if="!c.data.keywords">Showing the most popular items</h5>
        <ul class="list-group result-container">
          <li class="list-group-item" ng-repeat="item in c.data.items">
            <a href>{{item.name}}</a><span class="pull-right">{{item.price}}</span>
          </li>
        </ul>
      </div>
      <div class="panel-footer" ng-if="c.data.keywords">
        <ng-pluralize count="c.data.items.length"
                     when="{'0': 'No items found for ',
                         '1': 'One item matching ',
                         'other': 'Found {} items matching '}">
        </ng-pluralize>
        {{c.data.keywords}}
      </div>
    </div>
    

    This script provides a template to display the popular items returned from the server script.

  4. Refresh your test page preview to view the changes.

    The widget displays popular items to the user prior to any search input.