AutoCompleteTag.java
package sk.iway.iwcm.tags;
import static sk.iway.iwcm.Tools.isInteger;
import static sk.iway.iwcm.Tools.isNotEmpty;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyTag;
import org.json.JSONArray;
import net.sourceforge.stripes.exception.StripesJspException;
import net.sourceforge.stripes.tag.FormTag;
import net.sourceforge.stripes.tag.InputTagSupport;
import net.sourceforge.stripes.validation.ValidationMetadata;
/**
* AutoCompleteTag.java
*
* Tag designed to ease creation of tags with auto completing capabilities.
* The generated tag acts as a common input type="text" tag, it shares all the common
* HTML options. Any HTML attribute is passed as-is to the output.
* Attributes affecting auto completing capabilities:
*<p>
* id: DOM id. Passed to jQuery selector to identify the object
*</p><p>
* name: defines parameter name that the receiving script is about to access the search term by means of request.getParameter()
*</p><p>
* url: URL of the receiving script. This URL MAY contain a query string
*</p><p>
* urlParams: used in case we want to alter autocomplete list dynamically based on other values that merely the search term itself.
* Pass them in form of a jQuery selectors separated by comma ','. Do NOT include apostrophes
*</p><p>
* onOptionSelect: a function to post-process a value once it is chosen from the autocomplete list. Two arguments are passed to the function - event and ui.
* ui is an object encapsulating the chosen value. Search term can be accessed by calling 'ui.item.value'. Pass only the function's name, WITHOUT BRACES!
*</p>
*
* The receiving script is expected to return a javascript-compliant array, one that can be easily generated by {@link JSONArray}.toString(). This array is
* passed into javascript's eval() function and is expected to form an array after calling eval().
*
* Referential use: conf_editor_popup.jsp + _conf_autocomplete.jsp
*
* Dependencies:
* jquery.js
* jquery-ui-core.js
* jquery-ui-autocomplete.js
* ajax_support.js
*
*
*@Title webjet7
*@Company Interway s.r.o. (www.interway.sk)
*@Copyright Interway s.r.o. (c) 2001-2010
*@author $Author: marosurbanec $
*@version $Revision: 1.3 $
*@created Date: 14.07.2010 16:19:42
*@modified $Date: 2004/08/16 06:26:11 $
*/
public class AutoCompleteTag extends InputTagSupport implements BodyTag
{
public AutoCompleteTag()
{
getAttributes().put("type", "text");
}
String onOptionSelect;
String urlParams;
String placeholder;
String url;
String value;
String maxRows;
String maxLength;
String minLength;
public String getMinLength()
{
return minLength;
}
public void setMinLength(String minLength)
{
this.minLength = minLength;
}
public String getMaxRows()
{
return maxRows;
}
public void setMaxRows(String maxRows)
{
this.maxRows = maxRows;
}
public String getValue()
{
if (value == null) return "";
return value;
}
public void setValue(String value)
{
this.value = value;
}
public String getUrl()
{
return url;
}
public void setUrl(String url)
{
this.url = url;
}
public String getOnOptionSelect()
{
if (onOptionSelect == null) return "";
return onOptionSelect;
}
public void setOnOptionSelect(String onOptionSelect)
{
this.onOptionSelect = onOptionSelect;
}
public String getUrlParams()
{
if (urlParams == null) return "";
return urlParams;
}
public void setUrlParams(String urlParams)
{
this.urlParams = urlParams;
}
/**
* Inserts an input-text tag with necessary javascript libraries
*/
@Override
public int doEndInputTag() throws JspException
{
getAttributes().put("value", getValue());
getAttributes().put("maxLength", maxLength);
getAttributes().put("placeholder", getPlaceholder());
try
{
JspWriter out = pageContext.getOut();
HttpServletRequest request = (HttpServletRequest)pageContext.getRequest();
set("autocomplete", "off");
//najskor sa muzi sapisat input tag, az potom ostatne JS (aby existoval ked ma)
writeSingletonTag(out, "input");
insertAjaxSupport(out, request);
//unpacked autocomplete is bugged, doesn't work properly (fires off JS error), insert packed version
insertUIcore(out,request);
insertAutoComplete(out, request);
//out.println(jsText());
ReadWriteScriptBean bean = new ReadWriteScriptBean("text/javascript", null, null, null, null, jsBody(), null, null, "AutoCompleteTag.java");
//out.println("<script type='text/javascript' src='/components/_common/javascript/ajax_support.js'></script>");
ReadWriteScriptTag.addScriptFromClass( bean, request, out);
}
catch (IOException e)
{
sk.iway.iwcm.Logger.error(e);
}
return EVAL_PAGE;
}
/**
*
*/
private void insertUIcore(JspWriter out, HttpServletRequest request) throws IOException
{
boolean coreInserted = isNotEmpty( (String)(request.getAttribute("jQueryUI-core-Inserted")) );
request.setAttribute("jQueryUI-core-Inserted", "true");
if(!coreInserted)
{
ReadWriteScriptBean bean = null;
if ("iwcm.interway.sk".equals(request.getServerName()))
{
bean = new ReadWriteScriptBean("text/javascript", "/components/_common/javascript/jqui/jquery-ui-core.js", null, null, null, null, null, null, "AutoCompleteTag.java", null, null);
//out.println("<script type=\"text/javascript\" src=\"/components/_common/javascript/jqui/jquery-ui-core.js\" ></script>");
}
else
{
bean = new ReadWriteScriptBean("text/javascript", "/components/_common/javascript/jqui/jquery-ui-core.min.js", null, null, null, null, null, null, "AutoCompleteTag.java", null, null);
//out.println("<script type=\"text/javascript\" src=\"/components/_common/javascript/jqui/jquery-ui-core.min.js\" ></script>");
}
ReadWriteScriptTag.addScriptFromClass( bean, request, out);
}
}
/**
* Make sure those scripts are present once and only once on a page.
*/
private void insertAutoComplete(JspWriter out, HttpServletRequest request) throws IOException
{
if (request.getAttribute("autocompleteInserted") == null && request.getAttribute("jQueryUI-autocomplete-Inserted") == null && request.getAttribute("jQueryUI-all-Inserted") == null)
{
ReadWriteScriptBean bean = new ReadWriteScriptBean("text/javascript", "/components/_common/javascript/jqui/jquery-ui-autocomplete.min.js", null, null, null, null, null, null, "AutoCompleteTag.java", null, null);
ReadWriteScriptTag.addScriptFromClass( bean, request, out);
//out.println("<script type='text/javascript' src='/components/_common/javascript/jqui/jquery-ui-autocomplete.min.js' ></script>");
}
request.setAttribute("autocompleteInserted", true);
}
private void insertAjaxSupport(JspWriter out, HttpServletRequest request) throws IOException
{
if (request.getAttribute("ajaxSupportInserted") == null)
{
ReadWriteScriptBean bean = new ReadWriteScriptBean("text/javascript", "/components/_common/javascript/ajax_support.js", null, null, null, null, null, null, "AutoCompleteTag.java", null, null);
//out.println("<script type='text/javascript' src='/components/_common/javascript/ajax_support.js'></script>");
ReadWriteScriptTag.addScriptFromClass( bean, request, out);
}
request.setAttribute("ajaxSupportInserted", true);
}
/**
* Utilitises ajax_support.js to create a chained call leading in subscribing a
* function hook to document onReady event.
*/
/*private String jsText()
{
StringBuilder code = new StringBuilder().
append("<script type='text/javascript'>\n").
append("new AutoCompleter('#").
append(getId()).
append("').setUrl('").
append(getUrl()).
append("')");
if (isNotEmpty(urlParams))
code.append(".setParams('").append(urlParams).append("')");
if (isNotEmpty(onOptionSelect))
code.append(".setOnOptionSelect('").append(onOptionSelect).append("')");
if (isInteger(maxRows))
code.append(".setMaxRows(").append(maxRows).append(')');
if (isInteger(minLength))
code.append(".setMinLength(").append(minLength).append(')');
code.append(".transform()\n").append("</script>");
return code.toString();
}*/
private String jsBody()
{
StringBuilder code = new StringBuilder().
//append("<script type='text/javascript'>\n").
append("new AutoCompleter('#").
append(getId()).
append("').setUrl('").
append(getUrl()).
append("')");
if (isNotEmpty(urlParams))
code.append(".setParams('").append(urlParams).append("')");
if (isNotEmpty(onOptionSelect))
code.append(".setOnOptionSelect('").append(onOptionSelect).append("')");
if (isInteger(maxRows))
code.append(".setMaxRows(").append(maxRows).append(')');
if (isInteger(minLength))
code.append(".setMinLength(").append(minLength).append(')');
code.append(".transform()\n");//.append("</script>");
return code.toString();
}
//----------------------TO SHUT UP STRIPES COMPLAINTS--------------------
@Override
public FormTag getParentFormTag() throws StripesJspException{return null;}
@Override
protected ValidationMetadata getValidationMetadata() throws StripesJspException {return new ValidationMetadata("");}
@Override
protected String getLocalizedFieldName(String arg0) throws StripesJspException {return "";}
@Override
protected void registerWithParentForm() throws StripesJspException {
//
}
@Override
protected void loadErrors() throws StripesJspException {
//
}
@Override
public int doStartInputTag() throws JspException
{
return EVAL_BODY_BUFFERED;
}
@Override
public void doInitBody() throws JspException{/*nothing*/}
@Override
public int doAfterBody() throws JspException{return SKIP_BODY;}
public String getPlaceholder()
{
return placeholder;
}
public void setPlaceholder(String placeholder)
{
this.placeholder = placeholder;
}
public String getMaxLength()
{
return maxLength;
}
public void setMaxLength(String maxLength)
{
this.maxLength = maxLength;
}
}