source: Dev/trunk/src/client/dojox/form/ListInput.js

Last change on this file was 483, checked in by hendrikvanantwerpen, 11 years ago

Added Dojo 1.9.3 release.

  • Property svn:executable set to *
File size: 24.6 KB
Line 
1define([
2        "dojo/_base/kernel",
3        "dojo/_base/lang",
4        "dojo/_base/array",
5        "dojo/_base/json",
6        "dojo/_base/fx",
7        "dojo/_base/window",
8        "dojo/_base/connect",
9        "dojo/dom-class",
10        "dojo/dom-style",
11        "dojo/dom-construct",
12        "dojo/dom-geometry",
13        "dojo/keys",
14        "dijit/_Widget",
15        "dijit/_TemplatedMixin",
16        "dijit/form/_FormValueWidget",
17        "dijit/form/ValidationTextBox",
18        "dijit/InlineEditBox",
19        "dojo/i18n!dijit/nls/common",
20        "dojo/_base/declare"
21], function(kernel, lang, array, jsonUtil, fx, win, connect, domClass, domStyle, domConstruct, domGeometry, keys, Widget, TemplatedMixin, FormValueWidget, ValidationTextBox, InlineEditBox, i18nCommon, declare){
22kernel.experimental("dojox.form.ListInput");
23
24/*=====
25var __Constraints = {
26         // locale: String
27         //             locale used for validation, picks up value from this widget's lang attribute
28         // _flags_: anything
29         //             various flags passed to pattern function
30};
31=====*/
32
33var ListInput = declare("dojox.form.ListInput", [FormValueWidget],
34        {
35        // summary:
36        //              An automatic list maker
37        // description:
38        //              you can add value to list with add method.
39        //              you can only remove by clicking close button
40
41        constructor: function(){
42                this._items = [];
43
44
45                if(!lang.isArray(this.delimiter)){
46                        this.delimiter=[this.delimiter];
47                }
48                var r="("+this.delimiter.join("|")+")?";
49                this.regExp="^"+this.regExp+r+"$";
50        },
51
52        // inputClass: String
53        //              Class which will be used to create the input box. You can implements yours.
54        //              It must be a widget, focusNode or domNode must have "onkeydown" event
55        //              It must have .attr("value") to get value
56        //              It also must implement an (or more) handler for the "onChange" method
57        inputClass: "dojox.form._ListInputInputBox",
58
59        // inputHandler: String|Array
60        //              The widget will connect on all handler to check input value
61        //              You can use comma separated list
62        inputHandler: "onChange",
63
64        // inputProperties: String|Object
65        //              Properties used to create input box
66        //              If String, it must be a valid JSON
67        inputProperties: {
68                minWidth:50
69        },
70
71        // submitOnlyValidValue: Boolean
72        //              If true, only valid value will be submitted with form
73        submitOnlyValidValue:true,
74
75        // useOnBlur: Boolean
76        //              If true, onBlur event do a validate (like pressing ENTER)
77        useOnBlur:true,
78
79        // readOnlyInput: Boolean
80        //              if false, the list will be editable
81        //              Can only be set when instantiate
82        readOnlyInput: false,
83
84        // maxItems: Int
85        //              Specify max item the list can have
86        //              null = infinity
87        maxItems: null,
88
89        // showCloseButtonWhenValid: Boolean
90        //              if true, a close button will be added on valid item
91        showCloseButtonWhenValid: true,
92
93        // showCloseButtonWhenInvalid: Boolean
94        //              if true, a close button will be added on invalid item
95        showCloseButtonWhenInvalid: true,
96
97        // regExp: [extension protected] String
98        //              regular expression string used to validate the input
99        //              Do not specify both regExp and regExpGen
100        regExp: ".*", //"[a-zA-Z.-_]+@[a-zA-Z.-_]+.[a-zA-Z]+",
101
102        // delimiter: String|Array
103        //              delimiter for the string. Every match will be splitted.
104        //              The string can contain only one delimiter.
105        delimiter: ",",
106
107        // constraints: __Constraints
108        //              user-defined object needed to pass parameters to the validator functions
109        constraints: {},
110
111        baseClass:"dojoxListInput",
112
113        type: "select",
114
115        value: "",
116
117        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>",
118
119        _setNameAttr: "_selectNode",
120
121        // useAnim: Boolean
122        //              If true, then item will use an animation to show hide itself
123        useAnim: true,
124
125        // duration: Integer
126        //              Animation duration
127        duration: 500,
128
129        // easingIn: function
130        //              function used to easing on fadeIn end
131        easingIn: null,
132
133        // easingOut: function
134        //              function used to easing on fadeOut end
135        easingOut: null,
136
137        // readOnlyItem: Boolean
138        //              If true, items can be edited
139        //              Can only be set when instantiate
140        readOnlyItem: false,
141
142        // useArrowForEdit: Boolean
143        //              If true, arraow left and right can be used for editing
144        //              Can only be set when instantiate
145        useArrowForEdit: true,
146
147        // _items: Array
148        //              Array of widget.
149        //              Contain all reference to _ListInputInputItem
150        _items: null,
151
152        // _lastAddedItem: Widget
153        //              Contain a reference to the last created item
154        _lastAddedItem: null,
155
156        // _currentItem: Widget
157        //              Widget currently in edition
158        _currentItem: null,
159
160        // _input: Widget
161        //              Widget use for input box
162        _input: null,
163
164        // _count: Int
165        //              Count items
166        _count: 0,
167
168        postCreate: function(){
169                // summary:
170                //              If closeButton is used, add a class
171                this.inherited(arguments);
172                this._createInputBox();
173        },
174
175        _setReadOnlyInputAttr: function(/*Boolean*/ value){
176                // summary:
177                //              Change status and if needed, create the inputbox
178                // tags:
179                //              private
180                if(!this._started){ return this._createInputBox(); }
181                this.readOnlyInput = value;
182                this._createInputBox();
183        },
184
185        _setReadOnlyItemAttr: function(/*Boolean*/ value){
186                // summary:
187                //              set read only items
188                // tags:
189                //              private
190                if(!this._started){ return; }
191                for(var i in this._items){
192                        this._items[i].set("readOnlyItem", value);
193                }
194        },
195
196        _createInputBox: function(){
197                // summary:
198                //              Create the input box
199                // tags:
200                //              private
201                domClass.toggle(this._inputNode, "dijitHidden", this.readOnlyInput);
202                if(this.readOnlyInput){ return; }
203                if(this._input){ return; }
204
205                if(this.inputHandler === null){
206                        console.warn("you must add some handler to connect to input field");
207                        return false;
208                }
209                if(lang.isString(this.inputHandler)){
210                        this.inputHandler = this.inputHandler.split(",");
211                }
212                if(lang.isString(this.inputProperties)){
213                        this.inputProperties = jsonUtil.fromJson(this.inputProperties);
214                }
215
216
217                var input = lang.getObject(this.inputClass, false);
218
219                this.inputProperties.regExp = this.regExpGen(this.constraints);
220
221                this._input = new input(this.inputProperties);
222                this._input.startup();
223                this._inputNode.appendChild(this._input.domNode);
224                array.forEach(this.inputHandler, function(handler){
225                        this.connect(this._input,lang.trim(handler),"_onHandler");
226                },this);
227
228                this.connect(this._input, "onKeyDown", "_inputOnKeyDown");
229                this.connect(this._input, "onBlur", "_inputOnBlur");
230        },
231
232        compare: function(/*Array*/ val1, /*Array*/ val2){
233                // summary:
234                //              Compare 2 values (as returned by attr('value') for this widget).
235                // tags:
236                //              protected
237                val1 = val1.join(",");
238                val2 = val2.join(",");
239                if(val1 > val2){
240                        return 1;
241                }else if(val1 < val2){
242                        return -1;
243                }else{
244                        return 0;
245                }
246        },
247
248        add: function(/*String|Array*/ values){
249                // summary:
250                //              Create new list element
251                if(this._count>=this.maxItems && this.maxItems !== null){return;}
252                this._lastValueReported = this._getValues();
253
254                if(!lang.isArray(values)){
255                        values = [values];
256                }
257
258                for(var i in values){
259                        var value=values[i];
260                        if(value === "" || typeof value != "string"){
261                                continue;
262                        }
263                        this._count++;
264                        var re = new RegExp(this.regExpGen(this.constraints));
265
266                        this._lastAddedItem = new _ListInputInputItem({
267                                "index" : this._items.length,
268                                readOnlyItem : this.readOnlyItem,
269                                value : value,
270                                regExp: this.regExpGen(this.constraints)
271                        });
272                        this._lastAddedItem.startup();
273
274                        this._testItem(this._lastAddedItem,value);
275
276                        this._lastAddedItem.onClose = lang.hitch(this,"_onItemClose",this._lastAddedItem);
277                        this._lastAddedItem.onChange = lang.hitch(this,"_onItemChange",this._lastAddedItem);
278                        this._lastAddedItem.onEdit = lang.hitch(this,"_onItemEdit",this._lastAddedItem);
279                        this._lastAddedItem.onKeyDown = lang.hitch(this,"_onItemKeyDown",this._lastAddedItem);
280
281                        if(this.useAnim){
282                                domStyle.set(this._lastAddedItem.domNode, {opacity:0, display:""});
283                        }
284
285                        this._placeItem(this._lastAddedItem.domNode);
286
287                        if(this.useAnim){
288                                var anim = fx.fadeIn({
289                                        node : this._lastAddedItem.domNode,
290                                        duration : this.duration,
291                                        easing : this.easingIn
292                                }).play();
293                        }
294
295                        this._items[this._lastAddedItem.index] = this._lastAddedItem;
296
297                        if(this._onChangeActive && this.intermediateChanges){ this.onChange(value); }
298
299                        if(this._count>=this.maxItems && this.maxItems !== null){
300                                break;
301                        }
302                }
303
304                this._updateValues();
305                if(this._lastValueReported.length==0){
306                        this._lastValueReported = this.value;
307                }
308
309                if(!this.readOnlyInput){
310                        this._input.set("value", "");
311                }
312
313                if(this._onChangeActive){ this.onChange(this.value); }
314
315                this._setReadOnlyWhenMaxItemsReached();
316        },
317
318        _setReadOnlyWhenMaxItemsReached: function(){
319                // summary:
320                //              set input to readonly when max is reached
321                // tags:
322                //              private
323                this.set("readOnlyInput",(this._count>=this.maxItems && this.maxItems !== null));
324        },
325
326        _setSelectNode: function(){
327                // summary:
328                //              put all item in the select (for a submit)
329                // tags:
330                //              private
331                this._selectNode.options.length = 0;
332
333                var values=this.submitOnlyValidValue?this.get("MatchedValue"):this.value;
334
335                if(!lang.isArray(values)){
336                        return;
337                }
338                array.forEach(values,function(item){
339                        this._selectNode.options[this._selectNode.options.length]=new Option(item,item,true,true);
340                },this);
341        },
342
343        _placeItem: function(/*DomNode*/ node){
344                // summary:
345                //              Place item in the list
346                // tags:
347                //              private
348                domConstruct.place(node,this._inputNode, "before");
349        },
350
351        _getCursorPos: function(/*DomNode*/ node){
352                // summary:
353                //              get current cursor pos
354                // tags:
355                //              private
356                if(typeof node.selectionStart != 'undefined'){
357                        return node.selectionStart;
358                }
359
360                // IE Support
361                try{ node.focus(); }catch(e){}
362                var range = node.createTextRange();
363                range.moveToBookmark(win.doc.selection.createRange().getBookmark());
364                range.moveEnd('character', node.value.length);
365                try{
366                        return node.value.length - range.text.length;
367                }finally{ range=null; }
368        },
369
370        _onItemClose: function(/*dijit/_Widget*/ item){
371                // summary:
372                //              Destroy a list element when close button is clicked
373                // tags:
374                //              private
375                if(this.disabled){ return; }
376
377                if(this.useAnim){
378                        var anim = fx.fadeOut({
379                                node : item.domNode,
380                                duration : this.duration,
381                                easing : this.easingOut,
382                                onEnd : lang.hitch(this, "_destroyItem", item)
383                        }).play();
384                }else{
385                        this._destroyItem(item);
386                }
387        },
388
389        _onItemKeyDown:  function(/*dijit/_Widget*/ item, /*Event*/ e){
390                // summary:
391                //              Call when item get a keypress
392                // tags:
393                //              private
394                if(this.readOnlyItem || !this.useArrowForEdit){ return; }
395
396                if(e.keyCode == keys.LEFT_ARROW && this._getCursorPos(e.target)==0){
397                        this._editBefore(item);
398                }else if(e.keyCode == keys.RIGHT_ARROW && this._getCursorPos(e.target)==e.target.value.length){
399                        this._editAfter(item);
400                }
401        },
402
403        _editBefore: function(/*widget*/ item){
404                // summary:
405                //              move trough items
406                // tags:
407                //              private
408                this._currentItem = this._getPreviousItem(item);
409                if(this._currentItem !== null){
410                        this._currentItem.edit();
411                }
412        },
413        _editAfter: function(/*widget*/ item){
414                // summary:
415                //              move trough items
416                // tags:
417                //              private
418                this._currentItem = this._getNextItem(item);
419                if(this._currentItem !== null){
420                        this._currentItem.edit();
421                }
422
423                if(!this.readOnlyInput){
424                        if(this._currentItem === null){
425                                //no more item ?
426                                //so edit input (if available)
427                                this._focusInput();
428                        }
429                }
430        },
431
432        _onItemChange: function(/*dijit/_Widget*/ item, /*String*/ value){
433                // summary:
434                //              Call when item value change
435                // tags:
436                //              private
437
438                value = value || item.get("value");
439
440                //revalidate content
441                this._testItem(item,value);
442
443                //update value
444                this._updateValues();
445        },
446
447        _onItemEdit: function(/*dijit/_Widget*/ item){
448                // summary:
449                //              Call when item is edited
450                // tags:
451                //              private
452                domClass.remove(item.domNode,["dijitError", this.baseClass + "Match", this.baseClass + "Mismatch"]);
453        },
454
455        _testItem: function(/*Object*/ item, /*String*/ value){
456                // summary:
457                //              Change class of item (match, mismatch)
458                // tags:
459                //              private
460                var re = new RegExp(this.regExpGen(this.constraints));
461                var match = ('' + value).match(re);
462
463                domClass.remove(item.domNode, this.baseClass + (!match ? "Match" : "Mismatch"));
464                domClass.add(item.domNode, this.baseClass + (match ? "Match" : "Mismatch"));
465                domClass.toggle(item.domNode, "dijitError", !match);
466
467                if((this.showCloseButtonWhenValid && match) ||
468                        (this.showCloseButtonWhenInvalid && !match)){
469                        domClass.add(item.domNode,this.baseClass+"Closable");
470                }else {
471                        domClass.remove(item.domNode,this.baseClass+"Closable");
472                }
473        },
474
475        _getValueAttr: function(){
476                // summary:
477                //              get all value in then list and return an array
478                // tags:
479                //              private
480                return this.value;
481        },
482
483        _setValueAttr: function(/*Array|String*/ newValue){
484                // summary:
485                //              Hook so attr('value', value) works.
486                // description:
487                //              Sets the value of the widget.
488                //              If the value has changed, then fire onChange event, unless priorityChange
489                //              is specified as null (or false?)
490                this._destroyAllItems();
491
492                this.add(this._parseValue(newValue));
493        },
494
495        _parseValue: function(/*String*/ newValue){
496                // summary:
497                //              search for delimiters and split if needed
498                // tags:
499                //              private
500                if(typeof newValue == "string"){
501                        if(lang.isString(this.delimiter)){
502                                this.delimiter = [this.delimiter];
503                        }
504                        var re = new RegExp("^.*("+this.delimiter.join("|")+").*");
505                        if(newValue.match(re)){
506                                re = new RegExp(this.delimiter.join("|"));
507                                return newValue.split(re);
508                        }
509                }
510                return newValue;
511        },
512
513        regExpGen: function(/*__Constraints*/ constraints){
514                // summary:
515                //              Overridable function used to generate regExp when dependent on constraints.
516                //              Do not specify both regExp and regExpGen.
517                // tags:
518                //              extension protected
519                return this.regExp;     // String
520        },
521
522        _setDisabledAttr: function(/*Boolean*/ value){
523                // summary:
524                //              also enable/disable editable items
525                // tags:
526                //              private
527                if(!this.readOnlyItem){
528                        for(var i in this._items){
529                                this._items[i].set("disabled", value);
530                        }
531                }
532
533                if(!this.readOnlyInput){
534                        this._input.set("disabled", value);
535                }
536                this.inherited(arguments);
537        },
538
539        _onHandler: function(/*String*/ value){
540                // summary:
541                //              When handlers of input are fired, this method check input value and (if needed) modify it
542                // tags:
543                //              private
544                var parsedValue = this._parseValue(value);
545                if(lang.isArray(parsedValue)){
546                        this.add(parsedValue);
547                }
548        },
549
550        _onClick:  function(/*Event*/ e){
551                // summary:
552                //              give focus to inputbox
553                // tags:
554                //              private
555                this._focusInput();
556        },
557
558        _focusInput: function(){
559                // summary:
560                //              give focus to input
561                // tags:
562                //              private
563                if(!this.readOnlyInput && this._input.focus){
564                        this._input.focus();
565                }
566        },
567
568        _inputOnKeyDown: function(/*Event*/ e){
569                // summary:
570                //              Used to add keyboard interactivity
571                // tags:
572                //              private
573                this._currentItem = null;
574                var val = this._input.get("value");
575
576                if(e.keyCode == keys.BACKSPACE && val == "" && this.get("lastItem")){
577                        this._destroyItem(this.get("lastItem"));
578                }else if(e.keyCode == keys.ENTER && val != ""){
579                        this.add(val);
580                }else if(e.keyCode == keys.LEFT_ARROW && this._getCursorPos(this._input.focusNode) == 0 &&
581                        !this.readOnlyItem && this.useArrowForEdit){
582                                this._editBefore();
583                }
584        },
585
586        _inputOnBlur: function(){
587                // summary:
588                //              Remove focus class and act like pressing ENTER key
589                // tags:
590                //              private
591                var val = this._input.get('value');
592                if(this.useOnBlur && val != ""){
593                        this.add(val);
594                }
595        },
596
597        _getMatchedValueAttr: function(){
598                // summary:
599                //              get value that match regexp in then list and return an array
600                // tags:
601                //              private
602                return this._getValues(lang.hitch(this,this._matchValidator));
603        },
604
605        _getMismatchedValueAttr: function(){
606                // summary:
607                //              get value that mismatch regexp in then list and return an array
608                // tags:
609                //              private
610                return this._getValues(lang.hitch(this,this._mismatchValidator));
611        },
612
613        _getValues: function(/*Function*/ validator){
614                // summary:
615                //              return values with comparator constraint
616                // tags:
617                //              private
618                var value = [];
619                validator = validator||this._nullValidator;
620                for(var i in this._items){
621                        var item = this._items[i];
622                        if(item === null){
623                                continue;
624                        }
625                        var itemValue = item.get("value");
626                        if(validator(itemValue)){
627                                value.push(itemValue);
628                        }
629                }
630                return value;
631        },
632
633        _nullValidator: function(/*String*/ itemValue){
634                // summary:
635                //              return true or false
636                // tags:
637                //              private
638                return true;
639        },
640        _matchValidator: function(/*String*/ itemValue){
641                // summary:
642                //              return true or false
643                // tags:
644                //              private
645                var re = new RegExp(this.regExpGen(this.constraints));
646                return itemValue.match(re);
647        },
648        _mismatchValidator: function(/*String*/ itemValue){
649                // summary:
650                //              return true or false
651                // tags:
652                //              private
653                var re = new RegExp(this.regExpGen(this.constraints));
654                return !(itemValue.match(re));
655        },
656
657        _getLastItemAttr: function(){
658                // summary:
659                //              return the last item in list
660                // tags:
661                //              private
662                return this._getSomeItem();
663        },
664        _getSomeItem: function(/*dijit/_Widget*/ item, /*String*/ position){
665                // summary:
666                //              return the item before the one in params
667                // tags:
668                //              private
669                item=item||false;
670                position=position||"last";
671
672                var lastItem = null;
673                var stop=-1;
674                for(var i in this._items){
675                        if(this._items[i] === null){ continue; }
676
677                        if(position=="before" && this._items[i] === item){
678                                break;
679                        }
680
681                        lastItem = this._items[i];
682
683                        if(position=="first" ||stop==0){
684                                stop=1;
685                                break;
686                        }
687                        if(position=="after" && this._items[i] === item){
688                                stop=0;
689                        }
690                }
691                if(position=="after" && stop==0){
692                        lastItem = null;
693                }
694                return lastItem;
695        },
696        _getPreviousItem: function(/*dijit/_Widget*/ item){
697                // summary:
698                //              return the item before the one in params
699                // tags:
700                //              private
701                return this._getSomeItem(item,"before");
702        },
703        _getNextItem: function(/*dijit._Widget*/ item){
704                // summary:
705                //              return the item before the one in params
706                // tags:
707                //              private
708                return this._getSomeItem(item,"after");
709        },
710
711        _destroyItem: function(/*dijit/_Widget*/ item, /*Boolean?*/ updateValue){
712                // summary:
713                //              destroy an item
714                // tags:
715                //              private
716                this._items[item.index] = null;
717                item.destroy();
718                this._count--;
719                if(updateValue!==false){
720                        this._updateValues();
721                        this._setReadOnlyWhenMaxItemsReached();
722                }
723        },
724
725        _updateValues: function(){
726                // summary:
727                //              update this.value and the select node
728                // tags:
729                //              private
730                this.value = this._getValues();
731                this._setSelectNode();
732        },
733
734        _destroyAllItems: function(){
735                // summary:
736                //              destroy all items
737                // tags:
738                //              private
739                for(var i in this._items){
740                        if(this._items[i]==null){ continue; }
741                        this._destroyItem(this._items[i],false);
742                }
743                this._items = [];
744                this._count = 0;
745                this.value = null;
746                this._setSelectNode();
747                this._setReadOnlyWhenMaxItemsReached();
748        },
749
750        destroy: function(){
751                // summary:
752                //              Destroy all widget
753                this._destroyAllItems();
754                this._lastAddedItem = null;
755
756                if(!this._input){
757                        this._input.destroy();
758                }
759
760                this.inherited(arguments);
761        }
762});
763
764var _ListInputInputItem = declare("dojox.form._ListInputInputItem", [Widget, TemplatedMixin],
765        {
766        // summary:
767        //              Item created by ListInputInput when delimiter is found
768        // description:
769        //              Simple `<li>` with close button added to ListInputInput when delimiter is found
770
771        templateString: "<li class=\"dijit dijitReset dijitLeft dojoxListInputItem\" dojoAttachEvent=\"onclick: onClick\" ><span dojoAttachPoint=\"labelNode\"></span></li>",
772
773        // closeButtonNode: domNode
774        //              ref to the close button node
775        closeButtonNode: null,
776
777        // readOnlyItem: Boolean
778        //              if true, item is editable
779        readOnlyItem: true,
780
781        baseClass:"dojoxListInputItem",
782
783        // value: String
784        //              value of item
785        value: "",
786
787        // regExp: [extension protected] String
788        //              regular expression string used to validate the input
789        //              Do not specify both regExp and regExpGen
790        regExp: ".*",
791
792        // _editBox: Widget
793        //              inline edit box
794        _editBox: null,
795
796        // _handleKeyDown: handle
797        //              handle for the keyDown connect
798        _handleKeyDown: null,
799
800        attributeMap: {
801                value: { node: "labelNode", type: "innerHTML" }
802        },
803
804        postMixInProperties: function(){
805                var _nlsResources = i18nCommon;
806                lang.mixin(this, _nlsResources);
807                this.inherited(arguments);
808        },
809
810        postCreate: function(){
811                // summary:
812                //              Create the close button if needed
813                this.inherited(arguments);
814
815                this.closeButtonNode = domConstruct.create("span",{
816                        "class" : "dijitButtonNode dijitDialogCloseIcon",
817                        title : this.itemClose,
818                        onclick: lang.hitch(this, "onClose"),
819                        onmouseenter: lang.hitch(this, "_onCloseEnter"),
820                        onmouseleave: lang.hitch(this, "_onCloseLeave")
821                }, this.domNode);
822
823                domConstruct.create("span",{
824                        "class" : "closeText",
825                        title : this.itemClose,
826                        innerHTML : "x"
827                }, this.closeButtonNode);
828        },
829
830        startup: function(){
831                // summary:
832                //              add the edit box
833                this.inherited(arguments);
834                this._createInlineEditBox();
835        },
836
837        _setReadOnlyItemAttr: function(/*Boolean*/ value){
838                // summary:
839                //              change the readonly state
840                // tags:
841                //              private
842                this.readOnlyItem = value;
843                if(!value){
844                        this._createInlineEditBox();
845                }else if(this._editBox){
846                        this._editBox.set("disabled", true);
847                }
848        },
849
850        _createInlineEditBox: function(){
851                // summary:
852                //              create the inline editbox if needed
853                // tags:
854                //              private
855                if(this.readOnlyItem){ return; }
856                if(!this._started){ return; }
857                if(this._editBox){
858                        this._editBox.set("disabled",false);
859                        return;
860                }
861                this._editBox = new InlineEditBox({
862                        value:this.value,
863                        editor: "dijit.form.ValidationTextBox",
864                        editorParams:{
865                                regExp:this.regExp
866                        }
867                },this.labelNode);
868                this.connect(this._editBox,"edit","_onEdit");
869                this.connect(this._editBox,"onChange","_onCloseEdit");
870                this.connect(this._editBox,"onCancel","_onCloseEdit");
871        },
872
873        edit: function(){
874                // summary:
875                //              enter inline editbox in edit mode
876                if(!this.readOnlyItem){
877                        this._editBox.edit();
878                }
879        },
880
881        _onCloseEdit: function(/*String*/ value){
882                // summary:
883                //              call when inline editor close himself
884                // tags:
885                //              private
886                domClass.remove(this.closeButtonNode,this.baseClass + "Edited");
887                connect.disconnect(this._handleKeyDown);
888                this.onChange(value);
889        },
890
891        _onEdit: function(){
892                // summary:
893                //              call when inline editor start editing
894                // tags:
895                //              private
896                domClass.add(this.closeButtonNode,this.baseClass + "Edited");
897                this._handleKeyDown = connect.connect(this._editBox.editWidget,"_onKeyPress",this,"onKeyDown");
898                this.onEdit();
899        },
900
901        _setDisabledAttr: function(/*Boolean*/ value){
902                // summary:
903                //              disable inline edit box
904                // tags:
905                //              private
906                if(!this.readOnlyItem){
907                        this._editBox.set("disabled", value);
908                }
909        },
910
911        _getValueAttr: function(){
912                // summary:
913                //              return value
914                // tags:
915                //              private
916                return (!this.readOnlyItem && this._started ? this._editBox.get("value") : this.value);
917        },
918
919        destroy: function(){
920                // summary:
921                //              Destroy the inline editbox
922                if(this._editBox){
923                        this._editBox.destroy();
924                }
925                this.inherited(arguments);
926        },
927
928        _onCloseEnter: function(){
929                // summary:
930                //              Called when user hovers over close icon
931                // tags:
932                //              private
933                domClass.add(this.closeButtonNode, "dijitDialogCloseIcon-hover");
934        },
935
936        _onCloseLeave: function(){
937                // summary:
938                //              Called when user stops hovering over close icon
939                // tags:
940                //              private
941                domClass.remove(this.closeButtonNode, "dijitDialogCloseIcon-hover");
942        },
943
944        onClose: function(){
945                // summary:
946                //              callback when close button is clicked
947        },
948
949        onEdit: function(){
950                // summary:
951                //              callback when widget come in edition
952        },
953
954        onClick: function(){
955                // summary:
956                //              callback when widget is click
957        },
958
959        onChange: function(/*String*/ value){
960                // summary:
961                //              callback when widget change its content
962        },
963
964
965        onKeyDown: function(/*String*/ value){
966                // summary:
967                //              callback when widget get a KeyDown
968        }
969});
970var _ListInputInputBox = declare("dojox.form._ListInputInputBox", [ValidationTextBox],
971        {
972        // summary:
973        //              auto-sized text box
974        // description:
975        //              Auto sized textbox based on dijit.form.TextBox
976
977        // minWidth: Integer
978        //              Min width of the input box
979        minWidth:50,
980
981        // intermediateChanges: Boolean
982        //              Fires onChange for each value change or only on demand
983        //              Force to true in order to get onChanged called
984        intermediateChanges:true,
985
986        // regExp: [extension protected] String
987        //              regular expression string used to validate the input
988        //              Do not specify both regExp and regExpGen
989        regExp: ".*",
990
991        // _sizer: DomNode
992        //              Used to get size of textbox content
993        _sizer:null,
994
995        onChange: function(/*String*/ value){
996                // summary:
997                //              compute content width
998                this.inherited(arguments);
999                if(this._sizer === null){
1000                        this._sizer = domConstruct.create("div",{
1001                                style : {
1002                                        position : "absolute",
1003                                        left : "-10000px",
1004                                        top : "-10000px"
1005                                }
1006                        },win.body());
1007                }
1008                this._sizer.innerHTML = value;
1009                var w = domGeometry.getContentBox(this._sizer).w + this.minWidth;
1010                domGeometry.setContentSize(this.domNode,{ w : w });
1011        },
1012
1013        destroy: function(){
1014                // summary:
1015                //              destroy the widget
1016                domConstruct.destroy(this._sizer);
1017                this.inherited(arguments);
1018        }
1019});
1020return ListInput;
1021});
Note: See TracBrowser for help on using the repository browser.