/**
* @class Roo.bootstrap.TextArea
- * @extends Roo.bootstrap.Component
+ * @extends Roo.bootstrap.Input
* Bootstrap TextArea class
* @cfg {Number} cols Specifies the visible width of a text area
* @cfg {Number} rows Specifies the visible number of lines in a text area
- * @cfg {Number} readOnly Specifies that a text area should be read-only
* @cfg {string} wrap (soft|hard)Specifies how the text in a text area is to be wrapped when submitted in a form
- *
+ * @cfg {string} resize (none|both|horizontal|vertical|inherit|initial)
+ * @cfg {string} html text
*
* @constructor
* Create a new TextArea
Roo.extend(Roo.bootstrap.TextArea, Roo.bootstrap.Input, {
- cols : 20,
- rows : 3,
+ cols : false,
+ rows : 5,
readOnly : false,
warp : 'soft',
+ resize : false,
+ value: false,
+ html: false,
getAutoCreate : function(){
- var parent = this.parent();
-
- var align = parent.labelAlign;
+ var align = (!this.labelAlign) ? this.parentLabelAlign() : this.labelAlign;
var id = Roo.id();
var cfg = {};
+ if(this.inputType != 'hidden'){
+ cfg.cls = 'form-group' //input-group
+ }
+
var input = {
tag: 'textarea',
id : id,
warp : this.warp,
- cols : this.cols,
rows : this.rows,
- value : this.value,
+ value : this.value || '',
+ html: this.html || '',
cls : 'form-control',
placeholder : this.placeholder || ''
};
+ if(this.maxLength && this.maxLength != Number.MAX_VALUE){
+ input.maxLength = this.maxLength;
+ }
+
+ if(this.resize){
+ input.style = (typeof(input.style) == 'undefined') ? 'resize:' + this.resize : input.style + 'resize:' + this.resize;
+ }
+
+ if(this.cols){
+ input.cols = this.cols;
+ }
+
+ if (this.readOnly) {
+ input.readonly = true;
+ }
+
if (this.name) {
input.name = this.name;
}
if (this.size) {
- input.cls += ' input-' + this.size;
+ input.cls = (typeof(input.cls) == 'undefined') ? 'input-' + this.size : input.cls + ' input-' + this.size;
}
var settings=this;
var inputblock = input;
+ if(this.hasFeedback && !this.allowBlank){
+
+ var feedback = {
+ tag: 'span',
+ cls: 'glyphicon form-control-feedback'
+ };
+
+ inputblock = {
+ cls : 'has-feedback',
+ cn : [
+ input,
+ feedback
+ ]
+ };
+ }
+
+
if (this.before || this.after) {
inputblock = {
html : this.before
});
}
+
inputblock.cn.push(input);
+
+ if(this.hasFeedback && !this.allowBlank){
+ inputblock.cls += ' has-feedback';
+ inputblock.cn.push(feedback);
+ }
+
if (this.after) {
inputblock.cn.push({
tag :'span',
}
if (align ==='left' && this.fieldLabel.length) {
- Roo.log("left and has label");
- cfg.cn = [
-
- {
- tag: 'label',
- 'for' : id,
- cls : 'control-label col-sm-' + this.labelWidth,
- html : this.fieldLabel
-
- },
- {
- cls : "col-sm-" + (12 - this.labelWidth),
- cn: [
- inputblock
- ]
- }
-
- ];
+ cfg.cn = [
+ {
+ tag: 'label',
+ 'for' : id,
+ cls : 'control-label',
+ html : this.fieldLabel
+ },
+ {
+ cls : "",
+ cn: [
+ inputblock
+ ]
+ }
+
+ ];
+
+ if(this.labelWidth > 12){
+ cfg.cn[0].style = "width: " + this.labelWidth + 'px';
+ }
+
+ if(this.labelWidth < 13 && this.labelmd == 0){
+ this.labelmd = this.labelWidth;
+ }
+
+ if(this.labellg > 0){
+ cfg.cn[0].cls += ' col-lg-' + this.labellg;
+ cfg.cn[1].cls += ' col-lg-' + (12 - this.labellg);
+ }
+
+ if(this.labelmd > 0){
+ cfg.cn[0].cls += ' col-md-' + this.labelmd;
+ cfg.cn[1].cls += ' col-md-' + (12 - this.labelmd);
+ }
+
+ if(this.labelsm > 0){
+ cfg.cn[0].cls += ' col-sm-' + this.labelsm;
+ cfg.cn[1].cls += ' col-sm-' + (12 - this.labelsm);
+ }
+
+ if(this.labelxs > 0){
+ cfg.cn[0].cls += ' col-xs-' + this.labelxs;
+ cfg.cn[1].cls += ' col-xs-' + (12 - this.labelxs);
+ }
+
} else if ( this.fieldLabel.length) {
- Roo.log(" label");
- cfg.cn = [
-
- {
- tag: 'label',
- //cls : 'input-group-addon',
- html : this.fieldLabel
-
- },
-
- inputblock
-
- ];
+ cfg.cn = [
+
+ {
+ tag: 'label',
+ //cls : 'input-group-addon',
+ html : this.fieldLabel
+
+ },
+
+ inputblock
+
+ ];
} else {
-
- Roo.log(" no label && no align");
- cfg.cn = [
-
- inputblock
-
- ];
-
+
+ cfg.cn = [
+
+ inputblock
+
+ ];
}
input.disabled=true;
}
- if (this.readOnly) {
- input.readonly = true;
- }
-
return cfg;
},
/**
- * return the real input element.
+ * return the real textarea element.
*/
inputEl: function ()
{
- return this.el.select('input.form-control',true).first();
+ return this.el.select('textarea.form-control',true).first();
},
- setDisabled : function(v)
+
+ /**
+ * Clear any invalid styles/messages for this field
+ */
+ clearInvalid : function()
{
- var i = this.inputEl().dom;
- if (v) {
- i.removeAttribute('disabled');
+
+ if(!this.el || this.preventMark){ // not rendered
return;
-
}
- i.setAttribute('disabled','true');
- },
- initEvents : function()
- {
- this.inputEl().on("keydown" , this.fireKey, this);
- this.inputEl().on("focus", this.onFocus, this);
- this.inputEl().on("blur", this.onBlur, this);
- this.inputEl().relayEvent('keyup', this);
-
- // reference to original value for reset
- this.originalValue = this.getValue();
- //Roo.form.TextField.superclass.initEvents.call(this);
- if(this.validationEvent == 'keyup'){
- this.validationTask = new Roo.util.DelayedTask(this.validate, this);
- this.inputEl().on('keyup', this.filterValidation, this);
- }
- else if(this.validationEvent !== false){
- this.inputEl().on(this.validationEvent, this.validate, this, {buffer: this.validationDelay});
- }
+ var label = this.el.select('label', true).first();
+ var icon = this.el.select('i.fa-star', true).first();
- if(this.selectOnFocus){
- this.on("focus", this.preFocus, this);
-
- }
- if(this.maskRe || (this.vtype && this.disableKeyFilter !== true && (this.maskRe = Roo.form.VTypes[this.vtype+'Mask']))){
- this.inputEl().on("keypress", this.filterKeys, this);
+ if(label && icon){
+ icon.remove();
}
- /* if(this.grow){
- this.el.on("keyup", this.onKeyUp, this, {buffer:50});
- this.el.on("click", this.autoSize, this);
- }
- */
- if(this.inputEl().is('input[type=password]') && Roo.isSafari){
- this.inputEl().on('keydown', this.SafariOnKeyDown, this);
- }
-
- },
- filterValidation : function(e){
- if(!e.isNavKeyPress()){
- this.validationTask.delay(this.validationDelay);
- }
- },
- /**
- * Validates the field value
- * @return {Boolean} True if the value is valid, else false
- */
- validate : function(){
- //if(this.disabled || this.validateValue(this.processValue(this.getRawValue()))){
- if(this.disabled || this.validateValue(this.getRawValue())){
- this.clearInvalid();
- return true;
- }
- return false;
- },
-
-
- /**
- * Validates a value according to the field's validation rules and marks the field as invalid
- * if the validation fails
- * @param {Mixed} value The value to validate
- * @return {Boolean} True if the value is valid, else false
- */
- validateValue : function(value){
- if(value.length < 1) { // if it's blank
- if(this.allowBlank){
- this.clearInvalid();
- return true;
- }else{
- this.markInvalid(this.blankText);
- return false;
- }
- }
- if(value.length < this.minLength){
- this.markInvalid(String.format(this.minLengthText, this.minLength));
- return false;
- }
- if(value.length > this.maxLength){
- this.markInvalid(String.format(this.maxLengthText, this.maxLength));
- return false;
- }
- if(this.vtype){
- var vt = Roo.form.VTypes;
- if(!vt[this.vtype](value, this)){
- this.markInvalid(this.vtypeText || vt[this.vtype +'Text']);
- return false;
- }
- }
- if(typeof this.validator == "function"){
- var msg = this.validator(value);
- if(msg !== true){
- this.markInvalid(msg);
- return false;
- }
- }
- if(this.regex && !this.regex.test(value)){
- this.markInvalid(this.regexText);
- return false;
- }
- return true;
- },
-
-
-
- // private
- fireKey : function(e){
- //Roo.log('field ' + e.getKey());
- if(e.isNavKeyPress()){
- this.fireEvent("specialkey", this, e);
- }
- },
- focus : function (selectText){
- if(this.rendered){
- this.inputEl().focus();
- if(selectText === true){
- this.inputEl().dom.select();
+ this.el.removeClass( this.validClass);
+ this.inputEl().removeClass('is-invalid');
+
+ if(this.hasFeedback && this.inputType != 'hidden' && !this.allowBlank){
+
+ var feedback = this.el.select('.form-control-feedback', true).first();
+
+ if(feedback){
+ this.el.select('.form-control-feedback', true).first().removeClass(this.invalidFeedbackClass);
}
+
}
- return this;
- } ,
-
- onFocus : function(){
- if(!Roo.isOpera && this.focusClass){ // don't touch in Opera
- // this.el.addClass(this.focusClass);
- }
- if(!this.hasFocus){
- this.hasFocus = true;
- this.startValue = this.getValue();
- this.fireEvent("focus", this);
- }
- },
-
- beforeBlur : Roo.emptyFn,
-
-
- // private
- onBlur : function(){
- this.beforeBlur();
- if(!Roo.isOpera && this.focusClass){ // don't touch in Opera
- //this.el.removeClass(this.focusClass);
- }
- this.hasFocus = false;
- if(this.validationEvent !== false && this.validateOnBlur && this.validationEvent != "blur"){
- this.validate();
- }
- var v = this.getValue();
- if(String(v) !== String(this.startValue)){
- this.fireEvent('change', this, v, this.startValue);
- }
- this.fireEvent("blur", this);
- },
-
- /**
- * Resets the current field value to the originally loaded value and clears any validation messages
- */
- reset : function(){
- this.setValue(this.originalValue);
- this.clearInvalid();
- },
- /**
- * Returns the name of the field
- * @return {Mixed} name The name field
- */
- getName: function(){
- return this.name;
- },
- /**
- * Returns the normalized data value (undefined or emptyText will be returned as ''). To return the raw value see {@link #getRawValue}.
- * @return {Mixed} value The field value
- */
- getValue : function(){
- var v = this.inputEl().getValue();
- return v;
- },
- /**
- * Returns the raw data value which may or may not be a valid, defined value. To return a normalized value see {@link #getValue}.
- * @return {Mixed} value The field value
- */
- getRawValue : function(){
- var v = this.inputEl().getValue();
- return v;
- },
-
- /**
- * Sets the underlying DOM field's value directly, bypassing validation. To set the value with validation see {@link #setValue}.
- * @param {Mixed} value The value to set
- */
- setRawValue : function(v){
- return this.inputEl().dom.value = (v === null || v === undefined ? '' : v);
- },
-
- selectText : function(start, end){
- var v = this.getRawValue();
- if(v.length > 0){
- start = start === undefined ? 0 : start;
- end = end === undefined ? v.length : end;
- var d = this.inputEl().dom;
- if(d.setSelectionRange){
- d.setSelectionRange(start, end);
- }else if(d.createTextRange){
- var range = d.createTextRange();
- range.moveStart("character", start);
- range.moveEnd("character", v.length-end);
- range.select();
- }
- }
+ this.fireEvent('valid', this);
},
- /**
- * Sets a data value into the field and validates it. To set the value directly without validation see {@link #setRawValue}.
- * @param {Mixed} value The value to set
+ /**
+ * Mark this field as valid
*/
- setValue : function(v){
- this.value = v;
- if(this.rendered){
- this.inputEl().dom.value = (v === null || v === undefined ? '' : v);
- this.validate();
- }
- },
-
- /*
- processValue : function(value){
- if(this.stripCharsRe){
- var newValue = value.replace(this.stripCharsRe, '');
- if(newValue !== value){
- this.setRawValue(newValue);
- return newValue;
- }
+ markValid : function()
+ {
+ if(!this.el || this.preventMark){ // not rendered
+ return;
}
- return value;
- },
- */
- preFocus : function(){
- if(this.selectOnFocus){
- this.inputEl().dom.select();
+ this.el.removeClass([this.invalidClass, this.validClass]);
+ this.inputEl().removeClass(['is-valid', 'is-invalid']);
+
+ var feedback = this.el.select('.form-control-feedback', true).first();
+
+ if(feedback){
+ this.el.select('.form-control-feedback', true).first().removeClass([this.invalidFeedbackClass, this.validFeedbackClass]);
}
- },
- filterKeys : function(e){
- var k = e.getKey();
- if(!Roo.isIE && (e.isNavKeyPress() || k == e.BACKSPACE || (k == e.DELETE && e.button == -1))){
+
+ if(this.disabled || this.allowBlank){
return;
}
- var c = e.getCharCode(), cc = String.fromCharCode(c);
- if(Roo.isIE && (e.isSpecialKey() || !cc)){
- return;
+
+ var label = this.el.select('label', true).first();
+ var icon = this.el.select('i.fa-star', true).first();
+
+ if(label && icon){
+ icon.remove();
}
- if(!this.maskRe.test(cc)){
- e.stopEvent();
+ if (Roo.bootstrap.version == 3) {
+ this.el.addClass(this.validClass);
+ } else {
+ this.inputEl().addClass('is-valid');
}
- },
- /**
- * Clear any invalid styles/messages for this field
- */
- clearInvalid : function(){
- if(!this.el || this.preventMark){ // not rendered
- return;
- }
- this.el.removeClass(this.invalidClass);
- /*
- switch(this.msgTarget){
- case 'qtip':
- this.el.dom.qtip = '';
- break;
- case 'title':
- this.el.dom.title = '';
- break;
- case 'under':
- if(this.errorEl){
- Roo.form.Field.msgFx[this.msgFx].hide(this.errorEl, this);
- }
- break;
- case 'side':
- if(this.errorIcon){
- this.errorIcon.dom.qtip = '';
- this.errorIcon.hide();
- this.un('resize', this.alignErrorIcon, this);
- }
- break;
- default:
- var t = Roo.getDom(this.msgTarget);
- t.innerHTML = '';
- t.style.display = 'none';
- break;
+
+ if(this.hasFeedback && this.inputType != 'hidden' && !this.allowBlank && (this.getValue().length || this.forceFeedback)){
+
+ var feedback = this.el.select('.form-control-feedback', true).first();
+
+ if(feedback){
+ this.el.select('.form-control-feedback', true).first().removeClass([this.invalidFeedbackClass, this.validFeedbackClass]);
+ this.el.select('.form-control-feedback', true).first().addClass([this.validFeedbackClass]);
+ }
+
}
- */
+
this.fireEvent('valid', this);
},
+
/**
* Mark this field as invalid
* @param {String} msg The validation message
*/
- markInvalid : function(msg){
+ markInvalid : function(msg)
+ {
if(!this.el || this.preventMark){ // not rendered
return;
}
- this.el.addClass(this.invalidClass);
- /*
- msg = msg || this.invalidText;
- switch(this.msgTarget){
- case 'qtip':
- this.el.dom.qtip = msg;
- this.el.dom.qclass = 'x-form-invalid-tip';
- if(Roo.QuickTips){ // fix for floating editors interacting with DND
- Roo.QuickTips.enable();
- }
- break;
- case 'title':
- this.el.dom.title = msg;
- break;
- case 'under':
- if(!this.errorEl){
- var elp = this.el.findParent('.x-form-element', 5, true);
- this.errorEl = elp.createChild({cls:'x-form-invalid-msg'});
- this.errorEl.setWidth(elp.getWidth(true)-20);
- }
- this.errorEl.update(msg);
- Roo.form.Field.msgFx[this.msgFx].show(this.errorEl, this);
- break;
- case 'side':
- if(!this.errorIcon){
- var elp = this.el.findParent('.x-form-element', 5, true);
- this.errorIcon = elp.createChild({cls:'x-form-invalid-icon'});
- }
- this.alignErrorIcon();
- this.errorIcon.dom.qtip = msg;
- this.errorIcon.dom.qclass = 'x-form-invalid-tip';
- this.errorIcon.show();
- this.on('resize', this.alignErrorIcon, this);
- break;
- default:
- var t = Roo.getDom(this.msgTarget);
- t.innerHTML = msg;
- t.style.display = this.msgDisplay;
- break;
- }
- */
- this.fireEvent('invalid', this, msg);
- },
- // private
- SafariOnKeyDown : function(event)
- {
- // this is a workaround for a password hang bug on chrome/ webkit.
- var isSelectAll = false;
+ this.el.removeClass([this.invalidClass, this.validClass]);
+ this.inputEl().removeClass(['is-valid', 'is-invalid']);
- if(this.inputEl().dom.selectionEnd > 0){
- isSelectAll = (this.inputEl().dom.selectionEnd - this.inputEl().dom.selectionStart - this.getValue().length == 0) ? true : false;
+ var feedback = this.el.select('.form-control-feedback', true).first();
+
+ if(feedback){
+ this.el.select('.form-control-feedback', true).first().removeClass([this.invalidFeedbackClass, this.validFeedbackClass]);
}
- if(((event.getKey() == 8 || event.getKey() == 46) && this.getValue().length ==1)){ // backspace and delete key
- event.preventDefault();
- this.setValue('');
+
+ if(this.disabled || this.allowBlank){
return;
}
- if(isSelectAll){ // backspace and delete key
+ var label = this.el.select('label', true).first();
+ var icon = this.el.select('i.fa-star', true).first();
+
+ if(!this.getValue().length && label && !icon){
+ this.el.createChild({
+ tag : 'i',
+ cls : 'text-danger fa fa-lg fa-star',
+ tooltip : 'This field is required',
+ style : 'margin-right:5px;'
+ }, label, true);
+ }
+
+ if (Roo.bootstrap.version == 3) {
+ this.el.addClass(this.invalidClass);
+ } else {
+ this.inputEl().addClass('is-invalid');
+ }
+
+ // fixme ... this may be depricated need to test..
+ if(this.hasFeedback && this.inputType != 'hidden' && !this.allowBlank){
- event.preventDefault();
- // this is very hacky as keydown always get's upper case.
- //
- var cc = String.fromCharCode(event.getCharCode());
- this.setValue( event.shiftKey ? cc : cc.toLowerCase());
+ var feedback = this.el.select('.form-control-feedback', true).first();
+
+ if(feedback){
+ this.el.select('.form-control-feedback', true).first().removeClass([this.invalidFeedbackClass, this.validFeedbackClass]);
+
+ if(this.getValue().length || this.forceFeedback){
+ this.el.select('.form-control-feedback', true).first().addClass([this.invalidFeedbackClass]);
+ }
+
+ }
}
-
+ this.fireEvent('invalid', this, msg);
}
});