
com.viaoa.jsp.OATextField Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of oa-web Show documentation
Show all versions of oa-web Show documentation
Object Automation Web library
/* Copyright 1999 Vince Via [email protected]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.viaoa.jsp;
import java.lang.reflect.Method;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.viaoa.ds.OADataSource;
import com.viaoa.hub.Hub;
import com.viaoa.object.*;
import com.viaoa.util.*;
/**
* Controls an html input type=text, bind to OA hub, using property path set size, maxwidth show/hide,
* that can be bound to property enabled, that can be bound to property ajax submit on change handle
* required validation input mask support for calendar popup
*
* For datetime, date, time formats - use OADateTime formats.
*
* @author vvia
*/
public class OATextField implements OAJspComponent, OATableEditor, OAJspRequirementsInterface {
private static final long serialVersionUID = 1L;
private static Logger LOG = Logger.getLogger(OATextField.class.getName());
protected Hub hub;
protected String id;
protected String propertyPath;
protected boolean bPropertyPathIsManyLink;
protected boolean bPropertyPathIsOneLink;
protected String visiblePropertyPath;
protected String enablePropertyPath;
protected int width, minLength, maxLength;
protected OAForm form;
protected boolean bEnabled = true;
protected boolean bVisible = true;
protected boolean bAjaxSubmit, bSubmit;
protected String inputMask;
protected boolean required;
protected String value;
protected String lastValue;
protected boolean bIsDate, bIsTime, bIsDateTime;
protected String regex;
private boolean bFocus;
protected String forwardUrl;
protected boolean bAutoComplete; // using jquery
protected char conversion; // 'U'pper, 'L'ower, 'T'itle, 'P'assword
protected boolean bMultiValue;
protected OATypeAhead typeAhead;
private String name;
private boolean bClearButton;
protected String toolTip;
protected OATemplate templateToolTip;
private boolean bHadToolTip;
protected String placeholder;
protected String floatLabel;
/** javascript regex */
// http://daringfireball.net/2010/07/improved_regex_for_matching_urls
// original
// (?i)\b((?:[a-z][\w-]+:(?:/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?������]))
public final static String RegexMatch_URL = "(?i)\\b((?:[a-z][\\w-]+:(?:/{1,3}|[a-z0-9%])|www\\d{0,3}[.]|[a-z0-9.\\-]+[.][a-z]{2,4}/)(?:[^\\s()<>]+|\\(([^\\s()<>]+|(\\([^\\s()<>]+\\)))*\\))+(?:\\(([^\\s()<>]+|(\\([^\\s()<>]+\\)))*\\)|[^\\s`!()\\[\\]{};:'\".,<>?������]))";
// http://ntt.cc/2008/05/10/over-10-useful-javascript-regular-expression-functions-to-improve-your-web-applications-efficiency.html
public final static String RegexMatch_Digits = "^\\s*\\d+\\s*$";
public final static String RegexMatch_Integer = "^\\s*(\\+|-)?\\d+\\s*$";
public final static String RegexMatch_Decimal = "^\\s*(\\+|-)?((\\d+(\\.\\d+)?)|(\\.\\d+))\\s*$";
public final static String RegexMatch_Currency = "^\\s*(\\+|-)?((\\d+(\\.\\d\\d)?)|(\\.\\d\\d))\\s*$";
public final static String RegexMatch_SingleDigit = "^([0-9])$";
public final static String RegexMatch_DoubleDigit = "^([1-9][0-9])$";
// http://www.zparacha.com/validate-email-address-using-javascript-regular-expression/
public final static String RegexMatch_Email = "^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}$";
//was: public final static String RegexMatch_Email = "^\\s*[\\w\\-\\+_]+(\\.[\\w\\-\\+_]+)*\\@[\\w\\-\\+_]+\\.[\\w\\-\\+_]+(\\.[\\w\\-\\+_]+)*\\s*$";
public final static String RegexMatch_CreditCard = "^\\s*\\d+\\s*$"; // qqq currently only checks if digits
// http://stackoverflow.com/questions/123559/a-comprehensive-regex-for-phone-number-validation
public final static String RegexMatch_USPhoneNumber = "^(?:(?:\\+?1\\s*(?:[.-]\\s*)?)?(?:\\(\\s*([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9])\\s*\\)|([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9]))\\s*(?:[.-]\\s*)?)?([2-9]1[02-9]|[2-9][02-9]1|[2-9][02-9]{2})\\s*(?:[.-]\\s*)?([0-9]{4})(?:\\s*(?:#|x\\.?|ext\\.?|extension)\\s*(\\d+))?$";
public final static String RegexMatch_DateMMDDYYYY = "^\\d{1,2}\\/\\d{1,2}\\/\\d{4}$";
public final static String RegexMatch_DateMMDDYY = "^\\d{1,2}\\/\\d{1,2}\\/\\d{2}$";
public final static String RegexMatch_Time12hr = "^(0?[1-9]|1[012]):[0-5][0-9]$";
public final static String RegexMatch_Time24hr = "^([01]?[0-9]|2[0-3]):[0-5][0-9]$";
// see jquery maskedinput js lib
public final static String MaskInput_USPhoneNumber = "(999) 999-9999";
public final static String MaskInput_DateMMDDYYYY = "99/99/9999";
public final static String MaskInput_DateMMDDYY = "99/99/99";
public final static String MaskInput_TimeHMS = "99:99:99";
public final static String MaskInput_TimeHM = "99:99";
public final static String MaskInput_Integer = "9?999999";
public final static String MaskInput_Decimal = "9?dddddd";
public final static String MaskInput_SingleDigit = "9";
public final static String MaskInput_DoubleDigit = "99";
// AutoNumeric jquery plugin
// see: http://www.decorplanit.com/plugin/
// NOTE: use the older version that supports jquery. The new version is huge and is not a jq plugin
// https://plugins.jquery.com/autoNumeric/
private static class AutoNum {
String min;
String max;
char symbol;
boolean symbolPrefix;
int decimalPlaces;
}
protected AutoNum autoNum;
public OATextField(String id, Hub hub, String propertyPath) {
this(id, hub, propertyPath, 0, 0);
}
public OATextField(Hub hub, String propertyPath) {
this(null, hub, propertyPath, 0, 0);
}
public OATextField(String id, Hub hub, String propertyPath, int width, int maxLength) {
this.id = id;
this.hub = hub;
this.width = width;
this.maxLength = maxLength;
setPropertyPath(propertyPath);
}
public OATextField(Hub hub, String propertyPath, int width, int maxLength) {
this(null, hub, propertyPath, width, maxLength);
}
public OATextField(Hub hub, String propertyPath, int maxLength) {
this(null, hub, propertyPath, 0, maxLength);
}
public OATextField(String id) {
this.id = id;
}
public OATextField() {
}
/**
* Used to use the autoNumeric plugin
* @param min value
* @param max value
* @param symbol example: $
* @param symbolPrefix true if symber is prefix, else it will be used as suffix
* @param decimalPlaces number of decimals places for input and display
*/
public void setNumeric(String min, String max, char symbol, boolean symbolPrefix, int decimalPlaces) {
autoNum = new AutoNum();
autoNum.min = min;
if (max == null) max = "9999999999999";
autoNum.max = max;
autoNum.symbol = symbol;
autoNum.symbolPrefix = symbolPrefix;
autoNum.decimalPlaces = decimalPlaces;
}
public void setDecimal(int deci) {
this.autoNum = new AutoNum();
setNumeric(null, null, (char) 0, true, deci);
}
public void setCurrency() {
this.autoNum = new AutoNum();
setNumeric(null, null, (char) '$', true, 2);
}
public void setInteger() {
this.autoNum = new AutoNum();
setNumeric(null, null, (char) 0, true, 0);
}
public void setPositiveDecimal(int deci) {
this.autoNum = new AutoNum();
setNumeric("0", null, (char) 0, true, deci);
}
public void setPositiveCurrency() {
this.autoNum = new AutoNum();
setNumeric("0", null, (char) '$', true, 2);
}
public void setPositiveInteger() {
this.autoNum = new AutoNum();
setNumeric("0", null, (char) 0, true, 0);
}
@Override
public boolean isChanged() {
if (value == lastValue) return false;
if (value == null || lastValue == null) return true;
return value.equals(lastValue);
}
@Override
public String getId() {
return id;
}
@Override
public void setId(String id) {
this.id = id;
}
@Override
public void reset() {
value = lastValue;
lastAjaxSent = null;
}
@Override
public void setForm(OAForm form) {
this.form = form;
}
@Override
public OAForm getForm() {
return this.form;
}
@Override
public boolean _beforeFormSubmitted() {
return true;
}
@Override
public boolean _onFormSubmitted(HttpServletRequest req, HttpServletResponse resp, HashMap hmNameValue) {
String s = req.getParameter("oacommand");
if (s == null && hmNameValue != null) {
String[] ss = hmNameValue.get("oacommand");
if (ss != null && ss.length > 0) s = ss[0];
}
boolean bWasSubmitted = (id != null && id.equals(s));
String name = null;
OAObject obj = null;
String[] values = null;
String value = null;
if (hmNameValue != null) {
for (Map.Entry ex : hmNameValue.entrySet()) {
name = ex.getKey();
if (!name.toUpperCase().startsWith(id.toUpperCase())) continue;
values = ex.getValue();
if (values == null || values.length == 0) {
value = null;
}
else value = values[0];
if (name.equalsIgnoreCase(id)) {
if (hub != null) {
obj = (OAObject) hub.getAO();
}
break;
}
else {
if (name.toUpperCase().startsWith(id.toUpperCase() + "_")) {
s = name.substring(id.length() + 1);
if (s.startsWith("guid.")) {
s = s.substring(5);
OAObjectKey k = new OAObjectKey(null, OAConv.toInt(s), true);
obj = OAObjectCacheDelegate.get(hub.getObjectClass(), k);
}
else {
obj = OAObjectCacheDelegate.get(hub.getObjectClass(), s);
}
if (obj == null) {
LOG.warning("Object not found in cache, request param name=" + name + ", hub=" + hub);
}
break;
}
}
}
}
value = convertInputText(value);
int max = getMaxWidth();
if (max > 0 && value != null && value.length() > max) {
value = value.substring(0, max);
}
if (hub != null) {
if (obj != null) {
try {
String fmt = getFormat();
if ( (bIsDateTime || bIsTime) && !OAString.isEmpty(value)) {
boolean b = true;
if (!OAString.isEmpty(fmt)) {
s = fmt.toUpperCase();
if (s.indexOf("X") >= 0 || s.indexOf("Z") >= 0) { // includes timezone in value
b = false;
}
}
if (b) {
OAForm f = getForm();
if (f != null) {
OASession sess = f.getSession();
if (sess != null) {
if (bIsDateTime) {
OADateTime dt = OADateTime.valueOf(value, fmt);
TimeZone tz = sess.getBrowserTimeZone();
if (tz != null) dt.setTimeZone(tz);
OADateTime d2 = new OADateTime(dt.getTime()); // use this computer's timezone
value = d2.toString(fmt);
}
else {
OATime dt = (OATime) OATime.valueOf(value, fmt);
TimeZone tz = sess.getBrowserTimeZone();
if (tz != null) dt.setTimeZone(tz);
OATime d2 = new OATime(dt.getTime()); // use this computer/server timezone
value = d2.toString(fmt);
}
}
}
}
}
if (!OAString.isEqual(value, lastValue)) {
if (value != null && (value.length() == 0 && lastValue == null)) {
}
else {
if (getTypeAhead()!=null && bPropertyPathIsManyLink) {
Object objx = ((OAObject)hub.getAO()).getProperty(propertyPath);
if (objx instanceof Hub) {
Hub hub = (Hub) objx;
// tagsinput js will put Ids in comma separated string in value
final String[] ss = value.split(",");
for (int i=0; ss!=null && i\").insertAfter('#"+id+"');\n");
final int max = getMaxWidth();
if (getClearButton()) {
sb.append("$('#"+getId()+"').addClass('oaTextFieldWithClear');\n");
sb.append("$('#"+getId()+"').wrap('');\n");
sb.append("$('#"+getId()+"').after('');\n");
sb.append("$('#"+getId()+"').keyup(function() {\n");
sb.append(" var text = $(this).val();\n");
sb.append(" $('#"+getId()+"Clear').css('visibility', ((text.length > 0)?'visible':'hidden'));\n");
if (max > 0) {
sb.append(" if (text.length > " + max + ") {\n");
sb.append(" $(this).val(text.slice(0, " + max + "));\n");
sb.append(" }\n");
}
sb.append("});\n");
sb.append("$('#"+getId()+"Clear').mousedown(function() {\n");
if (bAjaxSubmit) {
sb.append(" $('#"+getId()+"').ignore=true;\n");
sb.append(" $('#"+getId()+"').val('');\n");
sb.append(" $('#oacommand').val('" + getId() + "');\n");
sb.append(" ajaxSubmit();\n");
sb.append(" $('#"+getId()+"').ignore=false;\n");
}
else if (getSubmit()) {
sb.append(" $('#"+getId()+"').ignore=true;\n");
sb.append(" $('#"+getId()+"').val('');\n");
sb.append(" $('#oacommand').val('" + getId() + "');\n");
sb.append(" $('form').submit();\n");
sb.append(" $('#"+getId()+"').ignore=false;\n");
}
sb.append(" if ($('#"+getId()+"').val().length == 0) return false;\n");
sb.append(" $('#"+getId()+"').val('');\n");
// sb.append(" $('#"+getId()+"').blur();\n");
sb.append(" $('#"+getId()+"Clear').css('visibility', 'hidden');\n");
sb.append(" $('#"+getId()+"').focus();\n");
sb.append(" return false;\n");
sb.append("});\n");
}
else if (max > 0) {
sb.append("$('#" + getId() + "').keyup(function(event) {\n");
sb.append(" var text = $(this).val();\n");
sb.append(" if (text.length > " + max + ") {\n");
sb.append(" $(this).val(text.slice(0, " + max + "));\n");
sb.append(" }\n");
sb.append("});\n");
}
if (!getSubmit() && bAjaxSubmit && OAString.isEmpty(getForwardUrl())) {
if (!getAutoComplete() && (getTypeAhead()==null)) {
if (!isDateTime() && !isDate() && !isTime()) { // date/time will use close (see below)
sb.append("$('#" + id + "').blur(function(e) {if($(this).ignore){$(this).ignore=false;return;}$('#oacommand').val('" + id + "'); ajaxSubmit();return false;});\n");
sb.append("$('#" + id + "').keypress(function(e) { if (e.keyCode != 13) return; e.preventDefault(); $('#oacommand').val('" + id + "'); $(this).ignore=true;ajaxSubmit();$(this).ignore=false;return false;});\n");
}
}
}
else if (getSubmit() || OAString.notEmpty(getForwardUrl())) {
if (!isDateTime() && !isDate() && !isTime()) {
sb.append("$('#" + id + "').blur(function() { $('#oacommand').val('" + id + "'); $('form').submit(); $('#oacommand').val(''); return false;});\n");
}
}
if (isRequired()) {
sb.append("$('#" + id + "').addClass('oaRequired');\n");
sb.append("$('#" + id + "').attr('required', true);\n");
}
sb.append("$('#" + id + "').blur(function() {$(this).removeClass('oaError');}); \n");
if (getSubmit() || getAjaxSubmit()) {
sb.append("$('#" + id + "').addClass('oaSubmit');\n");
}
if (getAutoComplete()) {
// support for jqueryui autocomplete
sb.append("var cache" + id + " = {}, lastXhr" + id + ";\n");
sb.append("$( '#" + id + "' ).autocomplete({\n");
sb.append("minLength: 3,\n");
sb.append("source: function( request, response ) {\n");
sb.append(" var term = request.term;\n");
sb.append(" if ( term in cache" + id + " ) {\n");
sb.append(" response( cache" + id + "[ term ] );\n");
sb.append(" return;\n");
sb.append(" }\n");
sb.append(" \n");
sb.append(" lastXhr" + id + " = $.getJSON( 'oaautocomplete.jsp?oaform=" + form.getId() + "&id=" + getId()
+ "', request, function( data, status, xhr ) {\n");
sb.append(" cache" + id + "[ term ] = data;\n");
sb.append(" if ( xhr === lastXhr" + id + " ) {\n");
sb.append(" response( data );\n");
sb.append(" }\n");
sb.append(" });\n");
sb.append("}\n");
if (getAjaxSubmit()) {
sb.append(",\n");
sb.append("select: function( event, ui ) {\n");
sb.append(" $('#" + getId() + "').val(ui.item.value);\n");
sb.append(" $('#oacommand').val('" + getId() + "');\n");
sb.append(" ajaxSubmit();\n");
sb.append("}\n");
}
sb.append("});\n");
}
else if (getMultiValue() && getTypeAhead()==null && !bPropertyPathIsOneLink && !bPropertyPathIsManyLink) {
// free form multiple values
sb.append("$('#" + id + "').tagsinput();\n");
}
else if (getTypeAhead() != null && !getMultiValue() && !bPropertyPathIsOneLink && !bPropertyPathIsManyLink) {
// typeAhead one
sb.append("var " + id + "Bloodhound = new Bloodhound({\n");
sb.append(" datumTokenizer : Bloodhound.tokenizers.obj.whitespace('display'),\n");
sb.append(" queryTokenizer : Bloodhound.tokenizers.whitespace,\n");
sb.append(" remote : {\n");
sb.append(" url : 'oatypeahead.jsp?oaform="+getForm().getId()+"&id=" + id + "&term=%QUERY',\n");
sb.append(" wildcard: '%QUERY',\n");
sb.append(" cache: false\n"); // 20171030
sb.append(" }\n");
sb.append("});\n");
sb.append("" + id + "Bloodhound.initialize();\n");
int minLen = getTypeAhead().getMinimumInputLength();
if (minLen < 0) minLen = 3;
sb.append("$('#" + id + "').typeahead({\n");
sb.append(" hint: "+(getTypeAhead().getShowHint()?"true":"false")+",\n");
sb.append(" highlight: true,\n");
sb.append(" minLength: "+minLen+"\n");
sb.append("}, {\n");
sb.append(" source: " + id + "Bloodhound,\n");
sb.append(" name: '" + id + "Popup',\n");
sb.append(" limit: 400,\n"); // see: https://github.com/twitter/typeahead.js/issues/1232
sb.append(" display: 'display',\n");
sb.append(" templates: {\n");
sb.append(" suggestion: function(data) {return ''+data.dropdowndisplay+'
';}\n");
sb.append(" }\n");
if (bAjaxSubmit) {
sb.append(" }).on('typeahead:select', function (obj, datum) {\n"); // https://github.com/twitter/typeahead.js/blob/master/doc/jquery_typeahead.md#custom-events
sb.append(" $('#" + getId() + "').val(datum.display);\n");
sb.append(" $('#oacommand').val('" + getId() + "');\n");
sb.append(" ajaxSubmit();\n");
}
sb.append(" });\n");
}
else if (getTypeAhead() != null && getMultiValue() && !bPropertyPathIsOneLink && !bPropertyPathIsManyLink) {
// select multiple from ta list and store displayed value in one property
sb.append("var " + id + "Bloodhound = new Bloodhound({\n");
sb.append(" datumTokenizer : Bloodhound.tokenizers.obj.whitespace('display'),\n");
sb.append(" queryTokenizer : Bloodhound.tokenizers.whitespace,\n");
sb.append(" remote : {\n");
sb.append(" url : 'oatypeahead.jsp?oaform="+getForm().getId()+"&id=" + id + "&term=%QUERY',\n");
sb.append(" wildcard: '%QUERY'\n");
sb.append(" }\n");
sb.append("});\n");
sb.append("" + id + "Bloodhound.initialize();\n");
int minLen = getTypeAhead().getMinimumInputLength();
if (minLen < 0) minLen = 3;
sb.append("$('#" + id + "').tagsinput({\n");
// 20170913
sb.append(" itemValue: 'id',\n"); // <-- store id value
//was: sb.append(" itemValue: 'display',\n"); // <-- store display value
sb.append(" itemText: 'display',\n");
sb.append(" freeInput: false,\n");
sb.append(" typeaheadjs: [\n");
sb.append(" {\n");
sb.append(" minLength: "+minLen+",\n");
sb.append(" hint: "+(getTypeAhead().getShowHint()?"true":"false")+",\n");
sb.append(" highlight: true\n");
sb.append(" },\n");
sb.append(" {\n");
sb.append(" name: '" + id + "Popup',\n");
sb.append(" limit: 400,\n"); // see: https://github.com/twitter/typeahead.js/issues/1232
sb.append(" display: 'display',\n");
sb.append(" templates: {\n");
sb.append(" suggestion: function(data) {return ''+data.dropdowndisplay+'
';}\n");
sb.append(" },\n");
sb.append(" source: " + id + "Bloodhound.ttAdapter()\n");
sb.append(" }\n");
sb.append(" ]\n");
sb.append("});\n");
}
else if (getTypeAhead() != null && (bPropertyPathIsOneLink || bPropertyPathIsManyLink)) {
// use tagInput and ta, selected Ids will pass comma sep values when submitted
sb.append("var " + id + "Bloodhound = new Bloodhound({\n");
sb.append(" datumTokenizer : Bloodhound.tokenizers.obj.whitespace('display'),\n");
sb.append(" queryTokenizer : Bloodhound.tokenizers.whitespace,\n");
sb.append(" remote : {\n");
sb.append(" url : 'oatypeahead.jsp?oaform="+getForm().getId()+"&id=" + id + "&term=%QUERY',\n");
sb.append(" wildcard: '%QUERY'\n");
sb.append(" }\n");
sb.append("});\n");
sb.append("" + id + "Bloodhound.initialize();\n");
int minLen = getTypeAhead().getMinimumInputLength();
if (minLen < 0) minLen = 3;
// https://bootstrap-tagsinput.github.io/bootstrap-tagsinput/examples/
sb.append("$('#" + id + "').tagsinput({\n");
sb.append(" itemValue: 'id',\n"); // <-- store Id value
sb.append(" itemText: 'display',\n");
if (bPropertyPathIsOneLink) {
sb.append(" maxTags: 1,\n");
}
sb.append(" freeInput: false,\n");
sb.append(" typeaheadjs: [\n");
sb.append(" {\n");
sb.append(" minLength: "+minLen+",\n");
sb.append(" hint: "+(getTypeAhead().getShowHint()?"true":"false")+",\n");
sb.append(" highlight: true\n");
sb.append(" },\n");
sb.append(" {\n");
sb.append(" name: '" + id + "Popup',\n");
sb.append(" limit: 400,\n"); // see: https://github.com/twitter/typeahead.js/issues/1232
sb.append(" display: 'display',\n");
sb.append(" templates: {\n");
sb.append(" suggestion: function(data) {return ''+data.dropdowndisplay+'
';}\n");
sb.append(" },\n");
sb.append(" source: " + id + "Bloodhound.ttAdapter()\n");
sb.append(" }\n");
sb.append(" ]\n");
sb.append("});\n");
}
// 20170628 moved from begin of method
sb.append(_getAjaxScript(true));
String js = sb.toString();
return js;
}
@Override
public String getVerifyScript() {
StringBuilder sb = new StringBuilder(1024);
// see: OAForm.getInitScript for using "requires[]" and "errors[]"
if (isRequired()) {
String s = name;
if (OAString.isEmpty(s)) {
s = placeholder;
if (OAString.isEmpty(s)) s = id;
}
sb.append("if ($('#" + id + "').val() == '') { requires.push('" + s + "'); $('#" + id
+ "').addClass('oaError');}\n");
}
int max = getMaxWidth();
if (max > 0) {
sb.append("if ($('#" + id + "').val().length > " + max + ") { errors.push('length greater then " + max + " characters for "
+ (name != null ? name : id) + "'); $('#" + id + "').addClass('oaError');}\n");
}
String s = getRegexMatch();
if (!OAString.isEmpty(s)) {
sb.append("regex = new RegExp(/" + s + "/); val = $('#" + id + "').val(); if (!val.match(regex)) { errors.push('invalid "
+ (name != null ? name : id) + "'); $('#" + id + "').addClass('oaError');}\n");
}
// 20170327
if (isDateTime()) {
sb.append("if ($('#" + id + "').val().length > 0) $('#" + id + "_ts').val(Date.parse($('#" + id + "').val()));\n");
}
if (sb.length() == 0) return null;
return sb.toString();
}
/** used when displaying error message for this textfield */
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
private String lastAjaxSent;
@Override
public String getAjaxScript() {
return _getAjaxScript(false);
}
protected String _getAjaxScript(final boolean bIsInitializing) {
StringBuilder sb = new StringBuilder(1024);
String s = getTextJavaScript(bIsInitializing);
if (s != null) sb.append(s);
if (bIsInitializing && getClearButton()) {
sb.append("$('#"+getId()+"Clear').css('visibility', (($('#"+getId()+"').val().length > 0)?'visible':'hidden'));\n");
}
s = getPlaceholder();
if (bIsInitializing && s != null) {
s = OAJspUtil.createJsString(s, '\'');
sb.append("$('#" + id + "').attr('placeholder', '"+s+"');\n");
}
if (bIsInitializing) getFloatLabelJs(sb);
// tooltip
String prefix = null;
String tt = getProcessedToolTip();
if (OAString.isNotEmpty(tt)) {
if (!bHadToolTip) {
bHadToolTip = true;
prefix = "$('#"+id+"').tooltip();\n";
}
tt = OAJspUtil.createJsString(tt, '\'');
sb.append("$('#"+id+"').data('bs.tooltip').options.title = '"+tt+"';\n");
sb.append("$('#"+id+"').data('bs.tooltip').options.placement = 'top';\n");
}
else {
if (bHadToolTip) {
sb.append("$('#"+id+"').tooltip('destroy');\n");
bHadToolTip = false;
}
}
if (bFocus) {
sb.append("$('#" + id + "').focus();\n");
bFocus = false;
}
String js = sb.toString();
if (lastAjaxSent != null && lastAjaxSent.equals(js)) js = null;
else lastAjaxSent = js;
if (prefix != null) {
js = prefix + OAString.notNull(js);
}
return js;
}
protected String getTextJavaScript(final boolean bIsInitializing) {
StringBuilder sb = new StringBuilder(1024);
String newName = id;
String value = null;
if (hub != null && !OAString.isEmpty(propertyPath)) {
if (getTypeAhead() != null && bPropertyPathIsManyLink) {
// https://bootstrap-tagsinput.github.io/bootstrap-tagsinput/examples/
sb.append("$('#" + id + "').tagsinput('removeAll');\n");
OAObject obj = (OAObject) hub.getActiveObject();
if (obj != null) {
Hub h = (Hub) ((OAObject)obj).getProperty(propertyPath);
// value is a comma separated list of Ids, js code will be sent also
for (Object objx : h) {
if (!(objx instanceof OAObject)) continue;
obj = (OAObject) objx;
OAObjectKey key = obj.getObjectKey();
Object[] idxs = key.getObjectIds();
String idx;
if (idxs == null || idxs.length == 0) idx = obj.getGuid()+"";
else idx = idxs[0]+"";
String s2 = getTypeAhead().getDisplayValue(obj);
s2 = OAJspUtil.createJsString(s2, '\"');
sb.append("$('#" + this.id + "').tagsinput('add', { \"id\": "+idx+" , \"display\": \""+s2+"\"});\n");
}
}
}
else if (getTypeAhead() != null && bPropertyPathIsOneLink) {
// https://bootstrap-tagsinput.github.io/bootstrap-tagsinput/examples/
sb.append("$('#" + id + "').tagsinput('removeAll');\n");
OAObject obj = (OAObject) hub.getActiveObject();
if (obj != null) {
Object objx = ((OAObject)obj).getProperty(propertyPath);
if (objx != null) {
obj = (OAObject) objx;
OAObjectKey key = obj.getObjectKey();
Object[] idxs = key.getObjectIds();
String idx;
if (idxs == null || idxs.length == 0) idx = obj.getGuid()+"";
else idx = idxs[0]+"";
String s2 = getTypeAhead().getDisplayValue(obj);
s2 = OAJspUtil.createJsString(s2, '\"');
sb.append("$('#" + this.id + "').tagsinput('add', { \"id\": "+idx+" , \"display\": \""+s2+"\"});\n");
}
}
}
else {
OAObject obj = (OAObject) hub.getAO();
if (obj != null && nameIncludesObjectId) {
OAObjectKey key = OAObjectKeyDelegate.getKey(obj);
Object[] objs = key.getObjectIds();
if (objs != null && objs.length > 0 && objs[0] != null) {
newName += "_" + objs[0];
}
else {
newName += "_guid." + key.getGuid();
}
}
if (obj != null) {
if (isDateTime() || isDate() || isTime()) {
String fmt = getFormat();
boolean b = true;
// 20170925 added isTime
if (bIsDateTime || bIsTime) {
b = false;
if (!OAString.isEmpty(fmt)) {
String s = fmt.toUpperCase();
if (s.indexOf("X") >= 0 || s.indexOf("Z") >= 0) { // includes timezone in value
b = true;
}
}
if (!b) {
b = true;
OADateTime dt = (OADateTime) obj.getProperty(propertyPath);
if (dt != null) {
OAForm f = getForm();
if (f != null) {
OASession sess = f.getSession();
if (sess != null) {
TimeZone tz = sess.getBrowserTimeZone();
dt = dt.convertTo(tz);
if (isTime()) dt = new OATime(dt);
value = dt.toString(fmt);
b = false;
}
}
}
}
}
if (b) {
value = obj.getPropertyAsString(propertyPath, fmt);
}
}
else {
value = obj.getPropertyAsString(propertyPath);
}
}
}
}
else {
value = getValue();
}
if (value == null) value = "";
sb.append("$('#" + id + "').attr('name', '" + newName + "');\n");
lastValue = value;
// set existing value
if (getTypeAhead()!=null && (bPropertyPathIsManyLink || bPropertyPathIsOneLink)) {
// already done
}
else if (getTypeAhead()!=null && getMultiValue()) {
// uses tagsInput+typeAhead+bloodhound and uses array objects
// values are separated by comma and need to be added separately
sb.append("$('#" + id + "').tagsinput('removeAll');\n");
for (int i=1;;i++) {
String sx = OAString.field(value, ",", i);
if (sx == null) break;
sx = sx.trim();
if (sx.length() == 0) continue;
sx = OAJspUtil.createJsString(sx, '\"');
// the object.id is not known for the value, will instead use display as the id
// this is the same as getTypeAheadJson(..) return value
sb.append("$('#" + id + "').tagsinput('add', { \"id\": \""+sx+"\" , \"display\": \""+sx+"\"});\n");
}
}
else if (getMultiValue() && !bPropertyPathIsManyLink && !bPropertyPathIsOneLink) {
// values are separated by comma and need to be added
sb.append("$('#" + id + "').tagsinput('removeAll');\n");
for (int i=1;;i++) {
String sx = OAString.field(value, ",", i);
if (sx == null) break;
sx = sx.trim();
if (sx.length() == 0) continue;
sx = OAJspUtil.createJsString(sx, '\'');
sb.append("$('#" + id + "').tagsinput('add', '"+sx+"');\n");
}
}
else {
value = OAJspUtil.createJsString(value, '\'');
if (autoNum != null) {
if (autoNum.decimalPlaces > 0) {
double d = OAConv.toDouble(value);
value = OAConv.toString(d);
}
else {
long x = OAConv.toLong(value);
value = x+"";
}
}
if (autoNum != null && !bIsInitializing) {
sb.append("$('#" + id + "').autoNumeric('set', '"+value+"');\n");
//was: sb.append("$('#" + id + "').val($('#" + id + "').autoNumeric('set', '"+value+"'));\n");
}
else {
sb.append("$('#" + id + "').val('" + value + "');\n");
}
}
if (getMaxLength() > 0) sb.append("$('#" + id + "').attr('maxlength', '" + getMaxLength() + "');\n");
if (width > 0) sb.append("$('#" + id + "').attr('size', '" + width + "');\n");
String s = getEnabledScript(getEnabled());
if (s != null) sb.append(s);
if (!getMultiValue() && !bPropertyPathIsManyLink && !bPropertyPathIsOneLink) {
s = getVisibleScript(getVisible());
if (s != null) sb.append(s);
}
String fmt = getFormat();
if (isDateTime() || isDate() || isTime()) {
if (OAString.isEmpty(fmt)) {
if (isDateTime()) {
fmt = OADateTime.getGlobalOutputFormat();
}
else if (isDate()) {
fmt = OADate.getGlobalOutputFormat();
}
else fmt = OATime.getGlobalOutputFormat();
}
// [BEGIN] Jquery date/time formats
// see: http://api.jqueryui.com/datepicker/#utility-formatDate
// http://docs.jquery.com/UI/Datepicker/formatDate
// http://trentrichardson.com/examples/timepicker/
// https://github.com/trentrichardson/jQuery-Timepicker-Addon
String dfmtJquery = null;
String tfmtJquery = null;
int pos = fmt.indexOf('M');
if (pos < 0) {
pos = fmt.indexOf('y');
}
if (pos >= 0) {
pos = fmt.indexOf('H');
if (pos < 0) {
pos = fmt.indexOf('h');
}
if (pos >= 0) {
dfmtJquery = fmt.substring(0, pos).trim();
}
else dfmtJquery = fmt;
if (dfmtJquery.indexOf("MMM") >= 0) {
dfmtJquery = OAString.convert(dfmtJquery, "MMMM", "MM");
dfmtJquery = OAString.convert(dfmtJquery, "MMM", "M");
}
else dfmtJquery = OAString.convert(dfmtJquery, "M", "m");
dfmtJquery = OAString.convert(dfmtJquery, "yy", "y");
dfmtJquery = OAString.convert(dfmtJquery, "E", "D");
}
pos = fmt.indexOf('H');
if (pos < 0) {
pos = fmt.indexOf('h');
}
if (pos >= 0) {
tfmtJquery = fmt.substring(pos).trim();
tfmtJquery = OAString.convert(tfmtJquery, "aa", "TT");
tfmtJquery = OAString.convert(tfmtJquery, "a", "TT");
}
if (!isDateTime()) {
if (!isDate()) dfmtJquery = null;
if (!isTime()) tfmtJquery = null;
}
// [BEGIN] Bootstrap date/time formats
// see: http://momentjs.com/docs/#/displaying/format/
String dfmtBS = null;
String tfmtBS = null;
pos = fmt.indexOf('M');
if (pos < 0) {
pos = fmt.indexOf('y');
}
if (pos >= 0) {
pos = fmt.indexOf('H');
if (pos < 0) {
pos = fmt.indexOf('h');
}
if (pos >= 0) {
dfmtBS = fmt.substring(0, pos).trim();
}
else dfmtBS = fmt;
dfmtBS = OAString.convert(dfmtBS, "y", "Y");
dfmtBS = OAString.convert(dfmtBS, "d", "D");
dfmtBS = OAString.convert(dfmtBS, "E", "d"); // day of week
}
pos = fmt.indexOf('H');
if (pos < 0) {
pos = fmt.indexOf('h');
}
if (pos >= 0) {
tfmtBS = fmt.substring(pos).trim();
}
if (!isDateTime()) {
if (!isDate()) dfmtBS = null;
if (!isTime()) tfmtBS = null;
}
if (!OAString.isEmpty(dfmtJquery) && !OAString.isEmpty(tfmtJquery)) {
// supports jquery.datetimepicker and bootstrap datetimepicker (customized version: had to change name to bsdatetimepicker)
// see: https://eonasdan.github.io/bootstrap-datetimepicker/
if (bIsInitializing) {
sb.append("if ($().bsdatetimepicker) {\n");
sb.append(" $('#" + id + "').bsdatetimepicker({");
sb.append("format: '" + OAJspUtil.createJsString((dfmtBS + " " + tfmtBS), '\'') + "'");
sb.append(", sideBySide: true, showTodayButton: true, showClear: true, showClose: true});\n");
if (!getSubmit() && bAjaxSubmit && OAString.isEmpty(getForwardUrl())) {
if (!getAutoComplete() && (getTypeAhead()!=null)) {
sb.append("$('#" + id + "').on('dp.change', function (e) {\n");
sb.append(" $('#oacommand').val('" + id + "'); ajaxSubmit(); return false;});\n");
}
}
else if (getSubmit() || !OAString.isEmpty(getForwardUrl())) {
sb.append("$('#" + id + "').on('dp.change', function (e) {\n");
sb.append(" $('#oacommand').val('" + id + "'); $('form').submit(); $('#oacommand').val(''); return false;});\n");
}
sb.append("}\n"); // end bootstrap
sb.append("else {\n");
sb.append("$('#" + id + "').datetimepicker({ ");
sb.append("dateFormat: '" + OAJspUtil.createJsString(dfmtJquery,'\'') + "'");
sb.append(", timeFormat: '" + OAJspUtil.createJsString(tfmtJquery,'\'') + "'");
if (tfmtJquery != null && tfmtJquery.toLowerCase().indexOf('z') >= 0) {
// sb.append(", timezoneList: [{label: 'EDT', value: '-240'}, {label: 'other', value: '-480'}]");
}
if (!getSubmit() && bAjaxSubmit && OAString.isEmpty(getForwardUrl())) {
if (!getAutoComplete() && (getTypeAhead()!=null)) {
sb.append(", onClose: function() { $('#oacommand').val('" + id + "'); ajaxSubmit(); return false;}\n");
}
}
else if (getSubmit() || !OAString.isEmpty(getForwardUrl())) {
sb.append(", onClose: function() { $('#oacommand').val('" + id + "'); $('form').submit(); $('#oacommand').val(''); return false;}\n");
}
sb.append(" });\n");
sb.append("}\n"); // end jquery
}
}
else if (!OAString.isEmpty(dfmtJquery)) {
if (bIsInitializing) {
sb.append("if ($().bsdatetimepicker) {\n");
sb.append("$('#" + id + "').bsdatetimepicker({");
sb.append("format: '" + OAJspUtil.createJsString(dfmtBS, '\'') + "'");
sb.append(", showTodayButton: true, showClear: true, showClose: true});\n");
if (!getSubmit() && bAjaxSubmit && OAString.isEmpty(getForwardUrl())) {
if (!getAutoComplete() && (getTypeAhead()!=null)) {
sb.append("$('#" + id + "').on('dp.change', function (e) {");
sb.append("$('#oacommand').val('" + id + "'); ajaxSubmit(); return false;});\n");
}
}
else if (getSubmit() || !OAString.isEmpty(getForwardUrl())) {
sb.append("$('#" + id + "').on('dp.change', function (e) {\n");
sb.append(" $('#oacommand').val('" + id + "'); $('form').submit(); $('#oacommand').val(''); return false;});\n");
}
sb.append("}\n"); // end bootstrap
sb.append("else {\n");
sb.append("$('#" + id + "').datepicker({ dateFormat: '" + dfmtJquery + "'");
if (!getSubmit() && bAjaxSubmit && OAString.isEmpty(getForwardUrl())) {
if (!getAutoComplete() && (getTypeAhead()!=null)) {
sb.append(", onClose: function() { $('#oacommand').val('" + id + "'); ajaxSubmit(); return false;}\n");
}
}
else if (getSubmit() || !OAString.isEmpty(getForwardUrl())) {
sb.append(", onClose: function() { $('#oacommand').val('" + id + "'); $('form').submit(); $('#oacommand').val(''); return false;}\n");
}
sb.append("});\n");
sb.append("}\n"); // end jquery
}
}
else if (!OAString.isEmpty(tfmtJquery)) {
if (bIsInitializing) {
sb.append("if ($().bsdatetimepicker) {\n");
sb.append(" $('#" + id + "').bsdatetimepicker({ ");
sb.append("format: '" + OAJspUtil.createJsString(tfmtBS, '\'') + "'");
sb.append(", showClear: true, showClose: true});\n");
if (!getSubmit() && bAjaxSubmit && OAString.isEmpty(getForwardUrl())) {
if (!getAutoComplete() && (getTypeAhead()!=null)) {
sb.append("$('#" + id + "').on('dp.change', function (e) {\n");
sb.append(" $('#oacommand').val('" + id + "'); ajaxSubmit(); return false;});\n");
}
}
else if (getSubmit() || !OAString.isEmpty(getForwardUrl())) {
sb.append("$('#" + id + "').on('dp.change', function (e) {\n");
sb.append(" $('#oacommand').val('" + id + "'); $('form').submit(); $('#oacommand').val(''); return false;});\n");
}
sb.append("}\n"); // end bootstrap
sb.append("else {\n");
sb.append(" $('#" + id + "').timepicker({ timeFormat: '" + OAJspUtil.createJsString(tfmtJquery,'\'') + "'");
if (!getSubmit() && bAjaxSubmit && OAString.isEmpty(getForwardUrl())) {
if (!getAutoComplete() && (getTypeAhead()!=null)) {
sb.append(", onClose: function() { $('#oacommand').val('" + id + "'); ajaxSubmit(); return false;}");
}
}
else if (getSubmit() || !OAString.isEmpty(getForwardUrl())) {
sb.append(", onClose: function() { $('#oacommand').val('" + id + "'); $('form').submit(); $('#oacommand').val(''); return false;}");
}
sb.append("});\n");
sb.append("}"); // end jquery
}
}
if (isDateTime() && !getAutoComplete() && (getTypeAhead()!=null) && getForm() != null) {
if (bIsInitializing) {
sb.append("$('#" + getForm().getId() + "').prepend(\"\");\n");
}
}
}
else if (bIsInitializing && autoNum != null) {
s = "";
if (autoNum.symbol > 0) {
s = OAString.concat(s, "aSign: '"+autoNum.symbol+"'", ", ");
if (!autoNum.symbolPrefix) s = OAString.concat(s, "pSign: 's'", ", ");
}
if (OAString.isNotEmpty(autoNum.min) || OAString.isNotEmpty(autoNum.max)) {
if (OAString.isNotEmpty(autoNum.min)) s = OAString.concat(s, "vMin: '"+autoNum.min+"'", ", ");
if (OAString.isNotEmpty(autoNum.max)) s = OAString.concat(s, "vMax: '"+autoNum.max+"'", ", ");
}
//if (autoNum.decimalPlaces > 0) {
s = OAString.concat(s, "mDec: '"+autoNum.decimalPlaces+"'", ", ");
// s = OAString.concat(s, "aPad: 'true'", ", "); //default
//}
sb.append("$('#" + id + "').autoNumeric('init',{"+s+"});\n");
}
else if (bIsInitializing && !OAString.isEmpty(inputMask)) {
if (inputMask.indexOf('d') >= 0) sb.append("$.mask.definitions['d'] = '[0-9.]';\n");
sb.append("$('#" + id + "').mask('" + inputMask + "');\n");
}
String js = sb.toString();
return js;
}
protected String format;
public String getFormat() {
return format;
}
public void setFormat(String fmt) {
this.format = fmt;
}
public boolean isDate() {
return bIsDate;
}
public void setDate(boolean b) {
this.bIsDate = b;
}
public boolean isDateTime() {
return bIsDateTime;
}
public void setDateTime(boolean b) {
this.bIsDateTime = b;
}
public boolean isTime() {
return bIsTime;
}
public void setTime(boolean b) {
this.bIsTime = b;
}
/**
* Set regex example for email: "\S+@\S+\.\S+"
*/
public void setRegexMatch(String regex) {
this.regex = regex;
}
public String getRegexMatch() {
return this.regex;
}
/**
* ex: '(999) 999-9999'
*
* last char optional: ("(99) 999-99-9?9")
*
* see: http://digitalbush.com/projects/masked-input-plugin/
*
* @return
*/
public String getInputMask() {
return inputMask;
}
public void setInputMask(String inputMask) {
this.inputMask = inputMask;
}
public boolean isRequired() {
return required;
}
public boolean getRequired() {
return required;
}
public void setRequired(boolean required) {
this.required = required;
}
@Override
public void setEnabled(boolean b) {
this.bEnabled = b;
}
@Override
public boolean getEnabled() {
if (!bEnabled) return false;
if (hub == null) return bEnabled;
OAObject obj = (OAObject) hub.getAO();
if (obj == null) return false;
if (OAString.isEmpty(enablePropertyPath)) return bEnabled;
Object value = obj.getProperty(enablePropertyPath);
boolean b;
if (value instanceof Hub) {
b = ((Hub) value).size() > 0;
}
else b = OAConv.toBoolean(value);
return b;
}
public String getEnablePropertyPath() {
return enablePropertyPath;
}
public void setEnablePropertyPath(String enablePropertyPath) {
this.enablePropertyPath = enablePropertyPath;
}
@Override
public void setVisible(boolean b) {
this.bVisible = b;
}
@Override
public boolean getVisible() {
if (!bVisible) return false;
if (hub == null) return true;
if (OAString.isEmpty(visiblePropertyPath)) return bVisible;
OAObject obj = (OAObject) hub.getAO();
if (obj == null) return false;
Object value = obj.getProperty(visiblePropertyPath);
boolean b;
if (value instanceof Hub) {
b = ((Hub) value).size() > 0;
}
else b = OAConv.toBoolean(value);
return b;
}
public String getVisiblePropertyPath() {
return visiblePropertyPath;
}
public void setVisiblePropertyPath(String visiblePropertyPath) {
this.visiblePropertyPath = visiblePropertyPath;
}
public void setValue(String value) {
if (value != this.value || value == null || value.length() == 0 || !value.equals(this.value)) {
lastAjaxSent = null;
}
this.value = value;
}
public String getValue() {
return this.value;
}
public String getPropertyPath() {
return propertyPath;
}
public void setPropertyPath(String propertyPath) {
this.propertyPath = propertyPath;
boolean bDate = isDate();
boolean bDateTime = isDateTime();
boolean bTime = isTime();
if (hub != null && !OAString.isEmpty(propertyPath)) {
for (OAPropertyInfo pi : hub.getOAObjectInfo().getPropertyInfos()) {
if (!propertyPath.equalsIgnoreCase(pi.getName())) continue;
if (pi.getClassType().equals(OADateTime.class)) {
bDateTime = true;
}
else if (pi.getClassType().equals(OADate.class)) {
bDate = true;
}
else if (pi.getClassType().equals(OATime.class)) {
bTime = true;
}
break;
}
OAObjectInfo oi = hub.getOAObjectInfo();
OALinkInfo li = oi.getLinkInfo(propertyPath);
if (li != null) {
if (li.getType() == li.TYPE_MANY) {
bPropertyPathIsManyLink = true;
}
else {
bPropertyPathIsOneLink = true;
}
}
}
setDateTime(bDateTime);
setTime(bTime);
setDate(bDate);
}
private int dataSourceMax = -2;
public int getDataSourceMaxWidth() {
if (dataSourceMax == -2) {
if (hub != null) {
dataSourceMax = -1;
OADataSource ds = OADataSource.getDataSource(hub.getObjectClass());
if (ds != null) {
dataSourceMax = ds.getMaxLength(hub.getObjectClass(), getPropertyPath());
Method method = OAReflect.getMethod(hub.getObjectClass(), "get" + propertyPath, 0);
if (method != null) {
if (method.getReturnType().equals(String.class)) {
if (dataSourceMax > 254) dataSourceMax = -1;
}
else dataSourceMax = -1;
}
}
}
}
return dataSourceMax;
}
public int getMaxWidth() {
getDataSourceMaxWidth();
if (maxLength <= 0) {
if (dataSourceMax >= 0) return dataSourceMax;
}
if (dataSourceMax > 0 && maxLength > dataSourceMax) return dataSourceMax;
return maxLength;
}
/**
* max length of text. If -1 (default) then unlimited.
*/
public void setMaxWidth(int x) {
maxLength = x;
maxLength = getMaxWidth(); // verify with Datasource
}
public int getMaxLength() {
return getMaxWidth();
}
public void setMaxLength(int x) {
maxLength = x;
maxLength = getMaxWidth(); // verify with Datasource
}
public int getMinLength() {
return minLength;
}
public void setMinLength(int x) {
minLength = x;
}
public void setFocus(boolean b) {
this.bFocus = b;
}
public void setFocus() {
this.bFocus = true;
}
/**
* True if autoCompelte should be enabled.
*/
public void setAutoComplete(boolean b) {
this.bAutoComplete = b;
}
public boolean getAutoComplete() {
return bAutoComplete;
}
public void setTypeAhead(OATypeAhead ta) {
this.typeAhead = ta;
}
public OATypeAhead getTypeAhead() {
return typeAhead;
}
/**
* Called by browser if autoComplete is true.
* Uses oaautocomplete.jsp
*
* @param value user input
* @return list of values to send back to browser.
*/
public String[] getAutoCompleteText(String value) {
return null;
}
public Object getTypeAheadObject(String searchText) {
if (typeAhead == null || searchText == null) return null;
ArrayList al = typeAhead.search(searchText);
if (al == null) return null;
if (al.size() == 0) return null;
for (OAObject obj : al) {
String displayValue = typeAhead.getDisplayValue(obj);
if (searchText.equals(displayValue)) return obj;
}
return null;
}
public Object getTypeAheadObject() {
String searchText = getValue();
Object obj = getTypeAheadObject(searchText);
return obj;
}
/**
* Called by browser
* Uses oatypeahead.jsp
*
* Must be json string using double quotes, and "id", "display" for values
* ex: String s = "{\"id\":1,\"display\":\"m-1-1\"},{\"id\":2,\"display\":\"m-2-1\"}";
*
* @param searchText user input
* @return list of values to send back to browser.
*/
public String getTypeAheadJson(String searchText) {
String json = null;
try {
json = _getTypeAheadJson(searchText);
}
catch (Exception e) {
LOG.log(Level.WARNING, "Error getting json for typeahead search, searchText="+searchText, e);
json = "{\"id\":0,\"display\":\""+ OAJspUtil.createJsString(e.getMessage(),'"')+"\"}";
}
return json;
}
protected String _getTypeAheadJson(String searchText) {
if (typeAhead == null) return null;
ArrayList al = typeAhead.search(searchText);
if (al == null) return null;
String json = "";
// ex: String s = "{\"id\":1,\"display\":\"m-1-1\"},{\"id\":2,\"display\":\"m-2-1\"}";
for (Object objx : al) {
OAObject obj = (OAObject) objx;
if (json.length() > 0) json += ",";
OAObjectKey key = obj.getObjectKey();
Object[] ids = key.getObjectIds();
String id;
if (ids == null || ids.length == 0) id = obj.getGuid()+"";
else id = ids[0]+"";
String displayValue = typeAhead.getDisplayValue(obj);
if (displayValue == null) displayValue = "";
else {
displayValue = OAJspUtil.createJsString(displayValue, '\"');
//was: displayValue.replace('\"', ' ');
}
String dd = typeAhead.getDropDownDisplayValue(obj);
if (dd == null) dd = "";
else {
dd = OAJspUtil.createJsString(dd, '\"');
//was: dd.replace('\"', ' ');
}
boolean bUseId = (bPropertyPathIsManyLink || bPropertyPathIsOneLink);
if (!bUseId) {
if (hub == null || hub.getLinkPath(true) == null) {
bUseId = true;
}
}
if (bUseId) {
json += "{\"id\":"+id+",\"display\":\""+displayValue+"\",\"dropdowndisplay\":\""+dd+"\"}";
}
else {
// need to send id=displayValue, since they will be stored in property and not the id
// and then used when it has to reset the txt value from this data
json += "{\"id\":"+displayValue+",\"display\":\""+displayValue+"\",\"dropdowndisplay\":\""+dd+"\"}";
}
}
return json;
}
protected String getTypeAheadDisplayValueForId(int id) {
if (typeAhead == null) return null;
Class c = typeAhead.getToClass();
if (c == null) return null;
OAObject obj = OAObjectCacheDelegate.get(c, id);
if (obj == null) return "id "+id+" not found";
String s = typeAhead.getDisplayValue(obj);
return s;
}
//qqq
/* scrolling with heading not moving http://www.farinspace.com/jquery-scrollable-table-plugin/
*
* resize: http://www.audenaerde.org/simpleresizabletables.js
*
*
* resize heading: http://quocity.com/colresizable/#samples
*
* resize heading (small) ::: http://jsfiddle.net/ydTCZ/ */
@Override
public String getTableEditorHtml() {
// let cell take up all space
width = 0; // so that the "size" attribute wont be set
String s = "";
return s;
}
public void setMultiValue(boolean b) {
this.bMultiValue = b;
}
public boolean getMultiValue() {
return this.bMultiValue;
}
@Override
public String[] getRequiredJsNames() {
ArrayList al = new ArrayList<>();
al.add(OAJspDelegate.JS_jquery);
al.add(OAJspDelegate.JS_jquery_ui);
if (getAutoComplete()) {
}
if (getInputMask() != null) {
al.add(OAJspDelegate.JS_jquery_maskedinput);
}
if (getMultiValue()) {
al.add(OAJspDelegate.JS_bootstrap);
al.add(OAJspDelegate.JS_bootstrap_tagsinput);
}
else if (getTypeAhead() != null && (bPropertyPathIsOneLink || bPropertyPathIsManyLink)) {
al.add(OAJspDelegate.JS_bootstrap);
al.add(OAJspDelegate.JS_bootstrap_tagsinput);
}
if (getTypeAhead() != null) {
al.add(OAJspDelegate.JS_bootstrap);
al.add(OAJspDelegate.JS_bootstrap_typeahead);
}
if (isDateTime()) {
if (getForm() == null || getForm().getDefaultJsLibrary() == OAApplication.JSLibrary_JQueryUI) {
al.add(OAJspDelegate.JS_jquery_timepicker);
}
else {
al.add(OAJspDelegate.JS_bootstrap);
al.add(OAJspDelegate.JS_moment);
al.add(OAJspDelegate.JS_bootstrap_datetimepicker);
}
}
else if (isDate()) {
if (getForm() == null || getForm().getDefaultJsLibrary() == OAApplication.JSLibrary_JQueryUI) {
}
else {
al.add(OAJspDelegate.JS_bootstrap);
al.add(OAJspDelegate.JS_moment);
al.add(OAJspDelegate.JS_bootstrap_datetimepicker);
}
}
else if (isTime()) {
if (getForm() == null || getForm().getDefaultJsLibrary() == OAApplication.JSLibrary_JQueryUI) {
al.add(OAJspDelegate.JS_jquery_timepicker);
}
else {
al.add(OAJspDelegate.JS_bootstrap);
al.add(OAJspDelegate.JS_moment);
al.add(OAJspDelegate.JS_bootstrap_datetimepicker);
}
}
if (OAString.isNotEmpty(getToolTip())) {
al.add(OAJspDelegate.JS_bootstrap);
}
if (autoNum != null) {
al.add(OAJspDelegate.JS_jquery_autonumeric);
}
String[] ss = new String[al.size()];
return al.toArray(ss);
}
@Override
public String[] getRequiredCssNames() {
ArrayList al = new ArrayList<>();
if (getAutoComplete()) {
al.add(OAJspDelegate.CSS_jquery_ui);
}
if (getInputMask() != null) {
}
if (getMultiValue()) {
al.add(OAJspDelegate.CSS_bootstrap);
al.add(OAJspDelegate.CSS_bootstrap_tagsinput);
}
else if (getTypeAhead() != null && (bPropertyPathIsOneLink || bPropertyPathIsManyLink)) {
al.add(OAJspDelegate.CSS_bootstrap);
al.add(OAJspDelegate.CSS_bootstrap_tagsinput);
}
if (getTypeAhead() != null) {
al.add(OAJspDelegate.CSS_bootstrap);
al.add(OAJspDelegate.CSS_bootstrap_typeahead);
}
if (isDateTime()) {
if (getForm() == null || getForm().getDefaultJsLibrary() == OAApplication.JSLibrary_JQueryUI) {
al.add(OAJspDelegate.CSS_jquery_ui);
al.add(OAJspDelegate.CSS_jquery_timepicker);
}
else {
al.add(OAJspDelegate.CSS_bootstrap);
al.add(OAJspDelegate.CSS_bootstrap_datetimepicker);
}
}
else if (isDate()) {
if (getForm() == null || getForm().getDefaultJsLibrary() == OAApplication.JSLibrary_JQueryUI) {
al.add(OAJspDelegate.CSS_jquery_ui);
}
else {
al.add(OAJspDelegate.CSS_bootstrap);
al.add(OAJspDelegate.CSS_bootstrap_datetimepicker);
}
}
else if (isTime()) {
if (getForm() == null || getForm().getDefaultJsLibrary() == OAApplication.JSLibrary_JQueryUI) {
al.add(OAJspDelegate.CSS_jquery_ui);
al.add(OAJspDelegate.CSS_jquery_timepicker);
}
else {
al.add(OAJspDelegate.CSS_bootstrap);
// al.add(OAJspDelegate.JS_moment);
al.add(OAJspDelegate.CSS_bootstrap_datetimepicker);
}
}
if (OAString.isNotEmpty(getToolTip())) {
al.add(OAJspDelegate.CSS_bootstrap);
}
String[] ss = new String[al.size()];
return al.toArray(ss);
}
public void setClearButton(boolean b) {
this.bClearButton = b;
}
public boolean getClearButton() {
return this.bClearButton;
}
public void setToolTip(String tooltip) {
this.toolTip = tooltip;
templateToolTip = null;
}
public String getToolTip() {
return this.toolTip;
}
public String getProcessedToolTip() {
if (OAString.isEmpty(toolTip)) return toolTip;
if (templateToolTip == null) {
templateToolTip = new OATemplate();
templateToolTip.setTemplate(getToolTip());
}
OAObject obj = null;
if (hub != null) {
Object objx = hub.getAO();
if (objx instanceof OAObject) obj = (OAObject) objx;
}
String s = templateToolTip.process(obj, hub, null);
return s;
}
protected String getEnabledScript(boolean b) {
if (b) return ("$('#" + id + "').removeAttr('disabled');\n");
return ("$('#" + id + "').attr('disabled', 'disabled');\n");
}
protected String getVisibleScript(boolean b) {
if (b) return ("$('#" + id + "').show();\n");
return ("$('#" + id + "').hide();\n");
}
@Override
public String getRenderHtml(OAObject obj) {
return null;
}
@Override
public String getEditorHtml(OAObject obj) {
return null;
}
@Override
public void _beforeOnSubmit() {
}
public void setPlaceholder(String placeholder) {
this.placeholder = placeholder;
placeholder = null;
}
public String getPlaceholder() {
return this.placeholder;
}
public void setFloatLabel(String floatLabel) {
this.floatLabel = floatLabel;
floatLabel = null;
}
public String getFloatLabel() {
return this.floatLabel;
}
private boolean bFloatLabelJsInit;
protected void getFloatLabelJs(StringBuilder sb) {
String s = getFloatLabel();
if (OAString.isEmpty(s)) {
if (!bFloatLabelJsInit) return;
}
if (!bFloatLabelJsInit) {
sb.append("$('#" + id + "').addClass('oaFloatLabel');\n");
if (OAString.isEmpty(getFloatLabel())) {
sb.append("$('#" + id + "').after('');\n");
}
else {
sb.append("$('#" + id + "').after('');\n");
sb.append("$('#"+id+"').on('propertychange change keyup paste input', function() { if ($('#"+id+"').val().length > 0) $('#"+id+" + span').addClass('active'); else $('#"+id+" + span').removeClass('active'); });\n");
sb.append("if ($('#"+id+"').val().length > 0) $('#"+id+" + span').addClass('active');\n");
}
bFloatLabelJsInit = true;
}
s = getFloatLabel();
sb.append("$('#"+id+" + span').html(\""+OAJspUtil.createJsString(s,'\"')+"\");\n");
}
public String getValidationRules() {
// IMPORTANT NOTE: validation uses attr name as identifier, not id.
// need to set nameIncludesObjectId=false
//qqq oaweb needs to set name=id
if (!getRequired()) return null;
StringBuilder sb = new StringBuilder(80);
sb.append(id+": {");
int cnt = 0;
if (getRequired()) {
if (cnt++ > 0) sb.append(",\n");
sb.append("required: true");
}
int x = getMaxLength();
if (x > 0) {
if (cnt++ > 0) sb.append(",\n");
sb.append("maxlength: "+x+"");
}
x = getMinLength();
if (x > 0) {
if (cnt++ > 0) sb.append(",\n");
sb.append("minlength: "+x+"");
}
String s = getRegexMatch();
if (OAString.isNotEmpty(s)) {
if (s.equals(RegexMatch_Email)) {
if (cnt++ > 0) sb.append(",\n");
sb.append("email: true");
}
else if (s.equals(RegexMatch_CreditCard)) {
if (cnt++ > 0) sb.append(",\n");
sb.append("creditcard: true");
}
}
/*qqq add more later
$("#my-forms-wizard").validate({
onsubmit: false,
rules: {
txt10: {
required: true,
minlength: 3,
maxlength: 6,
min: 100,
max: 9999,
rangelength: [3, 6],
number: true,
pattern: /^AR\d{4}$/,
digits: true,
creditcard: true,
accept: "image/*",
extension:"doc|docx|pdf|txt",
alphanumeric: true,
integer: true
}
},
messages: {
txt10: {
required: "please enter your fullname",
minlength: "fullname needs to be {0} chars!!",
maxlength: "max len msg",
min: "min msg",
max: "max msg",
rangelength: "range msg",
number: "must be a num",
pattern: "pattern msg",
digits: "digits msg",
creditcard: "creditcard msg",
accept: "accept msg",
extension: "ext msg",
alphanumeric: "alphanum msg",
integer: "integer msg"
}
},
highlight : function(element) {
$(element).closest('.form-group').removeClass('has-success').addClass('has-error');
},
success : function(element) {
$(element).closest('.form-group').removeClass('has-error');
$(element).remove();
},
errorPlacement : function(error, element) {
element.parent().append(error);
}
});
*/
sb.append("}");
return sb.toString();
}
public String getValidationMessages() {
if (!getRequired()) return null;
StringBuilder sb = new StringBuilder(80);
sb.append(id+": {");
String s = name;
if (OAString.isEmpty(s)) {
s = placeholder;
if (OAString.isEmpty(s)) s = id;
}
sb.append("required: '"+s+" is required'");
//qqqqqq add more later
sb.append("}");
return sb.toString();
}
//qqqqqqqq 20171105 temp so that the attr name is same as attr id (needed by validation.js)
public boolean nameIncludesObjectId = true;
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy