dijit
Version:
Dijit provides a complete collection of user interface controls based on Dojo, giving you the power to create web applications that are highly optimized for usability, performance, internationalization, accessibility, but above all deliver an incredible u
176 lines (154 loc) • 6.01 kB
JavaScript
define([
"dojo/_base/declare", // declare
"dojo/dom-construct", // domConstruct.create
"dojo/dom-style", // domStyle.getComputedStyle
"dojo/_base/kernel", // kernel.deprecated
"dojo/_base/lang", // lang.hitch
"dojo/on",
"dojo/sniff", // has("ie") has("mozilla")
"./_FormValueWidget",
"./_TextBoxMixin",
"dojo/text!./templates/TextBox.html",
"../main" // to export dijit._setSelectionRange, remove in 2.0
], function(declare, domConstruct, domStyle, kernel, lang, on, has,
_FormValueWidget, _TextBoxMixin, template, dijit){
// module:
// dijit/form/TextBox
var TextBox = declare("dijit.form.TextBox" + (has("dojo-bidi") ? "_NoBidi" : ""), [_FormValueWidget, _TextBoxMixin], {
// summary:
// A base class for textbox form inputs
templateString: template,
_singleNodeTemplate: '<input class="dijit dijitReset dijitLeft dijitInputField" data-dojo-attach-point="textbox,focusNode" autocomplete="off" type="${type}" ${!nameAttrSetting} />',
_buttonInputDisabled: has("ie") ? "disabled" : "", // allows IE to disallow focus, but Firefox cannot be disabled for mousedown events
baseClass: "dijitTextBox",
postMixInProperties: function(){
var type = this.type.toLowerCase();
if(this.templateString && this.templateString.toLowerCase() == "input" || ((type == "hidden" || type == "file") && this.templateString == this.constructor.prototype.templateString)){
this.templateString = this._singleNodeTemplate;
}
this.inherited(arguments);
},
postCreate: function(){
this.inherited(arguments);
if(has("ie") < 9){
// IE INPUT tag fontFamily has to be set directly using STYLE
// the defer gives IE a chance to render the TextBox and to deal with font inheritance
this.defer(function(){
try{
var s = domStyle.getComputedStyle(this.domNode); // can throw an exception if widget is immediately destroyed
if(s){
var ff = s.fontFamily;
if(ff){
var inputs = this.domNode.getElementsByTagName("INPUT");
if(inputs){
for(var i=0; i < inputs.length; i++){
inputs[i].style.fontFamily = ff;
}
}
}
}
}catch(e){/*when used in a Dialog, and this is called before the dialog is
shown, s.fontFamily would trigger "Invalid Argument" error.*/}
});
}
},
_setPlaceHolderAttr: function(v){
this._set("placeHolder", v);
if(!this._phspan){
this._attachPoints.push('_phspan');
this._phspan = domConstruct.create('span', {
// dijitInputField class gives placeHolder same padding as the input field
// parent node already has dijitInputField class but it doesn't affect this <span>
// since it's position: absolute.
className: 'dijitPlaceHolder dijitInputField'
}, this.textbox, 'after');
this.own(
on(this._phspan, "mousedown", function(evt){ evt.preventDefault(); }),
on(this._phspan, "touchend, pointerup, MSPointerUp", lang.hitch(this, function(){
// If the user clicks placeholder rather than the <input>, need programmatic focus. Normally this
// is done in _FormWidgetMixin._onFocus() but after [30663] it's done on a delay, which is ineffective.
this.focus();
}))
);
}
this._phspan.innerHTML="";
this._phspan.appendChild(this._phspan.ownerDocument.createTextNode(v));
this._updatePlaceHolder();
},
_onInput: function(/*Event*/ evt){
// summary:
// Called AFTER the input event has happened
// See if the placeHolder text should be removed or added while editing.
this.inherited(arguments);
this._updatePlaceHolder();
},
_updatePlaceHolder: function(){
if(this._phspan){
this._phspan.style.display = (this.placeHolder && !this.textbox.value) ? "" : "none";
}
},
_setValueAttr: function(value, /*Boolean?*/ priorityChange, /*String?*/ formattedValue){
this.inherited(arguments);
this._updatePlaceHolder();
},
getDisplayedValue: function(){
// summary:
// Deprecated. Use get('displayedValue') instead.
// tags:
// deprecated
kernel.deprecated(this.declaredClass+"::getDisplayedValue() is deprecated. Use get('displayedValue') instead.", "", "2.0");
return this.get('displayedValue');
},
setDisplayedValue: function(/*String*/ value){
// summary:
// Deprecated. Use set('displayedValue', ...) instead.
// tags:
// deprecated
kernel.deprecated(this.declaredClass+"::setDisplayedValue() is deprecated. Use set('displayedValue', ...) instead.", "", "2.0");
this.set('displayedValue', value);
},
_onBlur: function(e){
if(this.disabled){ return; }
this.inherited(arguments);
this._updatePlaceHolder();
if(has("mozilla")){
if(this.selectOnClick){
// clear selection so that the next mouse click doesn't reselect
this.textbox.selectionStart = this.textbox.selectionEnd = undefined;
}
}
},
_onFocus: function(/*String*/ by){
if(this.disabled || this.readOnly){ return; }
this.inherited(arguments);
this._updatePlaceHolder();
}
});
if(has("ie") < 9){
TextBox.prototype._isTextSelected = function(){
var range = this.ownerDocument.selection.createRange();
var parent = range.parentElement();
return parent == this.textbox && range.text.length > 0;
};
// Overrides definition of _setSelectionRange from _TextBoxMixin (TODO: move to _TextBoxMixin.js?)
dijit._setSelectionRange = _TextBoxMixin._setSelectionRange = function(/*DomNode*/ element, /*Number?*/ start, /*Number?*/ stop){
if(element.createTextRange){
var r = element.createTextRange();
r.collapse(true);
r.moveStart("character", -99999); // move to 0
r.moveStart("character", start); // delta from 0 is the correct position
r.moveEnd("character", stop-start);
r.select();
}
}
}
if(has("dojo-bidi")){
TextBox = declare("dijit.form.TextBox", TextBox, {
_setPlaceHolderAttr: function(v){
this.inherited(arguments);
this.applyTextDir(this._phspan);
}
});
}
return TextBox;
});