| 1 19 package org.openbravo.erpCommon.businessUtility; 20 21 import java.io.*; 22 import java.util.Vector ; 23 import javax.servlet.*; 24 import javax.servlet.http.*; 25 import org.openbravo.base.secureApp.*; 26 import org.openbravo.data.FieldProvider; 27 import org.openbravo.erpCommon.utility.*; 28 import org.openbravo.utils.FormatUtilities; 29 import org.openbravo.xmlEngine.XmlDocument; 30 31 32 33 public class Buscador extends HttpSecureAppServlet { 34 35 protected static final int MAX_TEXTBOX_LENGTH=150; 36 protected static final int MAX_TEXTBOX_DISPLAY=30; 37 38 public void init (ServletConfig config) { 39 super.init(config); 40 boolHist = false; 41 } 42 43 public void doPost (HttpServletRequest request, HttpServletResponse response) throws IOException,ServletException { 44 VariablesSecureApp vars = new VariablesSecureApp(request); 45 46 if (vars.commandIn("DEFAULT")) { 47 String strTab = vars.getRequiredStringParameter("inpTabId"); 48 String strWindow = vars.getRequiredStringParameter("inpWindow"); 49 String strWindowId = vars.getStringParameter("inpWindowId"); 50 String strIsSOTrx = vars.getSessionValue(strWindowId + "|issotrxtab"); 51 BuscadorData[] data = BuscadorData.select(this, vars.getLanguage(), strTab); 52 if (data==null || data.length==0) data = BuscadorData.selectIdentifiers(this, vars.getLanguage(), strTab); 53 if (data==null || data.length==0) { 54 if (log4j.isDebugEnabled()) log4j.debug("there're no selection columns and no identifiers defined for this table"); 55 bdError(response,"SearchNothing" ,vars.getLanguage()); 56 } else { 57 data = removeParents(data, strTab); 58 if (loadParameters(vars, data, strTab)) { 59 for (int i=0;i<data.length;i++) { 60 if (data[i].reference.equals("10") || data[i].reference.equals("14") || data[i].reference.equals("34")) data[i].value = "%"; 61 else if (data[i].reference.equals("20")) data[i].value="N"; 62 else data[i].value=""; 63 } 64 } 65 if (data==null || data.length==0) { 66 if (log4j.isDebugEnabled()) log4j.debug("The columns defined were parent keys"); 67 bdError(response,"SearchNothing" ,vars.getLanguage()); 68 } else printPage(response, vars, strTab, data, strWindow, strWindowId, strIsSOTrx); 69 } 70 } else pageError(response); 71 } 72 73 BuscadorData[] removeParents(BuscadorData[] data, String strTab) throws ServletException { 74 String parentColumn = BuscadorData.parentsColumnName(this, strTab); 75 if (data==null || data.length==0) return data; 76 if (parentColumn.equals("")) return data; 77 Vector <Object > vec = new Vector <Object >(); 78 BuscadorData[] result=null; 79 for (int i=0;i<data.length;i++) { 80 if (!parentColumn.equalsIgnoreCase(data[i].columnname) || data[i].isselectioncolumn.equals("Y")) vec.addElement(data[i]); 81 } 82 if (vec.size()>0) { 83 result = new BuscadorData[vec.size()]; 84 vec.copyInto(result); 85 } 86 return result; 87 } 88 89 boolean loadParameters(VariablesSecureApp vars, BuscadorData[] data, String strTab) throws ServletException { 90 if (data==null || data.length==0) return false; 91 boolean isEmpty=true; 92 for (int i=0;i<data.length;i++) { 93 data[i].value = vars.getSessionValue(strTab + "|param" + FormatUtilities.replace(data[i].columnname)); 94 if (!data[i].value.equals("")) isEmpty=false; 95 } 96 return isEmpty; 97 } 98 99 100 void printPage(HttpServletResponse response, VariablesSecureApp vars, String strTab, BuscadorData[] data, String strWindow, String strWindowId, String strIsSOTrx) throws IOException, ServletException { 101 if (log4j.isDebugEnabled()) log4j.debug("Output: Frame 1 of the attributes seeker"); 102 XmlDocument xmlDocument = xmlEngine.readXmlTemplate("org/openbravo/erpCommon/businessUtility/Buscador").createXmlDocument(); 103 104 xmlDocument.setParameter("calendar", vars.getLanguage().substring(0,2)); 105 xmlDocument.setParameter("direction", "var baseDirection = \"" + strReplaceWith + "/\";\n"); 106 xmlDocument.setParameter("language", "LNG_POR_DEFECTO=\"" + vars.getLanguage() + "\";"); 107 StringBuffer script = new StringBuffer (); 108 Vector <StringBuffer > vecScript = new Vector <StringBuffer >(); 109 xmlDocument.setParameter("data", generateHtml(vars, data, strTab, strWindowId, script, strIsSOTrx, vecScript)); 110 xmlDocument.setParameter("scripsJS", vecScript.elementAt(0).toString()); 111 xmlDocument.setParameter("script", (script.toString() + generateScript(data, strWindow, strTab))); 112 xmlDocument.setParameter("tab", strTab); 113 xmlDocument.setParameter("window", strWindow); 114 { 115 OBError myMessage = vars.getMessage(strTab); 116 vars.removeMessage(strTab); 117 if (myMessage!=null) { 118 xmlDocument.setParameter("messageType", myMessage.getType()); 119 xmlDocument.setParameter("messageTitle", myMessage.getTitle()); 120 xmlDocument.setParameter("messageMessage", myMessage.getMessage()); 121 } 122 } 123 response.setContentType("text/html; charset=UTF-8"); 124 PrintWriter out = response.getWriter(); 125 out.println(xmlDocument.print()); 126 out.close(); 127 } 128 129 String generateScript(BuscadorData[] fields, String strWindow, String strTab) { 130 StringBuffer strHtml = new StringBuffer (); 131 StringBuffer strCombo = new StringBuffer (); 132 strHtml.append("function aceptar() {\n"); 133 strHtml.append(" var frm = document.forms[0];\n"); 134 strHtml.append(" var paramsData = new Array();\n"); 135 strHtml.append(" var count = 0;\n"); 136 boolean isHighVolume=false; 137 try { 138 isHighVolume = BuscadorData.isHighVolume(this, strTab).equals("Y"); 139 } catch (ServletException e) { 140 log4j.error(e); 141 } 142 StringBuffer paramsData = new StringBuffer (); 143 StringBuffer params = new StringBuffer (); 144 if (fields!=null && fields.length!=0 && isHighVolume) { 145 strHtml.append("if ("); 146 for (int i=0;i<fields.length;i++) { 147 if (i>0) strHtml.append(" && "); 148 paramsData.append("paramsData[count++] = new Array(\"inpParam").append(FormatUtilities.replace(fields[i].columnname)).append("\" , "); 149 params.append(", \"inpParam").append(FormatUtilities.replace(fields[i].columnname)).append("\","); 150 params.append(" escape("); 151 if (fields[i].reference.equals("20")) { 152 paramsData.append("((radioValue(frm.inpParam").append(FormatUtilities.replace(fields[i].columnname)).append(")!=null)?"); 153 paramsData.append("radioValue(frm.inpParam").append(FormatUtilities.replace(fields[i].columnname)).append("):"); 154 paramsData.append("\"\"));\n"); 155 params.append("((radioValue(frm.inpParam").append(FormatUtilities.replace(fields[i].columnname)).append(")!=null)?"); 156 params.append("radioValue(frm.inpParam").append(FormatUtilities.replace(fields[i].columnname)).append("):"); 157 params.append("\"\")"); 158 } else if (fields[i].reference.equals("17") || fields[i].reference.equals("18") || fields[i].reference.equals("19")) { paramsData.append("((frm.inpParam").append(FormatUtilities.replace(fields[i].columnname)).append(".selectedIndex!=-1)?"); 160 paramsData.append("frm.inpParam").append(FormatUtilities.replace(fields[i].columnname)).append(".options["); 161 paramsData.append("frm.inpParam").append(FormatUtilities.replace(fields[i].columnname)).append(".selectedIndex].value:"); 162 paramsData.append("\"\"));\n"); 163 params.append("((frm.inpParam").append(FormatUtilities.replace(fields[i].columnname)).append(".selectedIndex!=-1)?"); 164 params.append("frm.inpParam").append(FormatUtilities.replace(fields[i].columnname)).append(".options["); 165 params.append("frm.inpParam").append(FormatUtilities.replace(fields[i].columnname)).append(".selectedIndex].value:"); 166 params.append("\"\")"); 167 strCombo.append(" new TypeAheadCombo(\"idParam").append(FormatUtilities.replace(fields[i].columnname)).append("\");\n"); 168 } else if (Utility.isDecimalNumber(fields[i].reference) || Utility.isIntegerNumber(fields[i].reference) || Utility.isDateTime(fields[i].reference)) { 169 paramsData.append("frm.inpParam").append(FormatUtilities.replace(fields[i].columnname)).append(".value").append(");\n"); 170 paramsData.append("paramsData[count++] = new Array(\"inpParam").append(FormatUtilities.replace(fields[i].columnname)).append("_f\", "); 171 paramsData.append("frm.inpParam").append(FormatUtilities.replace(fields[i].columnname)).append("_f.value);\n"); 172 params.append("frm.inpParam").append(FormatUtilities.replace(fields[i].columnname)).append(".value"); 173 params.append("), \"inpParam").append(FormatUtilities.replace(fields[i].columnname)).append("_f\","); 174 params.append(" escape("); 175 params.append("frm.inpParam").append(FormatUtilities.replace(fields[i].columnname)).append("_f.value"); 176 } else { 177 paramsData.append("frm.inpParam").append(FormatUtilities.replace(fields[i].columnname)).append(".value);\n"); 178 params.append("frm.inpParam").append(FormatUtilities.replace(fields[i].columnname)).append(".value"); 179 } 180 params.append(")"); 181 if (fields[i].reference.equals("17") || fields[i].reference.equals("18") || fields[i].reference.equals("19")) { strHtml.append("frm.inpParam").append(FormatUtilities.replace(fields[i].columnname)).append(".selectedIndex!=-1"); 183 } else if (Utility.isDecimalNumber(fields[i].reference) || Utility.isIntegerNumber(fields[i].reference) || Utility.isDateTime(fields[i].reference)) { 184 strHtml.append("(frm.inpParam").append(FormatUtilities.replace(fields[i].columnname)).append(".value==null || "); 185 strHtml.append("frm.inpParam").append(FormatUtilities.replace(fields[i].columnname)).append(".value==\"\") "); 186 strHtml.append("&& (frm.inpParam").append(FormatUtilities.replace(fields[i].columnname)).append("_f.value==null || "); 187 strHtml.append("frm.inpParam").append(FormatUtilities.replace(fields[i].columnname)).append("_f.value==\"\") "); 188 } else { 189 strHtml.append("(frm.inpParam").append(FormatUtilities.replace(fields[i].columnname)).append(".value==null || "); 190 strHtml.append("frm.inpParam").append(FormatUtilities.replace(fields[i].columnname)).append(".value==\"\") "); 191 } 192 } 193 strHtml.append(") {\n"); 194 strHtml.append(" mensaje(1);\n"); 195 strHtml.append(" return false;\n"); 196 strHtml.append(" }\n"); 197 } else if (fields!=null) { 198 for (int i=0;i<fields.length;i++) { 199 paramsData.append("paramsData[count++] = new Array(\"inpParam").append(FormatUtilities.replace(fields[i].columnname)).append("\", "); 200 params.append(", \"inpParam").append(FormatUtilities.replace(fields[i].columnname)).append("\""); 201 params.append(", "); 202 params.append("escape("); 203 if (fields[i].reference.equals("20")) { 204 paramsData.append("((radioValue(frm.inpParam").append(FormatUtilities.replace(fields[i].columnname)).append(")!=null)?"); 205 paramsData.append("radioValue(frm.inpParam").append(FormatUtilities.replace(fields[i].columnname)).append("):"); 206 paramsData.append("\"\"));\n"); 207 params.append("((radioValue(frm.inpParam").append(FormatUtilities.replace(fields[i].columnname)).append(")!=null)?"); 208 params.append("radioValue(frm.inpParam").append(FormatUtilities.replace(fields[i].columnname)).append("):"); 209 params.append("\"\")"); 210 } else if (fields[i].reference.equals("17") || fields[i].reference.equals("18") || fields[i].reference.equals("19")) { 211 paramsData.append("((frm.inpParam").append(FormatUtilities.replace(fields[i].columnname)).append(".selectedIndex!=-1)?"); 212 paramsData.append("frm.inpParam").append(FormatUtilities.replace(fields[i].columnname)).append(".options["); 213 paramsData.append("frm.inpParam").append(FormatUtilities.replace(fields[i].columnname)).append(".selectedIndex].value:"); 214 paramsData.append("\"\"));\n"); 215 params.append("((frm.inpParam").append(FormatUtilities.replace(fields[i].columnname)).append(".selectedIndex!=-1)?"); 216 params.append("frm.inpParam").append(FormatUtilities.replace(fields[i].columnname)).append(".options["); 217 params.append("frm.inpParam").append(FormatUtilities.replace(fields[i].columnname)).append(".selectedIndex].value:"); 218 params.append("\"\")"); 219 strCombo.append(" new TypeAheadCombo(\"idParam").append(FormatUtilities.replace(fields[i].columnname)).append("\");\n"); 220 } else if (Utility.isDecimalNumber(fields[i].reference) || Utility.isIntegerNumber(fields[i].reference) || Utility.isDateTime(fields[i].reference)) { 221 paramsData.append("frm.inpParam").append(FormatUtilities.replace(fields[i].columnname)).append(".value);\n"); 222 paramsData.append("paramsData[count++] = new Array(\"inpParam").append(FormatUtilities.replace(fields[i].columnname)).append("_f\", "); 223 paramsData.append("frm.inpParam").append(FormatUtilities.replace(fields[i].columnname)).append("_f.value);\n"); 224 params.append("frm.inpParam").append(FormatUtilities.replace(fields[i].columnname)).append(".value"); 225 params.append("), \"inpParam").append(FormatUtilities.replace(fields[i].columnname)).append("_f\","); 226 params.append(" escape("); 227 params.append("frm.inpParam").append(FormatUtilities.replace(fields[i].columnname)).append("_f.value"); 228 } else { 229 paramsData.append("frm.inpParam").append(FormatUtilities.replace(fields[i].columnname)).append(".value);\n"); 230 params.append("frm.inpParam").append(FormatUtilities.replace(fields[i].columnname)).append(".value"); 231 } 232 params.append(")"); 233 } 234 } 235 strHtml.append("\n").append(paramsData); 236 strHtml.append(" if (window.opener.selectFilters) window.opener.selectFilters(paramsData);\n"); 237 strHtml.append(" else window.opener.submitFormGetParams(\"SEARCH\", \"../" + strWindow + "\"" + params.toString() + ");\n"); 238 strHtml.append(" window.close();\n"); 239 strHtml.append(" return true;\n"); 240 strHtml.append("}\n"); 241 strHtml.append("function onloadFunctions() {\n"); 242 strHtml.append(strCombo); 243 strHtml.append(" return true;\n"); 244 strHtml.append("}\n"); 245 return strHtml.toString(); 246 } 247 248 String generateHtml(VariablesSecureApp vars, BuscadorData[] fields, String strTab, String strWindow, StringBuffer script, String strIsSOTrx, Vector <StringBuffer > vecScript) throws IOException, ServletException { 249 if (fields==null || fields.length==0) return ""; 250 StringBuffer strHtml = new StringBuffer (); 251 boolean scriptCalendar=false; 252 boolean scriptClock=false; 253 boolean scriptCalculator=false; 254 boolean scriptKeyboard=false; 255 boolean scriptSearch=false; 256 boolean scriptSelect=false; 257 Vector <Object > vecKeys = new Vector <Object >(); 258 for (int i=0;i<fields.length;i++) { 259 if (Integer.valueOf(fields[i].displaylength).intValue()>MAX_TEXTBOX_DISPLAY) fields[i].displaylength=Integer.toString(MAX_TEXTBOX_DISPLAY); 260 strHtml.append("<tr><td class=\"TitleCell\"> <SPAN class=\"LabelText\">"); 261 if (Utility.isDecimalNumber(fields[i].reference) || Utility.isIntegerNumber(fields[i].reference) || Utility.isDateTime(fields[i].reference)) strHtml.append(fields[i].name).append(" ").append(Utility.messageBD(this, "From", vars.getLanguage())); 262 else strHtml.append(fields[i].name); 263 strHtml.append("</SPAN></td>\n"); 264 if (fields[i].reference.equals("17") || fields[i].reference.equals("18") || fields[i].reference.equals("19")) { scriptSelect = true; 266 strHtml.append("<td class=\"Combo_ContentCell\" colspan=\"3\">"); 267 strHtml.append("<select "); 268 strHtml.append("name=\"inpParam").append(FormatUtilities.replace(fields[i].columnname)).append("\" "); 269 strHtml.append("onchange=\"return true; \" id=\"idParam").append(FormatUtilities.replace(fields[i].columnname)).append("\" "); 270 if (Integer.valueOf(fields[i].fieldlength).intValue() < (MAX_TEXTBOX_LENGTH/4)) { 271 strHtml.append("class=\"Combo Combo_OneCell_width\""); 272 } else if (Integer.valueOf(fields[i].fieldlength).intValue() < (MAX_TEXTBOX_LENGTH/2)) { 273 strHtml.append("class=\"Combo Combo_TwoCells_width\""); 274 } else { 275 strHtml.append("class=\"Combo Combo_ThreeCells_width\""); 276 } 277 strHtml.append(">"); 278 strHtml.append("<option value=\"\"></option>\n"); 279 try { 280 ComboTableData comboTableData = new ComboTableData(vars, this, fields[i].reference, fields[i].columnname, fields[i].referencevalue, fields[i].adValRuleId, Utility.getContext(this, vars, "#User_Org", strWindow), Utility.getContext(this, vars, "#User_Client", strWindow), 0); 281 Utility.fillSQLParameters(this, vars, null, comboTableData, strWindow, fields[i].value); 282 FieldProvider[] data = comboTableData.select(false); 283 comboTableData = null; 284 for (int j=0;j<data.length;j++) { 285 strHtml.append("<option value=\""); 286 strHtml.append(data[j].getField("ID")); 287 strHtml.append("\" "); 288 if (data[j].getField("ID").equalsIgnoreCase(fields[i].value)) strHtml.append("selected"); 289 strHtml.append(">"); 290 strHtml.append(data[j].getField("NAME")); 291 strHtml.append("</option>\n"); 292 } 293 } catch (Exception ex) { 294 throw new ServletException(ex); 295 } 296 strHtml.append("</select>\n"); 297 } else if (fields[i].reference.equals("15")) { scriptCalendar = true; 299 strHtml.append("<td class=\"TextBox_btn_ContentCell\">\n"); 300 strHtml.append("<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\" summary=\"\" style=\"padding-top: 0px;\">\n"); 301 strHtml.append("<tr>\n"); 302 strHtml.append("<TD class=\"TextBox_ContentCell\">\n"); 303 strHtml.append("<input dojoType=\"openbravo:DateTextbox\" type=\"text\" class=\"TextBox_btn_OneCell_width\" "); 304 strHtml.append("displayFormat=\"").append(FormatUtilities.replace(vars.getSessionValue("#AD_SqlDateFormat"))).append("\" "); 305 strHtml.append("saveFormat=\"").append(FormatUtilities.replace(vars.getSessionValue("#AD_SqlDateFormat"))).append("\" "); 306 strHtml.append("name=\"inpParam").append(FormatUtilities.replace(fields[i].columnname)).append("\" "); 307 strHtml.append("maxlength=\"").append(fields[i].fieldlength).append("\" "); 308 strHtml.append("value=\"").append(fields[i].value).append("\" "); 309 strHtml.append("id=\"inpParam").append(FormatUtilities.replace(fields[i].columnname)).append("\" "); 310 strHtml.append("onkeyup=\"auto_complete_date(this.textbox);\"></input> "); 311 strHtml.append("<script>djConfig.searchIds.push(\"").append("inpParam").append(FormatUtilities.replace(fields[i].columnname)).append("\") </script>"); 312 strHtml.append("</td>\n"); 313 strHtml.append("<td class=\"FieldButton_ContentCell\">"); 314 strHtml.append("<table class=\"FieldButton\" onclick=\"showCalendar('frmMain.inpParam").append(FormatUtilities.replace(fields[i].columnname)).append("', "); 315 strHtml.append("document.frmMain.inpParam").append(FormatUtilities.replace(fields[i].columnname)).append(".value, false, '").append(FormatUtilities.replace(vars.getSessionValue("#AD_SqlDateFormat"))).append("');"); 316 strHtml.append("return false;\" onmouseout=\"this.className='FieldButton';window.status='';return true;\" onmouseover=\"this.className='FieldButton_hover';window.status='Show Calendar';return true;\" onmousedown=\"this.className='FieldButton_active';return true;\" onmouseup=\"this.className='FieldButton';return true;\">\n");; 317 strHtml.append("<tr>\n"); 318 strHtml.append("<td class=\"FieldButton_bg\">"); 319 strHtml.append("<IMG alt=\"Calendar\" class=\"FieldButton_Icon FieldButton_Icon_Calendar\" title=\"Calendar\" SRC=\"").append(strReplaceWith).append("/images/blank.gif\" border=\"0\"></IMG>\n"); 320 strHtml.append("</td>\n"); 321 strHtml.append("</tr>\n"); 322 strHtml.append("</table>\n"); 323 strHtml.append("</td>\n"); 324 strHtml.append("</tr>\n"); 325 strHtml.append("</table>\n"); 326 strHtml.append("<SPAN class=\"invalid\" style=\"display: none;\">* The value entered is not valid.</SPAN>"); 327 strHtml.append("<SPAN class=\"missing\" style=\"display: none;\">* This value is required.</SPAN>"); 328 strHtml.append("<SPAN class=\"range\" style=\"display: none;\">* This value is out of range.</SPAN>"); 329 strHtml.append("</td>\n"); 330 } else if (fields[i].reference.equals("20")) { strHtml.append("<TD class=\"Radio_Check_ContentCell\">\n"); 332 strHtml.append("<input type=\"checkbox\" value=\"Y\" name=\"inpParam").append(FormatUtilities.replace(fields[i].columnname)).append("\" "); 333 if (fields[i].value.equals("Y")) strHtml.append("checked"); 334 strHtml.append(">\n"); 335 } else if (fields[i].reference.equals("30") || fields[i].reference.equals("21") || fields[i].reference.equals("31") || fields[i].reference.equals("35") || fields[i].reference.equals("25") || fields[i].reference.equals("800011")) { strHtml.append("<td class=\"TextBox_btn_ContentCell\" colspan=\"3\">\n"); 337 strHtml.append("<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\" summary=\"\">\n"); 338 scriptSearch = true; 339 strHtml.append("<TR>\n<TD>\n"); 340 strHtml.append("<input type=\"hidden\" name=\"inpParam").append(FormatUtilities.replace(fields[i].columnname)).append("\" "); 341 strHtml.append("value=\"").append((!fields[i].value.equals("") && !fields[i].value.equals("%"))?fields[i].value:"").append("\">"); 342 strHtml.append("</TD>\n"); 343 strHtml.append("<TD class=\"TextBox_ContentCell\">\n"); 344 if (Integer.valueOf(fields[i].fieldlength).intValue() < (MAX_TEXTBOX_LENGTH/4)) { 345 strHtml.append("<input dojoType=\"openbravo:ValidationTextBox\" type=\"text\" class=\"TextBox_btn_OneCell_width\" "); 346 } else if (Integer.valueOf(fields[i].fieldlength).intValue() < (MAX_TEXTBOX_LENGTH/2)) { 347 strHtml.append("<input dojoType=\"openbravo:ValidationTextBox\" type=\"text\" class=\"TextBox_btn_TwoCells_width\" "); 348 } else { 349 strHtml.append("<input dojoType=\"openbravo:ValidationTextBox\" type=\"text\" class=\"TextBox_btn_ThreeCells_width\" "); 350 } 351 strHtml.append("name=\"inpParam").append(FormatUtilities.replace(fields[i].columnname)).append("_DES\" "); 352 strHtml.append("id=\"inpParam").append(FormatUtilities.replace(fields[i].columnname)).append("_DES\" "); 353 strHtml.append("maxlength=\"").append(fields[i].fieldlength).append("\" "); 354 355 if (!fields[i].value.equals("") && !fields[i].value.equals("%")) { 356 String strSearchTableName = BuscadorData.selectSearchTableName(this, fields[i].referencevalue); 357 if (strSearchTableName.equals("")) strSearchTableName = fields[i].columnname.substring(0,fields[i].columnname.length() - 3); 358 String strSearchName = BuscadorData.selectSearchName(this, strSearchTableName, fields[i].value, vars.getLanguage()); 359 strHtml.append("value=\"").append(strSearchName).append("\" "); 360 } 361 362 strHtml.append((!fields[i].reference.equals("21") && !fields[i].reference.equals("35"))?"":"readonly=\"true\" "); 363 strHtml.append("><script>djConfig.searchIds.push(\"").append("inpParam").append(FormatUtilities.replace(fields[i].columnname)).append("_DES\") </script></td>\n"); 364 String strMethod = ""; 365 if (fields[i].reference.equals("21")) { 366 strMethod = locationCommands(fields[i]); 367 } else if (fields[i].reference.equals("31")) { 368 strMethod = locatorCommands(fields[i], false, strWindow); 369 } else { 370 strMethod = searchsCommand(fields[i], false, strTab, strWindow, strIsSOTrx); 371 } 372 373 strMethod = "new Teclas(\"ENTER\", \"" + strMethod + "\", \"inpParam" + FormatUtilities.replace(fields[i].columnname) + "_DES\", \"null\")"; 374 vecKeys.addElement(strMethod); 375 376 if (fields[i].reference.equals("21")) { 377 strHtml.append(location(fields[i])); 378 } else if (fields[i].reference.equals("31")) { 379 strHtml.append(locator(fields[i], strWindow)); 380 } else { 381 strHtml.append(searchs(fields[i], strTab, strWindow, strIsSOTrx)); 382 } 383 } else if (Utility.isDecimalNumber(fields[i].reference) || Utility.isIntegerNumber(fields[i].reference)) { 384 scriptCalculator = true; 385 if (Utility.isDecimalNumber(fields[i].reference) || Utility.isIntegerNumber(fields[i].reference)) { 386 strHtml.append("<td class=\"TextBox_btn_ContentCell\">\n"); 387 } 388 else { 389 strHtml.append("<td class=\"TextBox_ContentCell\">\n"); 390 } 391 strHtml.append("<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\" summary=\"\" class=\"\">\n"); 392 strHtml.append("<tr>"); 393 strHtml.append("<td class=\"TextBox_ContentCell\">"); 394 strHtml.append("<input type=\"text\" "); 395 strHtml.append("class=\"dojoValidateValid TextBox_btn_OneCell_width\" "); 396 strHtml.append("name=\"inpParam").append(FormatUtilities.replace(fields[i].columnname)).append("\" "); 397 strHtml.append("maxlength=\"").append(fields[i].fieldlength).append("\" "); 398 strHtml.append("value=\"").append(fields[i].value).append("\" "); 399 if (Utility.isDecimalNumber(fields[i].reference)) strHtml.append("onkeydown=\"validateNumberBox(this.id);auto_completar_numero(this, true, true);return true;\" "); 400 else if (Utility.isIntegerNumber(fields[i].reference)) strHtml.append("onkeydown=\"validateNumberBox(this.id);auto_completar_numero(this, false, false);return true;\" "); 401 strHtml.append(">"); 402 if (Utility.isDecimalNumber(fields[i].reference) || Utility.isIntegerNumber(fields[i].reference)) { 403 strHtml.append("<td class=\"FieldButton_ContentCell\">\n<TABLE class=\"FieldButton\" onclick=\"calculator('frmMain."); 404 strHtml.append("inpParam").append(FormatUtilities.replace(fields[i].columnname)).append("', "); 405 strHtml.append("document.frmMain.inpParam").append(FormatUtilities.replace(fields[i].columnname)).append(".value, false);return false;\" "); 406 strHtml.append("onmouseout=\"this.className='FieldButton';window.status='';return true;\" onmouseover=\"this.className='FieldButton_hover';window.status='Show calculator';return true;\" onmousedown=\"this.className='FieldButton_active';return true;\" onmouseup=\"this.className='FieldButton';return true;\">"); 407 strHtml.append("<tr>\n<td class=\"FieldButton_bg\">\n"); 408 strHtml.append("<IMG alt=\"Calculator\" class=\"FieldButton_Icon FieldButton_Icon_Calc\" title=\"Calculator\" SRC=\"").append(strReplaceWith).append("/images/blank.gif\" border=\"0\"></IMG>\n"); 409 strHtml.append("</td>\n</tr>\n</table>\n</td>\n</tr>\n</table>\n"); 410 strHtml.append("<SPAN class=\"invalid\" style=\"display: none;\">* The value entered is not valid.</SPAN>"); 411 strHtml.append("<SPAN class=\"missing\" style=\"display: none;\">* This value is required.</SPAN>"); 412 strHtml.append("<SPAN class=\"range\" style=\"display: none;\">* This value is out of range.</SPAN>"); 413 strHtml.append("</td>"); 414 } 415 } else if ((Integer.valueOf(fields[i].fieldlength).intValue() > MAX_TEXTBOX_LENGTH)) { strHtml.append("<td>"); 417 strHtml.append("<textarea class=\"dojoValidateValid TextArea_TwoCells_width TextArea_Medium_height\" "); 418 strHtml.append("name=\"inpParam").append(FormatUtilities.replace(fields[i].columnname)).append("\" "); 419 strHtml.append("cols=\"50\" rows=\"3\" "); 420 strHtml.append(">"); 421 strHtml.append(fields[i].value); 422 strHtml.append("</textarea>\n"); 423 } else { 424 strHtml.append("<td class=\"TextBox_ContentCell\">"); 425 strHtml.append("<input type=\"text\" class=\"dojoValidateValid TextBox_OneCell_width\" "); 426 strHtml.append("name=\"inpParam").append(FormatUtilities.replace(fields[i].columnname)).append("\" "); 427 strHtml.append("maxlength=\"").append(fields[i].fieldlength).append("\" "); 428 strHtml.append("value=\"").append(fields[i].value).append("\" "); 429 if (Utility.isDecimalNumber(fields[i].reference)) { 430 scriptCalculator = true; 431 strHtml.append("onkeydown=\"auto_completar_numero(this, true, true);return true;\" "); 432 } else if (Utility.isIntegerNumber(fields[i].reference)) { 433 scriptCalculator = true; 434 strHtml.append("onkeydown=\"auto_completar_numero(this, false, false);return true;\" "); 435 } 436 strHtml.append(">"); 437 strHtml.append("</td>"); } 439 440 if (Utility.isDecimalNumber(fields[i].reference) || Utility.isIntegerNumber(fields[i].reference) || Utility.isDateTime(fields[i].reference)) { 441 String value = vars.getSessionValue(strTab + "|param" + FormatUtilities.replace(fields[i].columnname) + "_f"); 442 strHtml.append("<td class=\"TitleCell\"> <SPAN class=\"LabelText\">"); 443 strHtml.append(Utility.messageBD(this, "To", vars.getLanguage())); 444 strHtml.append("</SPAN></td>\n"); 445 446 if (Utility.isDecimalNumber(fields[i].reference) || Utility.isIntegerNumber(fields[i].reference)) { 447 strHtml.append("<td class=\"TextBox_btn_ContentCell\">\n"); 448 strHtml.append("<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\" summary=\"\" class=\"\">\n"); 449 strHtml.append("<tr>"); 450 strHtml.append("<td class=\"TextBox_ContentCell\">"); 451 strHtml.append("<input type=\"text\" "); 452 strHtml.append("class=\"dojoValidateValid TextBox_btn_OneCell_width\" "); 453 strHtml.append("name=\"inpParam").append(FormatUtilities.replace(fields[i].columnname)).append("_f\" "); 454 strHtml.append("maxlength=\"").append(fields[i].fieldlength).append("\" "); 455 strHtml.append("value=\"").append(value).append("\" "); 456 if (Utility.isDecimalNumber(fields[i].reference)) strHtml.append("onkeydown=\"validateNumberBox(this.id);auto_completar_numero(this, true, true);return true;\" "); 457 else if (Utility.isIntegerNumber(fields[i].reference)) strHtml.append("onkeydown=\"validateNumberBox(this.id);auto_completar_numero(this, false, false);return true;\" "); 458 strHtml.append(">"); 459 460 strHtml.append("<td class=\"FieldButton_ContentCell\">\n<TABLE class=\"FieldButton\" onclick=\"calculator('frmMain."); 461 strHtml.append("inpParam").append(FormatUtilities.replace(fields[i].columnname)).append("_f', "); 462 strHtml.append("document.frmMain.inpParam").append(FormatUtilities.replace(fields[i].columnname)).append("_f.value, false);return false;\" "); 463 strHtml.append("onmouseout=\"this.className='FieldButton';window.status='';return true;\" onmouseover=\"this.className='FieldButton_hover';window.status='Show calculator';return true;\" onmousedown=\"this.className='FieldButton_active';return true;\" onmouseup=\"this.className='FieldButton';return true;\">"); 464 strHtml.append("<tr>\n<td class=\"FieldButton_bg\">\n"); 465 strHtml.append("<IMG alt=\"Calculator\" class=\"FieldButton_Icon FieldButton_Icon_Calc\" title=\"Calculator\" SRC=\"").append(strReplaceWith).append("/images/blank.gif\" border=\"0\"></IMG>\n"); 466 strHtml.append("</td>\n</tr>\n</table>\n</td>\n</tr>\n</table>\n"); 467 strHtml.append("<SPAN class=\"invalid\" style=\"display: none;\">* The value entered is not valid.</SPAN>"); 468 strHtml.append("<SPAN class=\"missing\" style=\"display: none;\">* This value is required.</SPAN>"); 469 strHtml.append("<SPAN class=\"range\" style=\"display: none;\">* This value is out of range.</SPAN>"); 470 strHtml.append("</td>"); 471 } else if (fields[i].reference.equals("15")) { strHtml.append("<td class=\"TextBox_btn_ContentCell\">\n"); 473 strHtml.append("<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\" summary=\"\" style=\"padding-top: 0px;\">\n"); 474 strHtml.append("<tr>\n"); 475 strHtml.append("<TD class=\"TextBox_ContentCell\">\n"); 476 strHtml.append("<input dojoType=\"openbravo:DateTextbox\" type=\"text\" class=\"TextBox_btn_OneCell_width\" "); 477 strHtml.append("displayFormat=\"").append(FormatUtilities.replace(vars.getSessionValue("#AD_SqlDateFormat"))).append("\" "); 478 strHtml.append("saveFormat=\"").append(FormatUtilities.replace(vars.getSessionValue("#AD_SqlDateFormat"))).append("\" "); 479 strHtml.append("name=\"inpParam").append(FormatUtilities.replace(fields[i].columnname)).append("_f\" "); 480 strHtml.append("maxlength=\"").append(fields[i].fieldlength).append("\" "); 481 strHtml.append("value=\"").append(value).append("\" "); 482 strHtml.append("id=\"inpParam").append(FormatUtilities.replace(fields[i].columnname)).append("_f\" "); 483 strHtml.append("onkeyup=\"auto_complete_date(this.textbox);\"</input> "); 484 strHtml.append("<script>djConfig.searchIds.push(\"").append("inpParam").append(FormatUtilities.replace(fields[i].columnname)).append("_f\") </script>"); 485 strHtml.append("</td>\n"); 486 strHtml.append("<td class=\"FieldButton_ContentCell\">"); 487 strHtml.append("<table class=\"FieldButton\" onclick=\"showCalendar('frmMain.inpParam").append(FormatUtilities.replace(fields[i].columnname)).append("_f', "); 488 strHtml.append("document.frmMain.inpParam").append(FormatUtilities.replace(fields[i].columnname)).append("_f.value, false, '").append(FormatUtilities.replace(vars.getSessionValue("#AD_SqlDateFormat"))).append("');"); 489 strHtml.append("return false;\" onmouseout=\"this.className='FieldButton';window.status='';return true;\" onmouseover=\"this.className='FieldButton_hover';window.status='Show Calendar';return true;\" onmousedown=\"this.className='FieldButton_active';return true;\" onmouseup=\"this.className='FieldButton';return true;\">\n");; 490 strHtml.append("<tr>\n"); 491 strHtml.append("<td class=\"FieldButton_bg\">"); 492 strHtml.append("<IMG alt=\"Calendar\" class=\"FieldButton_Icon FieldButton_Icon_Calendar\" title=\"Calendar\" SRC=\"").append(strReplaceWith).append("/images/blank.gif\" border=\"0\"></IMG>\n"); 493 strHtml.append("</td>\n"); 494 strHtml.append("</tr>\n"); 495 strHtml.append("</table>\n"); 496 strHtml.append("</td>\n"); 497 strHtml.append("</tr>\n"); 498 strHtml.append("</table>\n"); 499 strHtml.append("<SPAN class=\"invalid\" style=\"display: none;\">* The value entered is not valid.</SPAN>"); 500 strHtml.append("<SPAN class=\"missing\" style=\"display: none;\">* This value is required.</SPAN>"); 501 strHtml.append("<SPAN class=\"range\" style=\"display: none;\">* This value is out of range.</SPAN>"); 502 strHtml.append("</td>\n"); 503 } else { 504 strHtml.append("<input type=\"text\" "); 505 strHtml.append("name=\"inpParam").append(FormatUtilities.replace(fields[i].columnname)).append("_f\" "); 506 strHtml.append(fields[i].fieldlength).append("\" "); 507 strHtml.append("value=\"").append(value).append("\" "); 508 strHtml.append(">"); 509 } 510 } 512 strHtml.append("</td></tr>\n"); 514 } 515 vecKeys.addElement("new Teclas(\"B\", \"aceptar()\", null, \"ctrlKey\")"); 516 vecKeys.addElement("new Teclas(\"ESCAPE\", \"window.close()\", null, null)"); 517 if (vecKeys.size()>0) { 518 script.append("var arrTeclas = new Array();\n"); 519 script.append("function activarTeclas() {\n"); 520 script.append("\n"); 521 for (int i=0;i<vecKeys.size();i++) { 522 script.append("arrTeclas[").append(i).append("] = ").append(vecKeys.elementAt(i).toString()).append(";\n"); 523 } 524 script.append("activarControlTeclas();\n"); 525 script.append("}\n"); 526 } 527 StringBuffer scrScr = new StringBuffer (); 528 if (scriptKeyboard) { 529 scrScr.append("<SCRIPT language=\"JavaScript\" SRC=\"").append(strReplaceWith).append("/js/keyboard.js\" type=\"text/javascript\"></SCRIPT>"); 530 scrScr.append("<SCRIPT language=\"JavaScript\" SRC=\"").append(strReplaceWith).append("/js/keys.js\" type=\"text/javascript\"></SCRIPT>"); 531 } 532 if (scriptClock) { 533 scrScr.append("<SCRIPT language=\"JavaScript\" SRC=\"").append(strReplaceWith).append("/js/time.js\" type=\"text/javascript\"></SCRIPT>"); 534 } 535 if (scriptCalendar) { 536 scrScr.append("<SCRIPT language=\"JavaScript\" SRC=\"").append(strReplaceWith).append("/js/calendar.js\" type=\"text/javascript\"></SCRIPT>\n"); 537 scrScr.append("<SCRIPT language=\"JavaScript\" SRC=\"").append(strReplaceWith).append("/js/lang/calendar-").append(vars.getLanguage().substring(0,2)).append(".js\" type=\"text/javascript\"></SCRIPT>\n"); 538 scrScr.append("<script language=\"JavaScript\" SRC=\"").append(strReplaceWith).append("/js/default/DateTextBox.js\" type=\"text/javascript\"></script>"); 539 } 540 if (scriptCalculator) { 541 scrScr.append("<SCRIPT language=\"JavaScript\" SRC=\"").append(strReplaceWith).append("/js/calculator.js\" type=\"text/javascript\"></SCRIPT>"); 542 } 543 if (scriptSearch) { 544 scrScr.append("<SCRIPT language=\"JavaScript\" SRC=\"").append(strReplaceWith).append("/js/searchs.js\" type=\"text/javascript\"></SCRIPT>"); 545 } 546 if (scriptSelect) { 547 scrScr.append("<SCRIPT language=\"JavaScript\" SRC=\"").append(strReplaceWith).append("/js/String.js\" type=\"text/javascript\"></SCRIPT>"); 548 scrScr.append("<SCRIPT language=\"JavaScript\" SRC=\"").append(strReplaceWith).append("/js/TypeAheadCombo.js\" type=\"text/javascript\"></SCRIPT>"); 549 } 550 vecScript.addElement(scrScr); 551 return strHtml.toString(); 552 } 553 554 public String locationCommands(BuscadorData efd) { 555 StringBuffer html = new StringBuffer (); 556 557 html.append("openLocation(null, null, '../info/Location_FS.html', null, false, 'frmMain', 'inpParam").append(FormatUtilities.replace(efd.columnname)).append("', 'inpParam").append(FormatUtilities.replace(efd.columnname)).append("_DES', document.frmMain.inpParam").append(FormatUtilities.replace(efd.columnname)).append(".value, 'inpwindowId', document.frmMain.inpwindowId.value);"); 558 return html.toString(); 559 } 560 561 public String location(BuscadorData efd) { 562 StringBuffer html = new StringBuffer (); 563 html.append("<td class=\"FieldButton_bg\"><a HREF=\"#\""); 564 html.append("<a HREF=\"#\""); 565 html.append("onClick=\"").append(locationCommands(efd)).append("return false;\" "); 566 html.append("onmouseout=\"this.className='FieldButton';window.status='';return true;\" onmouseover=\"this.className='FieldButton_hover';window.status='Search';return true;\" onmousedown=\"this.className='FieldButton_active';return true;\" onmouseup=\"this.className='FieldButton';return true;\">\n<img width=\"16\" height=\"16\" alt=\"").append(efd.searchname.trim()).append("\" title=\"").append(efd.searchname.trim()).append("\" "); 567 html.append("class=\"FieldButton_Icon FieldButton_Icon_").append(FormatUtilities.replace(efd.searchname.trim())).append("\" ");; 568 html.append("border=\"0\" SRC=\"").append(strReplaceWith).append("/images/blank.gif\"></a>"); 569 return html.toString(); 570 } 571 572 public String searchsCommand(BuscadorData efd, boolean fromButton, String tabId, String windowId, String strIsSOTrx) { 573 StringBuffer params = new StringBuffer (); 574 StringBuffer html = new StringBuffer (); 575 String strMethodName = "openSearch"; 576 if (!fromButton) { 577 params.append(", 'Command'"); 578 params.append(", 'KEY'"); 579 } 580 params.append(", 'WindowID'"); 581 params.append(", '").append(windowId).append("'"); 582 if (!strIsSOTrx.equals("")) { 583 params.append(", 'inpisSOTrxTab'"); 584 params.append(", '").append(strIsSOTrx).append("'"); 585 } 586 String searchName = (efd.reference.equals("25")?"/info/Account":("/info/" + (efd.reference.equals("800011")?"ProductComplete":FormatUtilities.replace(efd.searchname.trim())))) + "_FS.html"; 587 BuscadorData[] data = null; 588 try { 589 data = BuscadorData.selectSearchs(this, "I", efd.referencevalue); 590 } catch (ServletException ex) { 591 ex.printStackTrace(); 592 } 593 if (data!=null && data.length>0) { 594 searchName = data[0].mappingname; 595 } 596 597 if (efd.searchname.toUpperCase().startsWith("ATTRIBUTE")) { 598 strMethodName = "openPAttribute"; 599 params.append(", 'inpKeyValue'"); 600 params.append(", document.frmMain.inpParam").append(FormatUtilities.replace(efd.columnname)).append(".value"); 601 params.append(", 'inpwindowId'"); 602 params.append(", '").append(windowId).append("'"); 603 params.append(", 'inpProduct'"); 604 params.append(", document.frmMain.inpParam").append(FormatUtilities.replace("M_Product_ID")).append(".value"); 605 params.append(", 'inpLocatorId'"); 606 params.append(", ((document.frmMain.inpParam").append(FormatUtilities.replace("M_Locator_ID")); 607 params.append("!=null)?document.frmMain.inpParam"); 608 params.append(FormatUtilities.replace("M_Locator_ID")).append(".value:'')"); 609 } 610 html.append(strMethodName).append("(null, null, '..").append(searchName).append("', null, false, 'frmMain', 'inpParam").append(FormatUtilities.replace(efd.columnname)).append("', 'inpParam").append(FormatUtilities.replace(efd.columnname)).append("_DES', document.frmMain.inpParam").append(FormatUtilities.replace(efd.columnname)).append("_DES.value").append(params.toString()).append(");"); 611 return html.toString(); 612 } 613 614 public String searchs(BuscadorData efd, String tabId, String windowId, String strIsSOTrx) { 615 StringBuffer html = new StringBuffer (); 616 Vector <Object > vec = new Vector <Object >(); 617 if (efd.searchname.toUpperCase().indexOf("BUSINESS")!=-1) { 618 html.append("<input type=\"hidden\" name=\"inpParam").append(FormatUtilities.replace(efd.columnname)).append("_LOC\">\n"); 619 html.append("<input type=\"hidden\" name=\"inpParam").append(FormatUtilities.replace(efd.columnname)).append("_CON\">\n"); 620 } else if (efd.searchname.equalsIgnoreCase("PRODUCT")) { 621 html.append("<input type=\"hidden\" name=\"inpParam").append(FormatUtilities.replace(efd.columnname)).append("_PLIST\">\n"); 622 html.append("<input type=\"hidden\" name=\"inpParam").append(FormatUtilities.replace(efd.columnname)).append("_PSTD\">\n"); 623 html.append("<input type=\"hidden\" name=\"inpParam").append(FormatUtilities.replace(efd.columnname)).append("_UOM\">\n"); 624 html.append("<input type=\"hidden\" name=\"inpParam").append(FormatUtilities.replace(efd.columnname)).append("_PLIM\">\n"); 625 html.append("<input type=\"hidden\" name=\"inpParam").append(FormatUtilities.replace(efd.columnname)).append("_CURR\">\n"); 626 } 627 html.append("<td class=\"FieldButton_bg\"><a HREF=\"#\""); 628 html.append("onClick=\"").append(searchsCommand(efd, true, tabId, windowId, strIsSOTrx)).append("return false;\" "); 629 html.append("onmouseout=\"this.className='FieldButton';window.status='';return true;\" onmouseover=\"this.className='FieldButton_hover';window.status='Search';return true;\" onmousedown=\"this.className='FieldButton_active';return true;\" onmouseup=\"this.className='FieldButton';return true;\">\n<img width=\"16\" height=\"16\" alt=\"").append(efd.searchname.trim()).append("\" title=\"").append(efd.searchname.trim()).append("\" "); 630 html.append("class=\"FieldButton_Icon FieldButton_Icon_").append(FormatUtilities.replace(efd.searchname.trim())).append("\" ");; 631 html.append("border=\"0\" SRC=\"").append(strReplaceWith).append("/images/blank.gif\"></a></td></table>"); 632 return html.toString(); 633 } 634 635 public String locatorCommands(BuscadorData efd, boolean fromButton, String windowId) { 636 StringBuffer params = new StringBuffer (); 637 StringBuffer html = new StringBuffer (); 638 if (!fromButton) { 639 params.append(", 'Command'"); 640 params.append(", 'KEY'"); 641 } 642 params.append(", 'WindowID'"); 643 params.append(", '").append(windowId).append("'"); 644 html.append("openSearch(null, null, '../info/Locator_FS.html', null, false, 'frmMain', 'inpParam").append(FormatUtilities.replace(efd.columnname)).append("', 'inpParam").append(FormatUtilities.replace(efd.columnname)).append("_DES', document.frmMain.inpParam").append(FormatUtilities.replace(efd.columnname)).append("_DES.value").append(params.toString()).append(");"); 645 return html.toString(); 646 } 647 648 public String locator(BuscadorData efd, String windowId) { 649 StringBuffer html = new StringBuffer (); 650 html.append("<td class=\"FieldButton_bg\"><a HREF=\"#\""); 651 html.append("onClick=\"").append(locatorCommands(efd, true, windowId)).append("return false;\" "); 652 html.append("onmouseout=\"this.className='FieldButton';window.status='';return true;\" onmouseover=\"this.className='FieldButton_hover';window.status='Search';return true;\" onmousedown=\"this.className='FieldButton_active';return true;\" onmouseup=\"this.className='FieldButton';return true;\">\n");; 653 html.append("<img width=\"16\" height=\"16\" alt=\"").append(efd.searchname.trim()).append("\" title=\"").append(efd.searchname.trim()).append("\" "); 654 html.append("class=\"FieldButton_Icon FieldButton_Icon_").append(FormatUtilities.replace(efd.searchname.trim())).append("\" ");; 655 html.append("border=\"0\" SRC=\"").append(strReplaceWith).append("/images/blank.gif\"></a></td>"); 656 return html.toString(); 657 } 658 659 public String getServletInfo() { 660 return "Servlet que presenta el buscador"; 661 } } 663 | Popular Tags |