You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1021 lines
25 KiB
1021 lines
25 KiB
define([ |
|
"dojo/_base/kernel", |
|
"dojo/_base/lang", |
|
"dojo/_base/array", |
|
"dojo/_base/json", |
|
"dojo/_base/fx", |
|
"dojo/_base/window", |
|
"dojo/_base/connect", |
|
"dojo/dom-class", |
|
"dojo/dom-style", |
|
"dojo/dom-construct", |
|
"dojo/dom-geometry", |
|
"dojo/keys", |
|
"dijit/_Widget", |
|
"dijit/_TemplatedMixin", |
|
"dijit/form/_FormValueWidget", |
|
"dijit/form/ValidationTextBox", |
|
"dijit/InlineEditBox", |
|
"dojo/i18n!dijit/nls/common", |
|
"dojo/_base/declare" |
|
], function(kernel, lang, array, jsonUtil, fx, win, connect, domClass, domStyle, domConstruct, domGeometry, keys, Widget, TemplatedMixin, FormValueWidget, ValidationTextBox, InlineEditBox, i18nCommon, declare){ |
|
kernel.experimental("dojox.form.ListInput"); |
|
|
|
/*===== |
|
var __Constraints = { |
|
// locale: String |
|
// locale used for validation, picks up value from this widget's lang attribute |
|
// _flags_: anything |
|
// various flags passed to pattern function |
|
}; |
|
=====*/ |
|
|
|
var ListInput = declare("dojox.form.ListInput", [FormValueWidget], |
|
{ |
|
// summary: |
|
// An automatic list maker |
|
// description: |
|
// you can add value to list with add method. |
|
// you can only remove by clicking close button |
|
|
|
constructor: function(){ |
|
this._items = []; |
|
|
|
|
|
if(!lang.isArray(this.delimiter)){ |
|
this.delimiter=[this.delimiter]; |
|
} |
|
var r="("+this.delimiter.join("|")+")?"; |
|
this.regExp="^"+this.regExp+r+"$"; |
|
}, |
|
|
|
// inputClass: String |
|
// Class which will be used to create the input box. You can implements yours. |
|
// It must be a widget, focusNode or domNode must have "onkeydown" event |
|
// It must have .attr("value") to get value |
|
// It also must implement an (or more) handler for the "onChange" method |
|
inputClass: "dojox.form._ListInputInputBox", |
|
|
|
// inputHandler: String|Array |
|
// The widget will connect on all handler to check input value |
|
// You can use comma separated list |
|
inputHandler: "onChange", |
|
|
|
// inputProperties: String|Object |
|
// Properties used to create input box |
|
// If String, it must be a valid JSON |
|
inputProperties: { |
|
minWidth:50 |
|
}, |
|
|
|
// submitOnlyValidValue: Boolean |
|
// If true, only valid value will be submitted with form |
|
submitOnlyValidValue:true, |
|
|
|
// useOnBlur: Boolean |
|
// If true, onBlur event do a validate (like pressing ENTER) |
|
useOnBlur:true, |
|
|
|
// readOnlyInput: Boolean |
|
// if false, the list will be editable |
|
// Can only be set when instantiate |
|
readOnlyInput: false, |
|
|
|
// maxItems: Int |
|
// Specify max item the list can have |
|
// null = infinity |
|
maxItems: null, |
|
|
|
// showCloseButtonWhenValid: Boolean |
|
// if true, a close button will be added on valid item |
|
showCloseButtonWhenValid: true, |
|
|
|
// showCloseButtonWhenInvalid: Boolean |
|
// if true, a close button will be added on invalid item |
|
showCloseButtonWhenInvalid: true, |
|
|
|
// regExp: [extension protected] String |
|
// regular expression string used to validate the input |
|
// Do not specify both regExp and regExpGen |
|
regExp: ".*", //"[a-zA-Z.-_]+@[a-zA-Z.-_]+.[a-zA-Z]+", |
|
|
|
// delimiter: String|Array |
|
// delimiter for the string. Every match will be splitted. |
|
// The string can contain only one delimiter. |
|
delimiter: ",", |
|
|
|
// constraints: __Constraints |
|
// user-defined object needed to pass parameters to the validator functions |
|
constraints: {}, |
|
|
|
baseClass:"dojoxListInput", |
|
|
|
type: "select", |
|
|
|
value: "", |
|
|
|
templateString: "<div dojoAttachPoint=\"focusNode\" class=\"dijit dijitReset dijitLeft dojoxListInput\"><select dojoAttachpoint=\"_selectNode\" multiple=\"multiple\" class=\"dijitHidden\" ${!nameAttrSetting}></select><ul dojoAttachPoint=\"_listInput\"><li dojoAttachEvent=\"onclick: _onClick\" class=\"dijitInputField dojoxListInputNode dijitHidden\" dojoAttachPoint=\"_inputNode\"></li></ul></div>", |
|
|
|
_setNameAttr: "_selectNode", |
|
|
|
// useAnim: Boolean |
|
// If true, then item will use an animation to show hide itself |
|
useAnim: true, |
|
|
|
// duration: Integer |
|
// Animation duration |
|
duration: 500, |
|
|
|
// easingIn: function |
|
// function used to easing on fadeIn end |
|
easingIn: null, |
|
|
|
// easingOut: function |
|
// function used to easing on fadeOut end |
|
easingOut: null, |
|
|
|
// readOnlyItem: Boolean |
|
// If true, items can be edited |
|
// Can only be set when instantiate |
|
readOnlyItem: false, |
|
|
|
// useArrowForEdit: Boolean |
|
// If true, arraow left and right can be used for editing |
|
// Can only be set when instantiate |
|
useArrowForEdit: true, |
|
|
|
// _items: Array |
|
// Array of widget. |
|
// Contain all reference to _ListInputInputItem |
|
_items: null, |
|
|
|
// _lastAddedItem: Widget |
|
// Contain a reference to the last created item |
|
_lastAddedItem: null, |
|
|
|
// _currentItem: Widget |
|
// Widget currently in edition |
|
_currentItem: null, |
|
|
|
// _input: Widget |
|
// Widget use for input box |
|
_input: null, |
|
|
|
// _count: Int |
|
// Count items |
|
_count: 0, |
|
|
|
postCreate: function(){ |
|
// summary: |
|
// If closeButton is used, add a class |
|
this.inherited(arguments); |
|
this._createInputBox(); |
|
}, |
|
|
|
_setReadOnlyInputAttr: function(/*Boolean*/ value){ |
|
// summary: |
|
// Change status and if needed, create the inputbox |
|
// tags: |
|
// private |
|
if(!this._started){ return this._createInputBox(); } |
|
this.readOnlyInput = value; |
|
this._createInputBox(); |
|
}, |
|
|
|
_setReadOnlyItemAttr: function(/*Boolean*/ value){ |
|
// summary: |
|
// set read only items |
|
// tags: |
|
// private |
|
if(!this._started){ return; } |
|
for(var i in this._items){ |
|
this._items[i].set("readOnlyItem", value); |
|
} |
|
}, |
|
|
|
_createInputBox: function(){ |
|
// summary: |
|
// Create the input box |
|
// tags: |
|
// private |
|
domClass.toggle(this._inputNode, "dijitHidden", this.readOnlyInput); |
|
if(this.readOnlyInput){ return; } |
|
if(this._input){ return; } |
|
|
|
if(this.inputHandler === null){ |
|
console.warn("you must add some handler to connect to input field"); |
|
return false; |
|
} |
|
if(lang.isString(this.inputHandler)){ |
|
this.inputHandler = this.inputHandler.split(","); |
|
} |
|
if(lang.isString(this.inputProperties)){ |
|
this.inputProperties = jsonUtil.fromJson(this.inputProperties); |
|
} |
|
|
|
|
|
var input = lang.getObject(this.inputClass, false); |
|
|
|
this.inputProperties.regExp = this.regExpGen(this.constraints); |
|
|
|
this._input = new input(this.inputProperties); |
|
this._input.startup(); |
|
this._inputNode.appendChild(this._input.domNode); |
|
array.forEach(this.inputHandler, function(handler){ |
|
this.connect(this._input,lang.trim(handler),"_onHandler"); |
|
},this); |
|
|
|
this.connect(this._input, "onKeyDown", "_inputOnKeyDown"); |
|
this.connect(this._input, "onBlur", "_inputOnBlur"); |
|
}, |
|
|
|
compare: function(/*Array*/ val1, /*Array*/ val2){ |
|
// summary: |
|
// Compare 2 values (as returned by attr('value') for this widget). |
|
// tags: |
|
// protected |
|
val1 = val1.join(","); |
|
val2 = val2.join(","); |
|
if(val1 > val2){ |
|
return 1; |
|
}else if(val1 < val2){ |
|
return -1; |
|
}else{ |
|
return 0; |
|
} |
|
}, |
|
|
|
add: function(/*String|Array*/ values){ |
|
// summary: |
|
// Create new list element |
|
if(this._count>=this.maxItems && this.maxItems !== null){return;} |
|
this._lastValueReported = this._getValues(); |
|
|
|
if(!lang.isArray(values)){ |
|
values = [values]; |
|
} |
|
|
|
for(var i in values){ |
|
var value=values[i]; |
|
if(value === "" || typeof value != "string"){ |
|
continue; |
|
} |
|
this._count++; |
|
var re = new RegExp(this.regExpGen(this.constraints)); |
|
|
|
this._lastAddedItem = new _ListInputInputItem({ |
|
"index" : this._items.length, |
|
readOnlyItem : this.readOnlyItem, |
|
value : value, |
|
regExp: this.regExpGen(this.constraints) |
|
}); |
|
this._lastAddedItem.startup(); |
|
|
|
this._testItem(this._lastAddedItem,value); |
|
|
|
this._lastAddedItem.onClose = lang.hitch(this,"_onItemClose",this._lastAddedItem); |
|
this._lastAddedItem.onChange = lang.hitch(this,"_onItemChange",this._lastAddedItem); |
|
this._lastAddedItem.onEdit = lang.hitch(this,"_onItemEdit",this._lastAddedItem); |
|
this._lastAddedItem.onKeyDown = lang.hitch(this,"_onItemKeyDown",this._lastAddedItem); |
|
|
|
if(this.useAnim){ |
|
domStyle.set(this._lastAddedItem.domNode, {opacity:0, display:""}); |
|
} |
|
|
|
this._placeItem(this._lastAddedItem.domNode); |
|
|
|
if(this.useAnim){ |
|
var anim = fx.fadeIn({ |
|
node : this._lastAddedItem.domNode, |
|
duration : this.duration, |
|
easing : this.easingIn |
|
}).play(); |
|
} |
|
|
|
this._items[this._lastAddedItem.index] = this._lastAddedItem; |
|
|
|
if(this._onChangeActive && this.intermediateChanges){ this.onChange(value); } |
|
|
|
if(this._count>=this.maxItems && this.maxItems !== null){ |
|
break; |
|
} |
|
} |
|
|
|
this._updateValues(); |
|
if(this._lastValueReported.length==0){ |
|
this._lastValueReported = this.value; |
|
} |
|
|
|
if(!this.readOnlyInput){ |
|
this._input.set("value", ""); |
|
} |
|
|
|
if(this._onChangeActive){ this.onChange(this.value); } |
|
|
|
this._setReadOnlyWhenMaxItemsReached(); |
|
}, |
|
|
|
_setReadOnlyWhenMaxItemsReached: function(){ |
|
// summary: |
|
// set input to readonly when max is reached |
|
// tags: |
|
// private |
|
this.set("readOnlyInput",(this._count>=this.maxItems && this.maxItems !== null)); |
|
}, |
|
|
|
_setSelectNode: function(){ |
|
// summary: |
|
// put all item in the select (for a submit) |
|
// tags: |
|
// private |
|
this._selectNode.options.length = 0; |
|
|
|
var values=this.submitOnlyValidValue?this.get("MatchedValue"):this.value; |
|
|
|
if(!lang.isArray(values)){ |
|
return; |
|
} |
|
array.forEach(values,function(item){ |
|
this._selectNode.options[this._selectNode.options.length]=new Option(item,item,true,true); |
|
},this); |
|
}, |
|
|
|
_placeItem: function(/*DomNode*/ node){ |
|
// summary: |
|
// Place item in the list |
|
// tags: |
|
// private |
|
domConstruct.place(node,this._inputNode, "before"); |
|
}, |
|
|
|
_getCursorPos: function(/*DomNode*/ node){ |
|
// summary: |
|
// get current cursor pos |
|
// tags: |
|
// private |
|
if(typeof node.selectionStart != 'undefined'){ |
|
return node.selectionStart; |
|
} |
|
|
|
// IE Support |
|
try{ node.focus(); }catch(e){} |
|
var range = node.createTextRange(); |
|
range.moveToBookmark(win.doc.selection.createRange().getBookmark()); |
|
range.moveEnd('character', node.value.length); |
|
try{ |
|
return node.value.length - range.text.length; |
|
}finally{ range=null; } |
|
}, |
|
|
|
_onItemClose: function(/*dijit/_Widget*/ item){ |
|
// summary: |
|
// Destroy a list element when close button is clicked |
|
// tags: |
|
// private |
|
if(this.disabled){ return; } |
|
|
|
if(this.useAnim){ |
|
var anim = fx.fadeOut({ |
|
node : item.domNode, |
|
duration : this.duration, |
|
easing : this.easingOut, |
|
onEnd : lang.hitch(this, "_destroyItem", item) |
|
}).play(); |
|
}else{ |
|
this._destroyItem(item); |
|
} |
|
}, |
|
|
|
_onItemKeyDown: function(/*dijit/_Widget*/ item, /*Event*/ e){ |
|
// summary: |
|
// Call when item get a keypress |
|
// tags: |
|
// private |
|
if(this.readOnlyItem || !this.useArrowForEdit){ return; } |
|
|
|
if(e.keyCode == keys.LEFT_ARROW && this._getCursorPos(e.target)==0){ |
|
this._editBefore(item); |
|
}else if(e.keyCode == keys.RIGHT_ARROW && this._getCursorPos(e.target)==e.target.value.length){ |
|
this._editAfter(item); |
|
} |
|
}, |
|
|
|
_editBefore: function(/*widget*/ item){ |
|
// summary: |
|
// move trough items |
|
// tags: |
|
// private |
|
this._currentItem = this._getPreviousItem(item); |
|
if(this._currentItem !== null){ |
|
this._currentItem.edit(); |
|
} |
|
}, |
|
_editAfter: function(/*widget*/ item){ |
|
// summary: |
|
// move trough items |
|
// tags: |
|
// private |
|
this._currentItem = this._getNextItem(item); |
|
if(this._currentItem !== null){ |
|
this._currentItem.edit(); |
|
} |
|
|
|
if(!this.readOnlyInput){ |
|
if(this._currentItem === null){ |
|
//no more item ? |
|
//so edit input (if available) |
|
this._focusInput(); |
|
} |
|
} |
|
}, |
|
|
|
_onItemChange: function(/*dijit/_Widget*/ item, /*String*/ value){ |
|
// summary: |
|
// Call when item value change |
|
// tags: |
|
// private |
|
|
|
value = value || item.get("value"); |
|
|
|
//revalidate content |
|
this._testItem(item,value); |
|
|
|
//update value |
|
this._updateValues(); |
|
}, |
|
|
|
_onItemEdit: function(/*dijit/_Widget*/ item){ |
|
// summary: |
|
// Call when item is edited |
|
// tags: |
|
// private |
|
domClass.remove(item.domNode,["dijitError", this.baseClass + "Match", this.baseClass + "Mismatch"]); |
|
}, |
|
|
|
_testItem: function(/*Object*/ item, /*String*/ value){ |
|
// summary: |
|
// Change class of item (match, mismatch) |
|
// tags: |
|
// private |
|
var re = new RegExp(this.regExpGen(this.constraints)); |
|
var match = ('' + value).match(re); |
|
|
|
domClass.remove(item.domNode, this.baseClass + (!match ? "Match" : "Mismatch")); |
|
domClass.add(item.domNode, this.baseClass + (match ? "Match" : "Mismatch")); |
|
domClass.toggle(item.domNode, "dijitError", !match); |
|
|
|
if((this.showCloseButtonWhenValid && match) || |
|
(this.showCloseButtonWhenInvalid && !match)){ |
|
domClass.add(item.domNode,this.baseClass+"Closable"); |
|
}else { |
|
domClass.remove(item.domNode,this.baseClass+"Closable"); |
|
} |
|
}, |
|
|
|
_getValueAttr: function(){ |
|
// summary: |
|
// get all value in then list and return an array |
|
// tags: |
|
// private |
|
return this.value; |
|
}, |
|
|
|
_setValueAttr: function(/*Array|String*/ newValue){ |
|
// summary: |
|
// Hook so attr('value', value) works. |
|
// description: |
|
// Sets the value of the widget. |
|
// If the value has changed, then fire onChange event, unless priorityChange |
|
// is specified as null (or false?) |
|
this._destroyAllItems(); |
|
|
|
this.add(this._parseValue(newValue)); |
|
}, |
|
|
|
_parseValue: function(/*String*/ newValue){ |
|
// summary: |
|
// search for delimiters and split if needed |
|
// tags: |
|
// private |
|
if(typeof newValue == "string"){ |
|
if(lang.isString(this.delimiter)){ |
|
this.delimiter = [this.delimiter]; |
|
} |
|
var re = new RegExp("^.*("+this.delimiter.join("|")+").*"); |
|
if(newValue.match(re)){ |
|
re = new RegExp(this.delimiter.join("|")); |
|
return newValue.split(re); |
|
} |
|
} |
|
return newValue; |
|
}, |
|
|
|
regExpGen: function(/*__Constraints*/ constraints){ |
|
// summary: |
|
// Overridable function used to generate regExp when dependent on constraints. |
|
// Do not specify both regExp and regExpGen. |
|
// tags: |
|
// extension protected |
|
return this.regExp; // String |
|
}, |
|
|
|
_setDisabledAttr: function(/*Boolean*/ value){ |
|
// summary: |
|
// also enable/disable editable items |
|
// tags: |
|
// private |
|
if(!this.readOnlyItem){ |
|
for(var i in this._items){ |
|
this._items[i].set("disabled", value); |
|
} |
|
} |
|
|
|
if(!this.readOnlyInput){ |
|
this._input.set("disabled", value); |
|
} |
|
this.inherited(arguments); |
|
}, |
|
|
|
_onHandler: function(/*String*/ value){ |
|
// summary: |
|
// When handlers of input are fired, this method check input value and (if needed) modify it |
|
// tags: |
|
// private |
|
var parsedValue = this._parseValue(value); |
|
if(lang.isArray(parsedValue)){ |
|
this.add(parsedValue); |
|
} |
|
}, |
|
|
|
_onClick: function(/*Event*/ e){ |
|
// summary: |
|
// give focus to inputbox |
|
// tags: |
|
// private |
|
this._focusInput(); |
|
}, |
|
|
|
_focusInput: function(){ |
|
// summary: |
|
// give focus to input |
|
// tags: |
|
// private |
|
if(!this.readOnlyInput && this._input.focus){ |
|
this._input.focus(); |
|
} |
|
}, |
|
|
|
_inputOnKeyDown: function(/*Event*/ e){ |
|
// summary: |
|
// Used to add keyboard interactivity |
|
// tags: |
|
// private |
|
this._currentItem = null; |
|
var val = this._input.get("value"); |
|
|
|
if(e.keyCode == keys.BACKSPACE && val == "" && this.get("lastItem")){ |
|
this._destroyItem(this.get("lastItem")); |
|
}else if(e.keyCode == keys.ENTER && val != ""){ |
|
this.add(val); |
|
}else if(e.keyCode == keys.LEFT_ARROW && this._getCursorPos(this._input.focusNode) == 0 && |
|
!this.readOnlyItem && this.useArrowForEdit){ |
|
this._editBefore(); |
|
} |
|
}, |
|
|
|
_inputOnBlur: function(){ |
|
// summary: |
|
// Remove focus class and act like pressing ENTER key |
|
// tags: |
|
// private |
|
var val = this._input.get('value'); |
|
if(this.useOnBlur && val != ""){ |
|
this.add(val); |
|
} |
|
}, |
|
|
|
_getMatchedValueAttr: function(){ |
|
// summary: |
|
// get value that match regexp in then list and return an array |
|
// tags: |
|
// private |
|
return this._getValues(lang.hitch(this,this._matchValidator)); |
|
}, |
|
|
|
_getMismatchedValueAttr: function(){ |
|
// summary: |
|
// get value that mismatch regexp in then list and return an array |
|
// tags: |
|
// private |
|
return this._getValues(lang.hitch(this,this._mismatchValidator)); |
|
}, |
|
|
|
_getValues: function(/*Function*/ validator){ |
|
// summary: |
|
// return values with comparator constraint |
|
// tags: |
|
// private |
|
var value = []; |
|
validator = validator||this._nullValidator; |
|
for(var i in this._items){ |
|
var item = this._items[i]; |
|
if(item === null){ |
|
continue; |
|
} |
|
var itemValue = item.get("value"); |
|
if(validator(itemValue)){ |
|
value.push(itemValue); |
|
} |
|
} |
|
return value; |
|
}, |
|
|
|
_nullValidator: function(/*String*/ itemValue){ |
|
// summary: |
|
// return true or false |
|
// tags: |
|
// private |
|
return true; |
|
}, |
|
_matchValidator: function(/*String*/ itemValue){ |
|
// summary: |
|
// return true or false |
|
// tags: |
|
// private |
|
var re = new RegExp(this.regExpGen(this.constraints)); |
|
return itemValue.match(re); |
|
}, |
|
_mismatchValidator: function(/*String*/ itemValue){ |
|
// summary: |
|
// return true or false |
|
// tags: |
|
// private |
|
var re = new RegExp(this.regExpGen(this.constraints)); |
|
return !(itemValue.match(re)); |
|
}, |
|
|
|
_getLastItemAttr: function(){ |
|
// summary: |
|
// return the last item in list |
|
// tags: |
|
// private |
|
return this._getSomeItem(); |
|
}, |
|
_getSomeItem: function(/*dijit/_Widget*/ item, /*String*/ position){ |
|
// summary: |
|
// return the item before the one in params |
|
// tags: |
|
// private |
|
item=item||false; |
|
position=position||"last"; |
|
|
|
var lastItem = null; |
|
var stop=-1; |
|
for(var i in this._items){ |
|
if(this._items[i] === null){ continue; } |
|
|
|
if(position=="before" && this._items[i] === item){ |
|
break; |
|
} |
|
|
|
lastItem = this._items[i]; |
|
|
|
if(position=="first" ||stop==0){ |
|
stop=1; |
|
break; |
|
} |
|
if(position=="after" && this._items[i] === item){ |
|
stop=0; |
|
} |
|
} |
|
if(position=="after" && stop==0){ |
|
lastItem = null; |
|
} |
|
return lastItem; |
|
}, |
|
_getPreviousItem: function(/*dijit/_Widget*/ item){ |
|
// summary: |
|
// return the item before the one in params |
|
// tags: |
|
// private |
|
return this._getSomeItem(item,"before"); |
|
}, |
|
_getNextItem: function(/*dijit._Widget*/ item){ |
|
// summary: |
|
// return the item before the one in params |
|
// tags: |
|
// private |
|
return this._getSomeItem(item,"after"); |
|
}, |
|
|
|
_destroyItem: function(/*dijit/_Widget*/ item, /*Boolean?*/ updateValue){ |
|
// summary: |
|
// destroy an item |
|
// tags: |
|
// private |
|
this._items[item.index] = null; |
|
item.destroy(); |
|
this._count--; |
|
if(updateValue!==false){ |
|
this._updateValues(); |
|
this._setReadOnlyWhenMaxItemsReached(); |
|
} |
|
}, |
|
|
|
_updateValues: function(){ |
|
// summary: |
|
// update this.value and the select node |
|
// tags: |
|
// private |
|
this.value = this._getValues(); |
|
this._setSelectNode(); |
|
}, |
|
|
|
_destroyAllItems: function(){ |
|
// summary: |
|
// destroy all items |
|
// tags: |
|
// private |
|
for(var i in this._items){ |
|
if(this._items[i]==null){ continue; } |
|
this._destroyItem(this._items[i],false); |
|
} |
|
this._items = []; |
|
this._count = 0; |
|
this.value = null; |
|
this._setSelectNode(); |
|
this._setReadOnlyWhenMaxItemsReached(); |
|
}, |
|
|
|
destroy: function(){ |
|
// summary: |
|
// Destroy all widget |
|
this._destroyAllItems(); |
|
this._lastAddedItem = null; |
|
|
|
if(!this._input){ |
|
this._input.destroy(); |
|
} |
|
|
|
this.inherited(arguments); |
|
} |
|
}); |
|
|
|
var _ListInputInputItem = declare("dojox.form._ListInputInputItem", [Widget, TemplatedMixin], |
|
{ |
|
// summary: |
|
// Item created by ListInputInput when delimiter is found |
|
// description: |
|
// Simple `<li>` with close button added to ListInputInput when delimiter is found |
|
|
|
templateString: "<li class=\"dijit dijitReset dijitLeft dojoxListInputItem\" dojoAttachEvent=\"onclick: onClick\" ><span dojoAttachPoint=\"labelNode\"></span></li>", |
|
|
|
// closeButtonNode: domNode |
|
// ref to the close button node |
|
closeButtonNode: null, |
|
|
|
// readOnlyItem: Boolean |
|
// if true, item is editable |
|
readOnlyItem: true, |
|
|
|
baseClass:"dojoxListInputItem", |
|
|
|
// value: String |
|
// value of item |
|
value: "", |
|
|
|
// regExp: [extension protected] String |
|
// regular expression string used to validate the input |
|
// Do not specify both regExp and regExpGen |
|
regExp: ".*", |
|
|
|
// _editBox: Widget |
|
// inline edit box |
|
_editBox: null, |
|
|
|
// _handleKeyDown: handle |
|
// handle for the keyDown connect |
|
_handleKeyDown: null, |
|
|
|
attributeMap: { |
|
value: { node: "labelNode", type: "innerHTML" } |
|
}, |
|
|
|
postMixInProperties: function(){ |
|
var _nlsResources = i18nCommon; |
|
lang.mixin(this, _nlsResources); |
|
this.inherited(arguments); |
|
}, |
|
|
|
postCreate: function(){ |
|
// summary: |
|
// Create the close button if needed |
|
this.inherited(arguments); |
|
|
|
this.closeButtonNode = domConstruct.create("span",{ |
|
"class" : "dijitButtonNode dijitDialogCloseIcon", |
|
title : this.itemClose, |
|
onclick: lang.hitch(this, "onClose"), |
|
onmouseenter: lang.hitch(this, "_onCloseEnter"), |
|
onmouseleave: lang.hitch(this, "_onCloseLeave") |
|
}, this.domNode); |
|
|
|
domConstruct.create("span",{ |
|
"class" : "closeText", |
|
title : this.itemClose, |
|
innerHTML : "x" |
|
}, this.closeButtonNode); |
|
}, |
|
|
|
startup: function(){ |
|
// summary: |
|
// add the edit box |
|
this.inherited(arguments); |
|
this._createInlineEditBox(); |
|
}, |
|
|
|
_setReadOnlyItemAttr: function(/*Boolean*/ value){ |
|
// summary: |
|
// change the readonly state |
|
// tags: |
|
// private |
|
this.readOnlyItem = value; |
|
if(!value){ |
|
this._createInlineEditBox(); |
|
}else if(this._editBox){ |
|
this._editBox.set("disabled", true); |
|
} |
|
}, |
|
|
|
_createInlineEditBox: function(){ |
|
// summary: |
|
// create the inline editbox if needed |
|
// tags: |
|
// private |
|
if(this.readOnlyItem){ return; } |
|
if(!this._started){ return; } |
|
if(this._editBox){ |
|
this._editBox.set("disabled",false); |
|
return; |
|
} |
|
this._editBox = new InlineEditBox({ |
|
value:this.value, |
|
editor: "dijit.form.ValidationTextBox", |
|
editorParams:{ |
|
regExp:this.regExp |
|
} |
|
},this.labelNode); |
|
this.connect(this._editBox,"edit","_onEdit"); |
|
this.connect(this._editBox,"onChange","_onCloseEdit"); |
|
this.connect(this._editBox,"onCancel","_onCloseEdit"); |
|
}, |
|
|
|
edit: function(){ |
|
// summary: |
|
// enter inline editbox in edit mode |
|
if(!this.readOnlyItem){ |
|
this._editBox.edit(); |
|
} |
|
}, |
|
|
|
_onCloseEdit: function(/*String*/ value){ |
|
// summary: |
|
// call when inline editor close himself |
|
// tags: |
|
// private |
|
domClass.remove(this.closeButtonNode,this.baseClass + "Edited"); |
|
connect.disconnect(this._handleKeyDown); |
|
this.onChange(value); |
|
}, |
|
|
|
_onEdit: function(){ |
|
// summary: |
|
// call when inline editor start editing |
|
// tags: |
|
// private |
|
domClass.add(this.closeButtonNode,this.baseClass + "Edited"); |
|
this._handleKeyDown = connect.connect(this._editBox.editWidget,"_onKeyPress",this,"onKeyDown"); |
|
this.onEdit(); |
|
}, |
|
|
|
_setDisabledAttr: function(/*Boolean*/ value){ |
|
// summary: |
|
// disable inline edit box |
|
// tags: |
|
// private |
|
if(!this.readOnlyItem){ |
|
this._editBox.set("disabled", value); |
|
} |
|
}, |
|
|
|
_getValueAttr: function(){ |
|
// summary: |
|
// return value |
|
// tags: |
|
// private |
|
return (!this.readOnlyItem && this._started ? this._editBox.get("value") : this.value); |
|
}, |
|
|
|
destroy: function(){ |
|
// summary: |
|
// Destroy the inline editbox |
|
if(this._editBox){ |
|
this._editBox.destroy(); |
|
} |
|
this.inherited(arguments); |
|
}, |
|
|
|
_onCloseEnter: function(){ |
|
// summary: |
|
// Called when user hovers over close icon |
|
// tags: |
|
// private |
|
domClass.add(this.closeButtonNode, "dijitDialogCloseIcon-hover"); |
|
}, |
|
|
|
_onCloseLeave: function(){ |
|
// summary: |
|
// Called when user stops hovering over close icon |
|
// tags: |
|
// private |
|
domClass.remove(this.closeButtonNode, "dijitDialogCloseIcon-hover"); |
|
}, |
|
|
|
onClose: function(){ |
|
// summary: |
|
// callback when close button is clicked |
|
}, |
|
|
|
onEdit: function(){ |
|
// summary: |
|
// callback when widget come in edition |
|
}, |
|
|
|
onClick: function(){ |
|
// summary: |
|
// callback when widget is click |
|
}, |
|
|
|
onChange: function(/*String*/ value){ |
|
// summary: |
|
// callback when widget change its content |
|
}, |
|
|
|
|
|
onKeyDown: function(/*String*/ value){ |
|
// summary: |
|
// callback when widget get a KeyDown |
|
} |
|
}); |
|
var _ListInputInputBox = declare("dojox.form._ListInputInputBox", [ValidationTextBox], |
|
{ |
|
// summary: |
|
// auto-sized text box |
|
// description: |
|
// Auto sized textbox based on dijit.form.TextBox |
|
|
|
// minWidth: Integer |
|
// Min width of the input box |
|
minWidth:50, |
|
|
|
// intermediateChanges: Boolean |
|
// Fires onChange for each value change or only on demand |
|
// Force to true in order to get onChanged called |
|
intermediateChanges:true, |
|
|
|
// regExp: [extension protected] String |
|
// regular expression string used to validate the input |
|
// Do not specify both regExp and regExpGen |
|
regExp: ".*", |
|
|
|
// _sizer: DomNode |
|
// Used to get size of textbox content |
|
_sizer:null, |
|
|
|
onChange: function(/*String*/ value){ |
|
// summary: |
|
// compute content width |
|
this.inherited(arguments); |
|
if(this._sizer === null){ |
|
this._sizer = domConstruct.create("div",{ |
|
style : { |
|
position : "absolute", |
|
left : "-10000px", |
|
top : "-10000px" |
|
} |
|
},win.body()); |
|
} |
|
this._sizer.innerHTML = value; |
|
var w = domGeometry.getContentBox(this._sizer).w + this.minWidth; |
|
domGeometry.setContentSize(this.domNode,{ w : w }); |
|
}, |
|
|
|
destroy: function(){ |
|
// summary: |
|
// destroy the widget |
|
domConstruct.destroy(this._sizer); |
|
this.inherited(arguments); |
|
} |
|
}); |
|
return ListInput; |
|
});
|
|
|