@qooxdoo/framework
Version:
The JS Framework for Coders
287 lines (240 loc) • 7.87 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 :
{
text : 1,
textarea : 1,
select : 1,
checkbox : 1,
radio : 1,
password : 1,
hidden : 1,
submit : 1,
image : 1,
file : 1,
search : 1,
reset : 1,
button : 1
},
/**
* 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 : function(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 : function(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 : function(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" : function(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" : function(element, wrap)
{
var wrapValue = wrap ? "soft" : "off";
var styleValue = wrap ? "" : "auto";
element.setAttribute("wrap", wrapValue);
element.style.overflow = styleValue;
},
"webkit" : function(element, wrap)
{
var wrapValue = wrap ? "soft" : "off";
var styleValue = wrap ? "" : "auto";
element.setAttribute("wrap", wrapValue);
element.style.overflow = styleValue;
},
"default" : function(element, wrap) {
element.style.whiteSpace = wrap ? "normal" : "nowrap";
}
})
}
});