ZOFTINO.COM android and web dev tutorials

Search Functionality with JqueryUI & Google App Engine Search

Without search functionality it is very hard for users of your website to find information they are looking for. There are several ways in which search functionality can be implemented. Simple search functionality expects users to enter key words and click search button. Advanced search functionality provides contextual help while user enters text in search text box. To implement search functionality, you need to use back end and ui technologies. In this article I am going to show how to display search results in search text box as context drop down using JQuery UI and Google App engine Search.

Below is the code to index documents using Google App Engine Search API.


	public void indexDocument(String prdId, String category, String prdtitle){
		String INDEX_NAME = "productindex";
		category = category.toLowerCase();
		prdtitle = prdtitle.toLowerCase();
		Document doc = Document.newBuilder()
				.setId(prdId) 
				.addField(Field.newBuilder().setName("cat").setText(category))
				.addField(Field.newBuilder().setName("titl").setText(prdtitle))
				.build();

		IndexSpec indexSpec = IndexSpec.newBuilder().setName(INDEX_NAME).build(); 
		Index index = SearchServiceFactory.getSearchService().getIndex(indexSpec);

		index.put(doc);

	}

Below is the code to find matching documents for user entered search string.


	public List<JSONLabelValue> searchIndex( String searchstring){
		String INDEX_NAME = "productindex";

		IndexSpec indexSpec = IndexSpec.newBuilder().setName(INDEX_NAME).build(); 
		Index index = SearchServiceFactory.getSearchService().getIndex(indexSpec);       

		Results<ScoredDocument> results = index.search(searchstring);

		List<JSONLabelValue> prdlst = new ArrayList<JSONLabelValue>(); 

		for (ScoredDocument doc : results) {
			String titl = doc.getOnlyField("titl").getText();
			String cat = doc.getOnlyField("cat").getText();
			JSONLabelValue prdresult = new JSONLabelValue();
			prdresult.setId(CommonUtils.encryptProdId(doc.getId()));
			prdresult.setLabel(titl);
			prdresult.setValue(CommonUtils.encryptProdId(doc.getId())+"|"+cat+"|"+searchstring);
			prdlst.add(prdresult);
		}
		return prdlst;
	}

Below is the action mapped to search. It gets search results and converts results to Json for UI.

 	@RequestMapping("/search")
	public String search(String st, ModelMap model) {
		List<JSONLabelValue> jsonresults = searchIndex(st);
		model.addAttribute("products", new Gson().toJson(jsonresults));
		return "ajax/search-auto-populate";
	}

Below is the search form

<form id="searchfrm" action="/search" method="post">
<input id="searchinputtext"  name="st" class="frmcntnb input-smsb" length="100"  placeholder="Search for a product">
<input type="hidden" id="searchselect"  name="sl" value="">

<button type="submit" id="searfrmsb">Search</button>
</form>    		 

Ajax call in JqueryUI autocomplete.

  $( "#searchinputtext" ).autocomplete({
  source: function( request, response ) {
	$.ajax({
  	 url: "/search",
 	 dataType: "json",
  	 data: {
   	 st: request.term
  	 },
  	 success: function( data ) {
    	 response( data );
  	 }
	});
  },
  minLength: 3,
  delay: 800,
  select: function( event, ui ) {	
	$("#searchselect").val(ui.item.value);
	$("#searchinputtext").val('');
	event.preventDefault();
    $("#searchfrm").submit();
  },  
  open: function() {
    $(this).autocomplete('widget').zIndex(100000);
  }
  });