001 package railo.runtime.tag; 002 003 import java.io.IOException; 004 005 import javax.servlet.jsp.tagext.Tag; 006 007 import railo.commons.lang.HTMLEntities; 008 import railo.runtime.exp.ApplicationException; 009 import railo.runtime.exp.ExpressionException; 010 import railo.runtime.exp.PageException; 011 import railo.runtime.ext.tag.BodyTagImpl; 012 import railo.runtime.op.Caster; 013 import railo.runtime.op.Operator; 014 import railo.runtime.type.KeyImpl; 015 import railo.runtime.type.List; 016 import railo.runtime.type.Struct; 017 import railo.runtime.type.StructImpl; 018 019 /** 020 * 021 */ 022 public final class Select extends BodyTagImpl { 023 024 private static final int QUERY_POSITION_ABOVE = 0; 025 private static final int QUERY_POSITION_BELOW = 1; 026 private railo.runtime.type.Query query; 027 private String[] selected; 028 private String value; 029 private String display; 030 private String passthrough; 031 032 033 034 private Struct attributes=new StructImpl(); 035 private InputBean input=new InputBean(); 036 private boolean editable=false; 037 private int height=-1; 038 private int width=-1; 039 private String label; 040 private boolean visible=true; 041 private String tooltip; 042 private String group; 043 private int queryPosition=QUERY_POSITION_ABOVE; 044 private boolean caseSensitive=false; 045 046 047 /** 048 * @see javax.servlet.jsp.tagext.Tag#release() 049 */ 050 public void release() { 051 super.release(); 052 query=null; 053 selected=null; 054 value=null; 055 display=null; 056 passthrough=null; 057 editable=false; 058 height=-1; 059 width=-1; 060 label=null; 061 visible=true; 062 tooltip=null; 063 group=null; 064 queryPosition=QUERY_POSITION_ABOVE; 065 caseSensitive=false; 066 attributes.clear(); 067 input=new InputBean(); 068 } 069 070 /** 071 * @param cssclass The cssclass to set. 072 */ 073 public void setClass(String cssclass) { 074 attributes.setEL("class",cssclass); 075 } 076 /** 077 * @param cssstyle The cssstyle to set. 078 */ 079 public void setStyle(String cssstyle) { 080 attributes.setEL("style",cssstyle); 081 } 082 /** 083 * @param id The id to set. 084 */ 085 public void setId(String id) { 086 attributes.setEL("id",id); 087 } 088 /** 089 * @param multiple The multiple to set. 090 */ 091 public void setMultiple(String multiple) { 092 // alles ausser false ist true 093 if(Caster.toBooleanValue(multiple,true)) attributes.setEL("multiple","multiple"); 094 } 095 /** 096 * @param name The name to set. 097 */ 098 public void setName(String name) { 099 attributes.setEL(KeyImpl.NAME,name); 100 input.setName(name); 101 } 102 /** 103 * @param size The size to set. 104 */ 105 public void setSize(double size) { 106 attributes.setEL(KeyImpl.SIZE,Caster.toString(size)); 107 } 108 /** 109 * @param tabindex The tabindex to set. 110 */ 111 public void setTabindex(String tabindex) { 112 attributes.setEL("class",tabindex); 113 } 114 /** 115 * @param title The title to set. 116 */ 117 public void setTitle(String title) { 118 attributes.setEL(KeyImpl.TITLE,title); 119 } 120 /** 121 * @param title The title to set. 122 */ 123 public void setDir(String dir) { 124 attributes.setEL("dir",dir); 125 } 126 /** 127 * @param title The title to set. 128 */ 129 public void setLang(String lang) { 130 attributes.setEL("lang",lang); 131 } 132 /** 133 * @param onblur The onblur to set. 134 */ 135 public void setOnblur(String onblur) { 136 attributes.setEL("onblur",onblur); 137 } 138 /** 139 * @param onchange The onchange to set. 140 */ 141 public void setOnchange(String onchange) { 142 attributes.setEL("onchange",onchange); 143 } 144 /** 145 * @param onclick The onclick to set. 146 */ 147 public void setOnclick(String onclick) { 148 attributes.setEL("onclick",onclick); 149 } 150 /** 151 * @param ondblclick The ondblclick to set. 152 */ 153 public void setOndblclick(String ondblclick) { 154 attributes.setEL("ondblclick",ondblclick); 155 } 156 /** 157 * @param onmousedown The onmousedown to set. 158 */ 159 public void setOnmousedown(String onmousedown) { 160 attributes.setEL("onmousedown",onmousedown); 161 } 162 /** 163 * @param ondblclick The ondblclick to set. 164 */ 165 public void setOnmouseup(String onmouseup) { 166 attributes.setEL("onmouseup",onmouseup); 167 } 168 /** 169 * @param ondblclick The ondblclick to set. 170 */ 171 public void setOnmouseover(String onmouseover) { 172 attributes.setEL("onmouseover",onmouseover); 173 } 174 /** 175 * @param ondblclick The ondblclick to set. 176 */ 177 public void setOnmousemove(String onmousemove) { 178 attributes.setEL("onmousemove",onmousemove); 179 } 180 /** 181 * @param ondblclick The ondblclick to set. 182 */ 183 public void setOnmouseout(String onmouseout) { 184 attributes.setEL("onmouseout",onmouseout); 185 } 186 /** 187 * @param ondblclick The ondblclick to set. 188 */ 189 public void setOnkeypress(String onkeypress) { 190 attributes.setEL("onkeypress",onkeypress); 191 } 192 /** 193 * @param ondblclick The ondblclick to set. 194 */ 195 public void setOnkeydown(String onkeydown) { 196 attributes.setEL("onkeydown",onkeydown); 197 } 198 /** 199 * @param ondblclick The ondblclick to set. 200 */ 201 public void setOnkeyup(String onkeyup) { 202 attributes.setEL("onkeyup",onkeyup); 203 } 204 /** 205 * @param onfocus The onfocus to set. 206 */ 207 public void setOnfocus(String onfocus) { 208 attributes.setEL("onfocus",onfocus); 209 } 210 211 /** 212 * @param message The message to set. 213 */ 214 public void setMessage(String message) { 215 input.setMessage(message); 216 } 217 /** 218 * @param onerror The onerror to set. 219 */ 220 public void setOnerror(String onerror) { 221 input.setOnError(onerror); 222 } 223 /** 224 * @param required The required to set. 225 */ 226 public void setRequired(boolean required) { 227 input.setRequired(required); 228 } 229 /** 230 * @param passthrough The passthrough to set. 231 * @throws PageException 232 */ 233 public void setPassthrough(Object passthrough) throws PageException { 234 if(passthrough instanceof Struct) { 235 Struct sct = (Struct) passthrough; 236 railo.runtime.type.Collection.Key[] keys=sct.keys(); 237 railo.runtime.type.Collection.Key key; 238 for(int i=0;i<keys.length;i++) { 239 key=keys[i]; 240 attributes.setEL(key,sct.get(key,null)); 241 } 242 } 243 else this.passthrough = Caster.toString(passthrough); 244 } 245 /** 246 * @param query The query to set. 247 * @throws PageException 248 */ 249 public void setQuery(String strQuery) throws PageException { 250 this.query = Caster.toQuery(pageContext.getVariable(strQuery)); 251 } 252 /** 253 * @param display The display to set. 254 */ 255 public void setDisplay(String display) { 256 this.display = display; 257 } 258 259 public void setDataformatas(String dataformatas) throws ApplicationException { 260 dataformatas=dataformatas.trim(); 261 String lcDataformatas=dataformatas.toLowerCase(); 262 if( "plaintext".equals(lcDataformatas) || 263 "html".equals(lcDataformatas)) { 264 attributes.setEL("dataformatas",dataformatas); 265 } 266 else 267 throw new ApplicationException("attribute dataformatas for tag input has a invalid value ["+dataformatas+"], valid values are [plaintext, html"); 268 } 269 270 public void setDatafld(String datafld) { 271 attributes.setEL("datafld",datafld); 272 } 273 274 public void setDatasrc(String datasrc) { 275 attributes.setEL("datasrc",datasrc); 276 } 277 278 public void setDisabled(String disabled) { 279 // alles ausser false ist true 280 if(Caster.toBooleanValue(disabled,true)) setDisabled(true); 281 } 282 283 private void setDisabled(boolean disabled) { 284 if(disabled) attributes.setEL("disabled","disabled"); 285 } 286 287 /** 288 * @param selected The selected to set. 289 */ 290 public void setSelected(String selected) { 291 this.selected = List.trimItems(List.listToStringArray(selected,',')); 292 } 293 /** 294 * @param value The value to set. 295 */ 296 public void setValue(String value) { 297 this.value = value; 298 } 299 300 /** 301 * @see javax.servlet.jsp.tagext.Tag#doStartTag() 302 */ 303 public int doStartTag() { 304 return EVAL_BODY_BUFFERED; 305 } 306 307 /** 308 * @see javax.servlet.jsp.tagext.Tag#doStartTag() 309 */ 310 public int doEndTag() throws PageException { 311 try { 312 _doEndTag(); 313 return EVAL_PAGE; 314 } catch (IOException e) { 315 throw Caster.toPageException(e); 316 } 317 } 318 319 320 private void _doEndTag() throws IOException, ExpressionException, PageException { 321 322 // check 323 if(query!=null) { 324 if(value==null) 325 throw new ApplicationException("if you have defined attribute query for tag select, you must also define attribute value"); 326 else if(!query.containsKey(value)) 327 throw new ApplicationException("invalid value for attribute [value], there is no column in query with name ["+value+"]"); 328 329 if(display!=null && !query.containsKey(display)) 330 throw new ApplicationException("invalid value for attribute [display], there is no column in query with name ["+display+"]"); 331 332 if(group!=null && !query.containsKey(group)) 333 throw new ApplicationException("invalid value for attribute [group], there is no column in query with name ["+group+"]"); 334 } 335 336 input.setType(Input.TYPE_SELECT); 337 Tag parent=getParent(); 338 while(parent!=null && !(parent instanceof Form)){ 339 parent=parent.getParent(); 340 } 341 if(parent instanceof Form) { 342 Form form = (Form)parent; 343 form.setInput(input); 344 } 345 else { 346 throw new ApplicationException("Tag cfselect must be inside a cfform tag"); 347 } 348 349 350 pageContext.forceWrite("<select"); 351 352 railo.runtime.type.Collection.Key[] keys = attributes.keys(); 353 railo.runtime.type.Collection.Key key; 354 for(int i=0;i<keys.length;i++) { 355 key = keys[i]; 356 pageContext.forceWrite(" "); 357 pageContext.forceWrite(key.getString()); 358 pageContext.forceWrite("=\""); 359 pageContext.forceWrite(enc(Caster.toString(attributes.get(key,null)))); 360 pageContext.forceWrite("\""); 361 } 362 363 if(passthrough!=null) { 364 pageContext.forceWrite(" "); 365 pageContext.forceWrite(passthrough); 366 } 367 pageContext.forceWrite(">\n"); 368 369 370 if(bodyContent!=null && queryPosition==QUERY_POSITION_BELOW)pageContext.forceWrite(bodyContent.getString()); 371 372 // write query options 373 if(query!=null) { 374 int rowCount=query.getRowCount(); 375 String v,d,currentGroup=null,tmp; 376 boolean hasDisplay=display!=null; 377 boolean hasGroup=group!=null; 378 379 for(int i=1;i<=rowCount;i++) { 380 v = Caster.toString(query.getAt(value,i)); 381 d = hasDisplay?Caster.toString(query.getAt(display,i)):v; 382 if(hasGroup) { 383 tmp=Caster.toString(query.getAt(group,i)); 384 if(currentGroup==null || !Operator.equals(currentGroup,tmp,true)) { 385 if(currentGroup!=null)pageContext.forceWrite("</optgroup>\n"); 386 pageContext.forceWrite("<optgroup label=\""+tmp+"\">\n "); 387 currentGroup=tmp; 388 } 389 } 390 pageContext.forceWrite("<option"+selected(v,selected)+" value=\""+v+"\">"+d+"</option>\n"); 391 } 392 if(hasGroup)pageContext.forceWrite("</optgroup>\n"); 393 } 394 395 if(bodyContent!=null && queryPosition==QUERY_POSITION_ABOVE)pageContext.forceWrite(bodyContent.getString()); 396 pageContext.forceWrite("</select>"); 397 398 399 400 401 } 402 403 private String selected(String str, String[] selected) { 404 if(selected!=null) { 405 for(int i=0;i<selected.length;i++) { 406 if(caseSensitive) { 407 if(str.compareTo(selected[i])==0) return " selected"; 408 } 409 else { 410 if(Operator.compare(str,selected[i])==0) return " selected"; 411 } 412 //if(Operator.compare(str,selected[i])==0) return " selected"; 413 } 414 } 415 return ""; 416 } 417 418 419 420 /** 421 * html encode a string 422 * @param str string to encode 423 * @return encoded string 424 */ 425 private String enc(String str) { 426 return HTMLEntities.escapeHTML(str,HTMLEntities.HTMLV20); 427 } 428 429 /** 430 * @param editable the editable to set 431 * @throws ApplicationException 432 */ 433 public void setEditable(boolean editable) { 434 this.editable=editable; 435 } 436 437 /** 438 * @param group the group to set 439 * @throws ApplicationException 440 */ 441 public void setGroup(String group) { 442 this.group=group; 443 } 444 445 /** 446 * @param height the height to set 447 * @throws ApplicationException 448 */ 449 public void setHeight(double height) { 450 this.height=(int)height; 451 } 452 453 /** 454 * @param label the label to set 455 * @throws ApplicationException 456 */ 457 public void setLabel(String label) { 458 this.label=label; 459 } 460 461 /** 462 * @param queryPosition the queryPosition to set 463 * @throws ApplicationException 464 */ 465 public void setQueryposition(String strQueryPosition) throws ApplicationException { 466 strQueryPosition=strQueryPosition.trim().toLowerCase(); 467 if( "above".equals(strQueryPosition)) queryPosition=QUERY_POSITION_ABOVE; 468 else if( "below".equals(strQueryPosition)) queryPosition=QUERY_POSITION_BELOW; 469 else 470 throw new ApplicationException("attribute queryPosition for tag select has a invalid value ["+strQueryPosition+"], " + 471 "valid values are [above, below]"); 472 473 } 474 475 /** 476 * @param tooltip the tooltip to set 477 * @throws ApplicationException 478 */ 479 public void setTooltip(String tooltip) { 480 this.tooltip=tooltip; 481 } 482 483 /** 484 * @param visible the visible to set 485 * @throws ApplicationException 486 */ 487 public void setVisible(boolean visible) { 488 this.visible=visible; 489 } 490 491 /** 492 * @param width the width to set 493 * @throws ApplicationException 494 */ 495 public void setWidth(double width) { 496 this.width=(int) width; 497 } 498 /** 499 * @param width the width to set 500 * @throws ApplicationException 501 */ 502 public void setEnabled(String enabled) { 503 setDisabled(!Caster.toBooleanValue(enabled,true)); 504 } 505 506 /** 507 * @param caseSensitive the caseSensitive to set 508 */ 509 public void setCasesensitive(boolean caseSensitive) { 510 this.caseSensitive = caseSensitive; 511 } 512 }