If you are looking for a way to fill a field and perform a live search, in an asynchronous way, look no further.
jQuery autocompleter is a jQuery plugin that performs real-time autocompletion of a text-field.
You need jQuery and the jQuery plugin autocomplete of course.
Let’s suppose we have a text field where the user needs to enter the number of a person id. If the user types 1, all ids starting with 1 will show up. If the user types 12, all ids starting with 12 will show up.
Here is the code I wrote to asynchronously call a method that will perform a JPQL request in a database whenever the user types a digit in the text field.
First, the main JSP, search.jsp :
<%-- jQuery Libraries--%> <script type="text/javascript" src="ressources/js/jquery-1.4.2.min.js"></script> <script type="text/javascript" src="ressources/js/jquery-autocomplete/lib/jquery.bgiframe.min.js"></script> <script type="text/javascript" src="ressources/js/jquery-autocomplete/lib/jquery.ajaxQueue.js"></script> <script type="text/javascript" src="ressources/js/jquery-autocomplete/lib/thickbox-compressed.js"></script> <script type="text/javascript" src="ressources/js/jquery-autocomplete/jquery.autocomplete.js"></script> <link href="ressources/js/jquery-autocomplete/jquery.autocomplete.css" rel="stylesheet" type="text/css" /> <script type="text/javascript"> $().ready(function() { $("#tag").autocomplete('myWebApp/listPersonsId.action', { minChars: 1, max: 15, multiple: false, autoFill: true }); }); </script> ... <td><s:textfield id='tag' name="tagField" label="tag" /></td>
Then the second JSP, tag.jsp, that will hold the content of the list that will show beneath the text field :
tag.jsp : <%@ taglib prefix="s" uri="/struts-tags"%> <s:iterator value="listPersons"> <s:property value="id" escape="false"/> </s:iterator>
The struts mapping file search.xml :
<!-- This action is used to autocomplete the textfield person id --> <action name="listPersonsId" method="findTag"> <result name="success">/pages/search/tag.jsp</result> </action>
I have a Person entity bean (with an ID field) and a stateless session bean PersonDAO with a allPersonsById(long PersonId) method :
@SuppressWarnings("unchecked") public List<Person> allPersonsById(long PersonId) { String param = String.valueOf(PersonId); param = PersonId + "%"; Query reqPosition = entityManager.createQuery("select p from Person p where TRIM(p.id) like ?1"); reqPosition.setParameter(1, param); List<Person> listPersons = reqPosition.getResultList(); return listPersons; }
Pay special attention to the JPQL request. I have to use the TRIM function because the column ID is a number while the parameter is a String.
Different types throw an exception. TRIM avoids that exception.
Finally here is the Struts 2 action,
SearchAction.java:
public class SearchAction extends ActionSupport { //q is a parameter used by the jQuery autocomplete.js script private String q; public String getQ() { return q; } public void setQ(String q) { this.q = q; } // This list will be updated every time the user enters a new digit public List<Person> listPersons; public List<Person> getListPersons() { return listPersons; } public void setListPersons(List<Person> listPersons) { this.listPersons = listPersons; } public String findTag() throws Exception { String qUTF8 = ""; if (null !=q ){ try { qUTF8 = new String(q.getBytes(), "UTF8"); } catch (UnsupportedEncodingException e) { log.error(e.getMessage(), e); } } PersonDaoLocal facade = (PersonDaoLocal) ServiceLocator.getInstance().getService("myWebApp/PersonDao/local"); long personId = Long.valueOf(q);; listPersons = facade.allPersonsById(personId); return SUCCESS; } }
When a user starts typing in the input box, the autocompleter will request myWebApp/listPersonsId.action with a GET parameter named q that contains the current value of the input box.
Check the plugin documentation for more options.
You must be logged in to post a comment.