fix #7861 - add multiline combobox MultiLineTag
[roojs1] / Roo / bootstrap / form / MultiLineTag.js
1 /**
2  * 
3  * @class Roo.bootstrap.form.MultiLineTag
4  * @param {Object} config The config object
5  * 
6  */
7
8 Roo.bootstrap.form.MultiLineTag = function(config){
9     Roo.bootstrap.form.MultiLineTag.superclass.constructor.call(this, config);
10
11     this.addEvents({
12         /**
13          * @event beforeload
14          * Fires before a request is made for a new data object.  If the beforeload handler returns false
15          * the load action will be canceled.
16          * @param {Roo.boostrap.form.MultiLineTag} this
17          * @param {Store} store
18          * @param {Object} options The loading options that were specified (see {@link #load} for details)
19          */
20          beforeload : true
21     });
22 };
23
24 Roo.extend(Roo.bootstrap.form.MultiLineTag, Roo.bootstrap.form.Input,  {
25     tagRows : [],
26     minimumRow : 2,
27
28     // for combo box
29     displayField : '',
30     valueField : '',
31     placeholder : '',
32     queryParam : '',
33     listWidth : 300,
34     minChars : 2,
35
36     // for combo box store
37     url : undefined,
38     fields : [],
39
40
41
42     getAutoCreate : function()
43     {
44         var config = {
45             cls : 'roo-multi-line-tag form-group'
46         };
47
48         config = this.getAutoCreateLabel( config, {
49             cls : 'roo-multi-line-tag-container'
50         } );
51
52         return config;
53     },
54
55     initEvents : function()
56     {
57         this.tagRows = [];
58
59         for (var i = 0; i < this.minimumRow; i++) {
60             this.addTagRow();
61         }
62     },
63
64     addTagRow : function()
65     {
66         var _this = this; 
67
68         var comboBox = Roo.factory({
69             xns: Roo.bootstrap.form,
70             xtype : 'ComboBox',
71             editable : true,
72             triggerAction: 'all',
73             minChars: _this.minChars,
74             displayField: _this.displayField,
75             valueField : _this.valueField,
76             listWidth: _this.listWidth,
77             placeholder : _this.placeholder,
78             queryParam : _this.queryParam,
79             store : {
80                 xns : Roo.data,
81                 xtype : 'Store',
82                 listeners : {
83                     beforeload : function(_self, options)
84                     {
85                         _this.fireEvent('beforeload', _this, _self, options);
86                     }
87                 },
88                 proxy : {
89                     xns : Roo.data,
90                     xtype : 'HttpProxy',
91                     method : 'GET',
92                     url : _this.url
93                 },
94                 reader : {
95                     xns : Roo.data,
96                     xtype : 'JsonReader',
97                     fields : _this.fields
98                 }
99             },
100             listeners : {
101                 'render' : function (_self) {
102                     _self.inputEl().on('keyup', function(e) {
103                         if(_this.shouldAutoAddTagRow()) {
104                             _this.addTagRow();
105                         }
106                     });
107                     _self.inputEl().on('change', function(e) {
108                         _this.fireEvent('change', _this, _this.getValue(), false);
109                         _this.showHideRemoveBtn();
110
111                     });
112                 },
113                 'select' : function(_self, record, index) {
114                     _this.fireEvent('change', _this, _this.getValue(), false);
115                 }
116             }
117         });
118
119         var button = Roo.factory({
120             xns : Roo.bootstrap,
121             xtype : 'Button',
122             html : '-'
123         });
124
125         var row = {
126             xns : Roo.bootstrap,
127             xtype : 'Row',
128             items : [
129                 comboBox,
130                 button
131             ],
132             listeners : {
133                 'render' : function (_self) {
134                     this.inputCb = comboBox;
135                     this.removeBtn = button;
136
137                     this.removeBtn.on('click', function() {
138                         _this.removeTagRow(_self);
139                         _this.fireEvent('change', _this, _this.getValue(), false);
140                     });
141                 }
142             }
143         };
144         this.tagRows.push(this.addxtype(row));
145
146         _this.showHideRemoveBtn();
147     },
148
149     // a new tags should be added automatically when all existing tags are not empty
150     shouldAutoAddTagRow : function()
151     {
152         var ret = true;
153
154         Roo.each(this.tagRows, function(r) {
155             if(r.inputCb.getRawValue() == '') {
156                 ret = false;
157             }
158         });
159
160         return ret;
161     },
162
163     removeTagRow : function(row)
164     {
165         row.destroy();
166         this.tagRows.splice(this.tagRows.indexOf(row), 1);
167         this.showHideRemoveBtn();
168     },
169
170     // hide all remove buttons if there are {minimumRow} or less tags
171     // hide the remove button for empty tag
172     showHideRemoveBtn : function()
173     {
174         var _this = this;
175         
176         Roo.each(this.tagRows, function (r) {
177
178             r.removeBtn.show();
179
180             if(_this.tagRows.length <= _this.minimumRow || r.inputCb.getRawValue() == '') {
181                 r.removeBtn.hide();
182             }
183         });
184     },
185
186     getValue : function()
187     {
188         var _this = this;
189         var tags = [];
190         Roo.each(_this.tagRows, function(r) {
191             var value = r.inputCb.getRawValue();
192             if(value != '') {
193                 var tag = {};
194                 tag[_this.valueField] = r.inputCb.getRawValue();
195                 tags.push(tag);
196             }
197         });
198         
199         return JSON.stringify(tags);
200     },
201
202     setValue : function(json)
203     {
204
205         // remove all old tags
206         var oldTotal = this.tagRows.length;
207
208         for(var i = 0; i < oldTotal; i ++) {
209             this.removeTagRow(this.tagRows[0]);
210         }
211
212         // empty tag if invalid json
213         var arr = [];
214
215         try {
216             // set new tags
217             arr = JSON.parse(json);
218         }
219         catch {}
220
221         for (var i = 0; i < arr.length; i ++) {
222             this.addTagRow();
223             this.tagRows[i].inputCb.setRawValue(arr[i][this.valueField]);
224         }
225
226         // always add one extra empty tag
227         this.addTagRow();
228
229         // add empty tags until there are {minimumRow} tags
230         while(this.tagRows.length < this.minimumRow) {
231             this.addTagRow();
232         }
233         
234     },
235
236     getChildContainer : function()
237     {
238         return Roo.select('.roo-multi-line-tag-container', true).elements[0];
239     }
240 });