package railo.runtime.tag; import java.io.IOException; import java.util.Iterator; import java.util.Map.Entry; import javax.servlet.jsp.tagext.Tag; import railo.commons.lang.HTMLEntities; import railo.runtime.exp.ApplicationException; import railo.runtime.exp.ExpressionException; import railo.runtime.exp.PageException; import railo.runtime.ext.tag.BodyTagImpl; import railo.runtime.op.Caster; import railo.runtime.op.Operator; import railo.runtime.type.Collection.Key; import railo.runtime.type.Struct; import railo.runtime.type.StructImpl; import railo.runtime.type.util.KeyConstants; import railo.runtime.type.util.ListUtil; /** * */ public final class Select extends BodyTagImpl { private static final int QUERY_POSITION_ABOVE = 0; private static final int QUERY_POSITION_BELOW = 1; private railo.runtime.type.Query query; private String[] selected; private String value; private String display; private String passthrough; private Struct attributes=new StructImpl(); private InputBean input=new InputBean(); private boolean editable=false; private int height=-1; private int width=-1; private String label; private boolean visible=true; private String tooltip; private String group; private int queryPosition=QUERY_POSITION_ABOVE; private boolean caseSensitive=false; @Override public void release() { super.release(); query=null; selected=null; value=null; display=null; passthrough=null; editable=false; height=-1; width=-1; label=null; visible=true; tooltip=null; group=null; queryPosition=QUERY_POSITION_ABOVE; caseSensitive=false; attributes.clear(); input=new InputBean(); } /** * @param cssclass The cssclass to set. */ public void setClass(String cssclass) { attributes.setEL("class",cssclass); } /** * @param cssstyle The cssstyle to set. */ public void setStyle(String cssstyle) { attributes.setEL("style",cssstyle); } /** * @param id The id to set. */ public void setId(String id) { attributes.setEL("id",id); } /** * @param multiple The multiple to set. */ public void setMultiple(String multiple) { // alles ausser false ist true if(Caster.toBooleanValue(multiple,true)) attributes.setEL("multiple","multiple"); } /** * @param name The name to set. */ public void setName(String name) { attributes.setEL(KeyConstants._name,name); input.setName(name); } /** * @param size The size to set. */ public void setSize(double size) { attributes.setEL(KeyConstants._size,Caster.toString(size)); } /** * @param tabindex The tabindex to set. */ public void setTabindex(String tabindex) { attributes.setEL("class",tabindex); } /** * @param title The title to set. */ public void setTitle(String title) { attributes.setEL(KeyConstants._title,title); } /** * @param title The title to set. */ public void setDir(String dir) { attributes.setEL("dir",dir); } /** * @param title The title to set. */ public void setLang(String lang) { attributes.setEL("lang",lang); } /** * @param onblur The onblur to set. */ public void setOnblur(String onblur) { attributes.setEL("onblur",onblur); } /** * @param onchange The onchange to set. */ public void setOnchange(String onchange) { attributes.setEL("onchange",onchange); } /** * @param onclick The onclick to set. */ public void setOnclick(String onclick) { attributes.setEL("onclick",onclick); } /** * @param ondblclick The ondblclick to set. */ public void setOndblclick(String ondblclick) { attributes.setEL("ondblclick",ondblclick); } /** * @param onmousedown The onmousedown to set. */ public void setOnmousedown(String onmousedown) { attributes.setEL("onmousedown",onmousedown); } /** * @param ondblclick The ondblclick to set. */ public void setOnmouseup(String onmouseup) { attributes.setEL("onmouseup",onmouseup); } /** * @param ondblclick The ondblclick to set. */ public void setOnmouseover(String onmouseover) { attributes.setEL("onmouseover",onmouseover); } /** * @param ondblclick The ondblclick to set. */ public void setOnmousemove(String onmousemove) { attributes.setEL("onmousemove",onmousemove); } /** * @param ondblclick The ondblclick to set. */ public void setOnmouseout(String onmouseout) { attributes.setEL("onmouseout",onmouseout); } /** * @param ondblclick The ondblclick to set. */ public void setOnkeypress(String onkeypress) { attributes.setEL("onkeypress",onkeypress); } /** * @param ondblclick The ondblclick to set. */ public void setOnkeydown(String onkeydown) { attributes.setEL("onkeydown",onkeydown); } /** * @param ondblclick The ondblclick to set. */ public void setOnkeyup(String onkeyup) { attributes.setEL("onkeyup",onkeyup); } /** * @param onfocus The onfocus to set. */ public void setOnfocus(String onfocus) { attributes.setEL("onfocus",onfocus); } /** * @param message The message to set. */ public void setMessage(String message) { input.setMessage(message); } /** * @param onerror The onerror to set. */ public void setOnerror(String onerror) { input.setOnError(onerror); } /** * @param required The required to set. */ public void setRequired(boolean required) { input.setRequired(required); } /** * @param passthrough The passthrough to set. * @throws PageException */ public void setPassthrough(Object passthrough) throws PageException { if(passthrough instanceof Struct) { Struct sct = (Struct) passthrough; Iterator<Entry<Key, Object>> it = sct.entryIterator(); Entry<Key, Object> e; while(it.hasNext()) { e = it.next(); attributes.setEL(e.getKey(),e.getValue()); } } else this.passthrough = Caster.toString(passthrough); } /** * @param query The query to set. * @throws PageException */ public void setQuery(String strQuery) throws PageException { this.query = Caster.toQuery(pageContext.getVariable(strQuery)); } /** * @param display The display to set. */ public void setDisplay(String display) { this.display = display; } public void setDataformatas(String dataformatas) throws ApplicationException { dataformatas=dataformatas.trim(); String lcDataformatas=dataformatas.toLowerCase(); if( "plaintext".equals(lcDataformatas) || "html".equals(lcDataformatas)) { attributes.setEL("dataformatas",dataformatas); } else throw new ApplicationException("attribute dataformatas for tag input has an invalid value ["+dataformatas+"], valid values are [plaintext, html"); } public void setDatafld(String datafld) { attributes.setEL("datafld",datafld); } public void setDatasrc(String datasrc) { attributes.setEL("datasrc",datasrc); } public void setDisabled(String disabled) { // alles ausser false ist true if(Caster.toBooleanValue(disabled,true)) setDisabled(true); } private void setDisabled(boolean disabled) { if(disabled) attributes.setEL("disabled","disabled"); } /** * @param selected The selected to set. */ public void setSelected(String selected) { this.selected = ListUtil.trimItems(ListUtil.listToStringArray(selected,',')); } /** * @param value The value to set. */ public void setValue(String value) { this.value = value; } @Override public int doStartTag() { return EVAL_BODY_BUFFERED; } @Override public int doEndTag() throws PageException { try { _doEndTag(); return EVAL_PAGE; } catch (IOException e) { throw Caster.toPageException(e); } } private void _doEndTag() throws IOException, ExpressionException, PageException { // check if(query!=null) { if(value==null) throw new ApplicationException("if you have defined attribute query for tag select, you must also define attribute value"); else if(!query.containsKey(value)) throw new ApplicationException("invalid value for attribute [value], there is no column in query with name ["+value+"]"); if(display!=null && !query.containsKey(display)) throw new ApplicationException("invalid value for attribute [display], there is no column in query with name ["+display+"]"); if(group!=null && !query.containsKey(group)) throw new ApplicationException("invalid value for attribute [group], there is no column in query with name ["+group+"]"); } input.setType(Input.TYPE_SELECT); Tag parent=getParent(); while(parent!=null && !(parent instanceof Form)){ parent=parent.getParent(); } if(parent instanceof Form) { Form form = (Form)parent; form.setInput(input); } else { throw new ApplicationException("Tag cfselect must be inside a cfform tag"); } pageContext.forceWrite("<select"); Iterator<Entry<Key, Object>> it = attributes.entryIterator(); Entry<Key, Object> e; while(it.hasNext()) { e = it.next(); pageContext.forceWrite(" "); pageContext.forceWrite(e.getKey().getString()); pageContext.forceWrite("=\""); pageContext.forceWrite(enc(Caster.toString(e.getValue()))); pageContext.forceWrite("\""); } if(passthrough!=null) { pageContext.forceWrite(" "); pageContext.forceWrite(passthrough); } pageContext.forceWrite(">\n"); if(bodyContent!=null && queryPosition==QUERY_POSITION_BELOW)pageContext.forceWrite(bodyContent.getString()); // write query options if(query!=null) { int rowCount=query.getRowCount(); String v,d,currentGroup=null,tmp; boolean hasDisplay=display!=null; boolean hasGroup=group!=null; for(int i=1;i<=rowCount;i++) { v = Caster.toString(query.getAt(value,i)); d = hasDisplay?Caster.toString(query.getAt(display,i)):v; if(hasGroup) { tmp=Caster.toString(query.getAt(group,i)); if(currentGroup==null || !Operator.equals(currentGroup,tmp,true)) { if(currentGroup!=null)pageContext.forceWrite("</optgroup>\n"); pageContext.forceWrite("<optgroup label=\""+tmp+"\">\n"); currentGroup=tmp; } } pageContext.forceWrite("<option"+selected(v,selected)+" value=\""+v+"\">"+d+"</option>\n"); } if(hasGroup)pageContext.forceWrite("</optgroup>\n"); } if(bodyContent!=null && queryPosition==QUERY_POSITION_ABOVE)pageContext.forceWrite(bodyContent.getString()); pageContext.forceWrite("</select>"); } private String selected(String str, String[] selected) { if(selected!=null) { for(int i=0;i<selected.length;i++) { if(caseSensitive) { if(str.compareTo(selected[i])==0) return " selected"; } else { if(Operator.compare(str,selected[i])==0) return " selected"; } //if(Operator.compare(str,selected[i])==0) return " selected"; } } return ""; } /** * html encode a string * @param str string to encode * @return encoded string */ private String enc(String str) { return HTMLEntities.escapeHTML(str,HTMLEntities.HTMLV20); } /** * @param editable the editable to set * @throws ApplicationException */ public void setEditable(boolean editable) { this.editable=editable; } /** * @param group the group to set * @throws ApplicationException */ public void setGroup(String group) { this.group=group; } /** * @param height the height to set * @throws ApplicationException */ public void setHeight(double height) { this.height=(int)height; } /** * @param label the label to set * @throws ApplicationException */ public void setLabel(String label) { this.label=label; } /** * @param queryPosition the queryPosition to set * @throws ApplicationException */ public void setQueryposition(String strQueryPosition) throws ApplicationException { strQueryPosition=strQueryPosition.trim().toLowerCase(); if( "above".equals(strQueryPosition)) queryPosition=QUERY_POSITION_ABOVE; else if( "below".equals(strQueryPosition)) queryPosition=QUERY_POSITION_BELOW; else throw new ApplicationException("attribute queryPosition for tag select has an invalid value ["+strQueryPosition+"], " + "valid values are [above, below]"); } /** * @param tooltip the tooltip to set * @throws ApplicationException */ public void setTooltip(String tooltip) { this.tooltip=tooltip; } /** * @param visible the visible to set * @throws ApplicationException */ public void setVisible(boolean visible) { this.visible=visible; } /** * @param width the width to set * @throws ApplicationException */ public void setWidth(double width) { this.width=(int) width; } /** * @param width the width to set * @throws ApplicationException */ public void setEnabled(String enabled) { setDisabled(!Caster.toBooleanValue(enabled,true)); } /** * @param caseSensitive the caseSensitive to set */ public void setCasesensitive(boolean caseSensitive) { this.caseSensitive = caseSensitive; } }