@qooxdoo/framework
Version:
The JS Framework for Coders
282 lines (239 loc) • 8.01 kB
JavaScript
/* ************************************************************************
qooxdoo - the new era of web development
http://qooxdoo.org
Copyright:
2004-2008 1&1 Internet AG, Germany, http://www.1und1.de
License:
MIT: https://opensource.org/licenses/MIT
See the LICENSE file in the project's top-level directory for details.
Authors:
* Sebastian Werner (wpbasti)
* Andreas Ecker (ecker)
======================================================================
This class contains code based on the following work:
* jQuery
http://jquery.com
Version 1.3.1
Copyright:
2009 John Resig
License:
MIT: http://www.opensource.org/licenses/mit-license.php
************************************************************************ */
/**
* Cross browser abstractions to work with input elements.
*/
qx.Bootstrap.define("qx.bom.Input", {
/*
*****************************************************************************
STATICS
*****************************************************************************
*/
statics: {
/** @type {Map} Internal data structures with all supported input types */
__types: {
textarea: true,
select: true,
button: true,
checkbox: true,
color: true,
date: true,
"datetime-local": true,
email: true,
file: true,
hidden: true,
image: true,
month: true,
number: true,
password: true,
radio: true,
range: true,
reset: true,
search: true,
submit: true,
tel: true,
text: true,
time: true,
url: true,
week: true
},
/**
* Creates an DOM input/textarea/select element.
*
* Attributes may be given directly with this call. This is critical
* for some attributes e.g. name, type, ... in many clients.
*
* Note: <code>select</code> and <code>textarea</code> elements are created
* using the identically named <code>type</code>.
*
* @param type {String} Any valid type for HTML, <code>select</code>
* and <code>textarea</code>
* @param attributes {Map} Map of attributes to apply
* @param win {Window} Window to create the element for
* @return {Element} The created input node
*/
create(type, attributes, win) {
if (qx.core.Environment.get("qx.debug")) {
qx.core.Assert.assertKeyInMap(
type,
this.__types,
"Unsupported input type."
);
}
// Work on a copy to not modify given attributes map
var attributes = attributes ? qx.lang.Object.clone(attributes) : {};
var tag;
if (type === "textarea" || type === "select") {
tag = type;
} else {
tag = "input";
attributes.type = type;
}
return qx.dom.Element.create(tag, attributes, win);
},
/**
* Applies the given value to the element.
*
* Normally the value is given as a string/number value and applied
* to the field content (textfield, textarea) or used to
* detect whether the field is checked (checkbox, radiobutton).
*
* Supports array values for selectboxes (multiple-selection)
* and checkboxes or radiobuttons (for convenience).
*
* Please note: To modify the value attribute of a checkbox or
* radiobutton use {@link qx.bom.element.Attribute#set} instead.
*
* @param element {Element} element to update
* @param value {String|Number|Array} the value to apply
*/
setValue(element, value) {
var tag = element.nodeName.toLowerCase();
var type = element.type;
var Type = qx.lang.Type;
if (typeof value === "number") {
value += "";
}
if (type === "checkbox" || type === "radio") {
if (Type.isArray(value)) {
element.checked = value.includes(element.value);
} else {
element.checked = element.value == value;
}
} else if (tag === "select") {
var isArray = Type.isArray(value);
var options = element.options;
var subel, subval;
for (var i = 0, l = options.length; i < l; i++) {
subel = options[i];
subval = subel.getAttribute("value");
if (subval == null) {
subval = subel.text;
}
subel.selected = isArray ? value.includes(subval) : value == subval;
}
if (isArray && value.length == 0) {
element.selectedIndex = -1;
}
} else if (
(type === "text" || type === "textarea") &&
qx.core.Environment.get("engine.name") == "mshtml"
) {
// These flags are required to detect self-made property-change
// events during value modification. They are used by the Input
// event handler to filter events.
element.$$inValueSet = true;
element.value = value;
element.$$inValueSet = null;
} else {
element.value = value;
}
},
/**
* Returns the currently configured value.
*
* Works with simple input fields as well as with
* select boxes or option elements.
*
* Returns an array in cases of multi-selection in
* select boxes but in all other cases a string.
*
* @param element {Element} DOM element to query
* @return {String|Array} The value of the given element
*/
getValue(element) {
var tag = element.nodeName.toLowerCase();
if (tag === "option") {
return (element.attributes.value || {}).specified
? element.value
: element.text;
}
if (tag === "select") {
var index = element.selectedIndex;
// Nothing was selected
if (index < 0) {
return null;
}
var values = [];
var options = element.options;
var one = element.type == "select-one";
var clazz = qx.bom.Input;
var value;
// Loop through all the selected options
for (
var i = one ? index : 0, max = one ? index + 1 : options.length;
i < max;
i++
) {
var option = options[i];
if (option.selected) {
// Get the specific value for the option
value = clazz.getValue(option);
// We don't need an array for one selects
if (one) {
return value;
}
// Multi-Selects return an array
values.push(value);
}
}
return values;
} else {
return (element.value || "").replace(/\r/g, "");
}
},
/**
* Sets the text wrap behaviour of a text area element.
* This property uses the attribute "wrap" respectively
* the style property "whiteSpace"
*
* @signature function(element, wrap)
* @param element {Element} DOM element to modify
* @param wrap {Boolean} Whether to turn text wrap on or off.
*/
setWrap: qx.core.Environment.select("engine.name", {
mshtml(element, wrap) {
var wrapValue = wrap ? "soft" : "off";
// Explicitly set overflow-y CSS property to auto when wrapped,
// allowing the vertical scroll-bar to appear if necessary
var styleValue = wrap ? "auto" : "";
element.wrap = wrapValue;
element.style.overflowY = styleValue;
},
gecko(element, wrap) {
var wrapValue = wrap ? "soft" : "off";
var styleValue = wrap ? "" : "auto";
element.setAttribute("wrap", wrapValue);
element.style.overflow = styleValue;
},
webkit(element, wrap) {
var wrapValue = wrap ? "soft" : "off";
var styleValue = wrap ? "" : "auto";
element.setAttribute("wrap", wrapValue);
element.style.overflow = styleValue;
},
default(element, wrap) {
element.style.whiteSpace = wrap ? "normal" : "nowrap";
}
})
}
});