romo 0.19.6 → 0.19.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA512:
3
- metadata.gz: 643c9c0e9600c876e1ec481fafc0488260c94f0c99d06a53fbc7abe791b23ff363f0922cf2ba92f605e886df4403bb8b368631f83e080a74949583dccf21675c
4
- data.tar.gz: 1dd48f7b1d07b69f3b2e135048ba7565a6b53e1758c08e242e7074d5a2e44fcc8f32ad9f731a3a8bfdbe3b64a4f715460814bda4d43bb74400afd3fd966f0abd
5
2
  SHA1:
6
- metadata.gz: 86052336ce3a41a0592c123eb52ad0c8f0a61709
7
- data.tar.gz: 8d5fda1c6c5172f7e59664624dffc2830bb70410
3
+ metadata.gz: 97d1c8900aee3e16f65d499f0837bb74f6225033
4
+ data.tar.gz: 17737178b8474f79671d577bd173db8fffdfb817
5
+ SHA512:
6
+ metadata.gz: dc935bbf15d8cc944fff91f2e7c2687ec8b8d033839b881cd66d30a549d1eac82e258aa85d8517f91797fb4239317f496702467a58103545058c0f7b12b51dbd
7
+ data.tar.gz: 01dbeac8de96746f831ed7993efb7c65ef34f4c2aac876528ccf784c668f361c3c95c2b0a9fab537fc2a85a3ef9fc0b03a2f671a62b385ff8e49984a17573b04
@@ -318,7 +318,7 @@
318
318
  @include align-middle;
319
319
  }
320
320
 
321
- /* input option list (used by selects vie option list dropdown) */
321
+ /* input option list (used by selects/pickers via option list dropdown) */
322
322
 
323
323
  .romo-input-option-list {
324
324
  cursor: pointer;
@@ -366,4 +366,26 @@
366
366
  color: $disabledColor;
367
367
  }
368
368
 
369
+ /* selected options list (used by multi selects/pickers) */
370
+
371
+ .romo-selected-options-list {
372
+ font-weight: normal;
373
+ @include user-select(none);
374
+ background-color: $inputBgColor;
375
+ color: $inputColor;
376
+ @include border1;
377
+
378
+ .romo-selected-options-list-items {
379
+ min-height: 35px;
380
+ }
381
+ .romo-selected-options-list-items {
382
+ padding: 4px;
383
+ }
384
+ .romo-selected-options-list-item {
385
+ display: inline-block;
386
+ @include border1;
387
+ @include bg-alt;
388
+ }
389
+ }
390
+
369
391
  }
@@ -193,7 +193,7 @@ RomoDatepicker.prototype.onTriggerSetDate = function(e, value) {
193
193
 
194
194
  RomoDatepicker.prototype.onElemKeyDown = function(e) {
195
195
  if (this.elem.hasClass('disabled') === false) {
196
- if (this.romoDropdown.popupElem.hasClass('romo-dropdown-open')) {
196
+ if (this.romoDropdown.popupOpen()) {
197
197
  return true;
198
198
  } else {
199
199
  if(e.keyCode === 40 /* Down */ ) {
@@ -38,6 +38,14 @@ var RomoDropdown = function(element) {
38
38
  this.elem.trigger('dropdown:ready', [this]);
39
39
  }
40
40
 
41
+ RomoDropdown.prototype.popupOpen = function() {
42
+ return this.popupElem.hasClass('romo-dropdown-open') === true;
43
+ }
44
+
45
+ RomoDropdown.prototype.popupClosed = function() {
46
+ return this.popupElem.hasClass('romo-dropdown-open') === false;
47
+ }
48
+
41
49
  RomoDropdown.prototype.doInit = function() {
42
50
  // override as needed
43
51
  }
@@ -177,7 +185,7 @@ RomoDropdown.prototype.onToggleClick = function(e) {
177
185
  }
178
186
 
179
187
  RomoDropdown.prototype.doToggle = function() {
180
- if (this.popupElem.hasClass('romo-dropdown-open')) {
188
+ if (this.popupOpen()) {
181
189
  setTimeout($.proxy(function() {
182
190
  this.doPopupClose();
183
191
  }, this), 100);
@@ -194,8 +202,7 @@ RomoDropdown.prototype.onPopupOpen = function(e) {
194
202
  e.preventDefault();
195
203
  }
196
204
 
197
- if (this.elem.hasClass('disabled') === false &&
198
- this.popupElem.hasClass('romo-dropdown-open') === false) {
205
+ if (this.elem.hasClass('disabled') === false && this.popupClosed()) {
199
206
  setTimeout($.proxy(function() {
200
207
  this.doPopupOpen();
201
208
  }, this), 100);
@@ -235,8 +242,7 @@ RomoDropdown.prototype.onPopupClose = function(e) {
235
242
  e.preventDefault();
236
243
  }
237
244
 
238
- if (this.elem.hasClass('disabled') === false &&
239
- this.popupElem.hasClass('romo-dropdown-open') === true) {
245
+ if (this.elem.hasClass('disabled') === false && this.popupOpen()) {
240
246
  setTimeout($.proxy(function() {
241
247
  this.doPopupClose();
242
248
  }, this), 100);
@@ -275,7 +281,7 @@ RomoDropdown.prototype.doUnBindElemKeyUp = function() {
275
281
 
276
282
  RomoDropdown.prototype.onElemKeyUp = function(e) {
277
283
  if (this.elem.hasClass('disabled') === false) {
278
- if (this.popupElem.hasClass('romo-dropdown-open')) {
284
+ if (this.popupOpen()) {
279
285
  if(e.keyCode === 27 /* Esc */ ) {
280
286
  this.doPopupClose();
281
287
  this.elem.trigger('dropdown:popupClosedByEsc', [this]);
@@ -29,6 +29,14 @@ RomoOptionListDropdown.prototype.popupElem = function() {
29
29
  return this.romoDropdown.popupElem;
30
30
  }
31
31
 
32
+ RomoOptionListDropdown.prototype.popupOpen = function() {
33
+ return this.romoDropdown.popupOpen();
34
+ }
35
+
36
+ RomoOptionListDropdown.prototype.popupClosed = function() {
37
+ return this.romoDropdown.popupClosed();
38
+ }
39
+
32
40
  RomoOptionListDropdown.prototype.selectedItemElem = function() {
33
41
  return this.romoDropdown.bodyElem.find('LI.selected');
34
42
  }
@@ -65,13 +73,20 @@ RomoOptionListDropdown.prototype.doInit = function() {
65
73
 
66
74
  RomoOptionListDropdown.prototype.doSetSelectedItem = function(itemValue) {
67
75
  this.selectedItemElem().removeClass('selected');
68
- this.romoDropdown.bodyElem.find(
69
- 'LI[data-romo-option-list-dropdown-option-value="'+itemValue+'"]'
70
- ).addClass('selected');
71
- this.doSetSelectedValueAndText(
72
- this.selectedItemElem().data('romo-option-list-dropdown-option-value'),
73
- this.selectedItemElem().data('romo-option-list-dropdown-option-display-text')
74
- );
76
+ if (itemValue !== undefined) {
77
+ this.romoDropdown.bodyElem.find(
78
+ 'LI[data-romo-option-list-dropdown-option-value="'+itemValue+'"]'
79
+ ).addClass('selected');
80
+ }
81
+ var selectedElem = this.selectedItemElem();
82
+ if (selectedElem[0] !== undefined) {
83
+ this.doSetSelectedValueAndText(
84
+ this.selectedItemElem().data('romo-option-list-dropdown-option-value'),
85
+ this.selectedItemElem().data('romo-option-list-dropdown-option-display-text')
86
+ );
87
+ } else {
88
+ this.doSetSelectedValueAndText('', '');
89
+ }
75
90
  }
76
91
 
77
92
  RomoOptionListDropdown.prototype.doSetSelectedValueAndText = function(value, text) {
@@ -83,6 +98,15 @@ RomoOptionListDropdown.prototype.doSetSelectedValueAndText = function(value, tex
83
98
  this.prevValue = value;
84
99
  }
85
100
 
101
+ RomoOptionListDropdown.prototype.doFocus = function(openOnFocus) {
102
+ if (openOnFocus === true) {
103
+ this.openOnFocus = true;
104
+ } else if (openOnFocus === false) {
105
+ this.openOnFocus = false;
106
+ }
107
+ this.elem.focus();
108
+ }
109
+
86
110
  /*
87
111
  Options are specified as a list of items. Each 'option' item object
88
112
  has either display text or html, a value, and can optionally be
@@ -451,7 +475,7 @@ RomoOptionListDropdown.prototype._onPopupOpenBodyKeyDown = function(e) {
451
475
 
452
476
  RomoOptionListDropdown.prototype._onElemKeyDown = function(e) {
453
477
  if (this.elem.hasClass('disabled') === false) {
454
- if (this.romoDropdown.popupElem.hasClass('romo-dropdown-open') === false) {
478
+ if (this.romoDropdown.popupClosed()) {
455
479
  if (e.keyCode === 40 /* Down */ || e.keyCode === 38 /* Up */) {
456
480
  this.romoDropdown.doPopupOpen();
457
481
  return false;
@@ -10,6 +10,7 @@ var RomoPicker = function(element) {
10
10
  this.defaultCaretClass = undefined;
11
11
  this.defaultCaretPaddingPx = 5;
12
12
  this.defaultCaretPosition = 'right'
13
+ this.defaultValuesDelim = ',';
13
14
 
14
15
  this.defaultOptionItems = this._buildDefaultOptionItems();
15
16
  this.filteredOptionItems = [];
@@ -17,18 +18,11 @@ var RomoPicker = function(element) {
17
18
  this.doInit();
18
19
  this._bindElem();
19
20
 
20
- var presetVal = this.elem[0].value;
21
- if (presetVal !== '') {
22
- this.doSetValue(presetVal);
23
- } else if (this.elem.data('romo-picker-empty-option') === true) {
24
- this.doSetValueAndText('', this.elem.data('romo-picker-empty-option-display-text') || '');
25
- } else {
26
- this.doSetValueAndText('', '');
27
- }
21
+ this.doSetValue(this._elemValues());
28
22
 
29
23
  if (this.elem.attr('id') !== undefined) {
30
24
  $('label[for="'+this.elem.attr('id')+'"]').on('click', $.proxy(function(e) {
31
- this.romoOptionListDropdown.elem.focus();
25
+ this.romoOptionListDropdown.doFocus();
32
26
  }, this));
33
27
  }
34
28
 
@@ -47,26 +41,41 @@ RomoPicker.prototype.doInit = function() {
47
41
  // override as needed
48
42
  }
49
43
 
50
- RomoPicker.prototype.doSetValue = function(value) {
44
+ RomoPicker.prototype.doSetValue = function(values) {
45
+ var value = undefined;
46
+ if (Array.isArray(values)) {
47
+ value = values.join(this._elemValuesDelim());
48
+ } else {
49
+ value = values;
50
+ }
51
51
  $.ajax({
52
52
  type: 'GET',
53
53
  url: this.elem.data('romo-picker-url'),
54
54
  data: { 'values': value },
55
- success: $.proxy(function(data, status, xhr) {
56
- if (data[0] !== undefined) {
57
- this.doSetValueAndText(data[0].value, data[0].displayText);
58
- } else if (this.elem.data('romo-picker-empty-option') === true) {
59
- this.doSetValueAndText('', this.elem.data('romo-picker-empty-option-display-text') || '');
60
- } else {
61
- this.doSetValueAndText('', '');
62
- }
63
- }, this),
55
+ success: $.proxy(function(data, status, xhr) { this.doSetValueDatas(data); }, this),
64
56
  });
65
57
  }
66
58
 
67
- RomoPicker.prototype.doSetValueAndText = function(value, text) {
68
- this.romoOptionListDropdown.doSetSelectedValueAndText(value, text);
69
- this._setValueAndText(value, text);
59
+ RomoPicker.prototype.doSetValueDatas = function(valueDatas) {
60
+ var datas = undefined;
61
+ if (Array.isArray(valueDatas)) {
62
+ datas = valueDatas;
63
+ } else {
64
+ datas = [valueDatas];
65
+ }
66
+ var values = datas.map(function(data) { return data.value; });
67
+ var displayTexts = datas.map(function(data) { return data.displayText; });
68
+
69
+ if (this.romoSelectedOptionsList !== undefined) {
70
+ this._setValuesAndDisplayText(values, '');
71
+ this.romoSelectedOptionsList.doSetItems(datas);
72
+ } else {
73
+ this._setValuesAndDisplayText(
74
+ values,
75
+ (displayTexts[0] || this.elem.data('romo-picker-empty-option-display-text') || '')
76
+ );
77
+ this.romoOptionListDropdown.doSetSelectedItem(values[0]);
78
+ }
70
79
  this._refreshUI();
71
80
  }
72
81
 
@@ -74,6 +83,7 @@ RomoPicker.prototype.doSetValueAndText = function(value, text) {
74
83
 
75
84
  RomoPicker.prototype._bindElem = function() {
76
85
  this._bindOptionListDropdown();
86
+ this._bindSelectedOptionsList();
77
87
  this._bindAjax();
78
88
 
79
89
  this.elem.on('romoPicker:triggerToggle', $.proxy(function(e) {
@@ -89,6 +99,37 @@ RomoPicker.prototype._bindElem = function() {
89
99
  this.romoOptionListDropdown.doSetListItems(this.defaultOptionItems);
90
100
  }
91
101
 
102
+ RomoPicker.prototype._bindSelectedOptionsList = function() {
103
+ this.romoSelectedOptionsList = undefined;
104
+ if (this.elem.prop('multiple') === true) {
105
+ if (this.elem.data('romo-picker-multiple-item-class') !== undefined) {
106
+ this.romoOptionListDropdown.elem.attr('data-romo-selected-options-list-item-class', this.elem.data('romo-picker-multiple-item-class'));
107
+ }
108
+ if (this.elem.data('romo-picker-multiple-max-rows') !== undefined) {
109
+ this.romoOptionListDropdown.elem.attr('data-romo-selected-options-list-max-rows', this.elem.data('romo-picker-multiple-max-rows'));
110
+ }
111
+
112
+ this.romoSelectedOptionsList = new RomoSelectedOptionsList(this.romoOptionListDropdown.elem);
113
+ this.romoSelectedOptionsList.elem.on('romoSelectedOptionsList:itemClick', $.proxy(function(e, itemValue, romoSelectedOptionsList) {
114
+ var currentValues = this._elemValues();
115
+ var index = currentValues.indexOf(itemValue);
116
+ if (index > -1) {
117
+ currentValues.splice(index, 1);
118
+ this._setValuesAndDisplayText(currentValues, '');
119
+ }
120
+ this.romoSelectedOptionsList.doRemoveItem(itemValue);
121
+ this._refreshUI();
122
+ }, this));
123
+ this.romoSelectedOptionsList.elem.on('romoSelectedOptionsList:listClick', $.proxy(function(e, romoSelectedOptionsList) {
124
+ this.romoOptionListDropdown.elem.trigger('dropdown:triggerPopupClose', []);
125
+ this.romoOptionListDropdown.doFocus(false);
126
+ }, this));
127
+
128
+ this.elemWrapper.before(this.romoSelectedOptionsList.elem);
129
+ this.romoSelectedOptionsList.doRefreshUI();
130
+ }
131
+ }
132
+
92
133
  RomoPicker.prototype._bindOptionListDropdown = function() {
93
134
  this.romoOptionListDropdown = this._buildOptionListDropdownElem().romoOptionListDropdown(this.elem)[0];
94
135
 
@@ -114,11 +155,22 @@ RomoPicker.prototype._bindOptionListDropdown = function() {
114
155
  }
115
156
  }, this));
116
157
  this.romoOptionListDropdown.elem.on('romoOptionListDropdown:itemSelected', $.proxy(function(e, itemValue, itemDisplayText, optionListDropdown) {
117
- this.romoOptionListDropdown.elem.focus();
158
+ this.romoOptionListDropdown.doFocus();
118
159
  this.elem.trigger('romoPicker:itemSelected', [itemValue, itemDisplayText, this]);
119
160
  }, this));
120
161
  this.romoOptionListDropdown.elem.on('romoOptionListDropdown:newItemSelected', $.proxy(function(e, itemValue, itemDisplayText, optionListDropdown) {
121
- this._setValueAndText(itemValue, itemDisplayText);
162
+ if (this.romoSelectedOptionsList !== undefined) {
163
+ var currentValues = this._elemValues();
164
+ if (!currentValues.includes(itemValue)) {
165
+ this._setValuesAndDisplayText(currentValues.concat([itemValue]), '');
166
+ this.romoSelectedOptionsList.doAddItem({
167
+ 'value': itemValue,
168
+ 'displayText': itemDisplayText
169
+ });
170
+ }
171
+ } else {
172
+ this._setValuesAndDisplayText([itemValue], itemDisplayText);
173
+ }
122
174
  this._refreshUI();
123
175
  this.elem.trigger('romoPicker:newItemSelected', [itemValue, itemDisplayText, this]);
124
176
  }, this));
@@ -285,14 +337,22 @@ RomoPicker.prototype._buildCustomOptionItem = function(value) {
285
337
  };
286
338
  }
287
339
 
288
- RomoPicker.prototype._setValueAndText = function(value, text) {
289
- this.elem[0].value = value;
340
+ RomoPicker.prototype._setValuesAndDisplayText = function(newValues, displayText) {
341
+ this.elem[0].value = newValues.join(this._elemValuesDelim());
290
342
 
291
343
  // store the display text on the DOM to compliment the value being stored on the
292
344
  // DOM via the elem above. need to use `attr` to persist selected values to the
293
345
  // DOM for back button logic to work. using `data` won't persist changes to DOM
294
346
  // and breaks how the component deals with back-button behavior.
295
- this.elem.attr('data-romo-picker-display-text', text);
347
+ this.elem.attr('data-romo-picker-display-text', displayText);
348
+ }
349
+
350
+ RomoPicker.prototype._elemValues = function() {
351
+ return this.elem[0].value.split(this._elemValuesDelim()).filter(function(v){ return v !== ''; });
352
+ }
353
+
354
+ RomoPicker.prototype._elemValuesDelim = function() {
355
+ return this.elem.data('romo-picker-values-delim') || this.defaultValuesDelim;
296
356
  }
297
357
 
298
358
  RomoPicker.prototype._refreshUI = function() {
@@ -300,6 +360,9 @@ RomoPicker.prototype._refreshUI = function() {
300
360
  // using `data` works the first time but does some elem caching or something
301
361
  // so it won't work subsequent times.
302
362
  var text = this.elem.attr('data-romo-picker-display-text');
363
+ if (this.romoSelectedOptionsList !== undefined) {
364
+ this.romoSelectedOptionsList.doRefreshUI();
365
+ }
303
366
  if (text === '') {
304
367
  text = ' '
305
368
  }
@@ -308,7 +371,7 @@ RomoPicker.prototype._refreshUI = function() {
308
371
 
309
372
  RomoPicker.prototype._onCaretClick = function(e) {
310
373
  if (this.elem.prop('disabled') === false) {
311
- this.romoOptionListDropdown.elem.focus();
374
+ this.romoOptionListDropdown.doFocus();
312
375
  this.elem.trigger('romoPicker:triggerPopupOpen');
313
376
  }
314
377
  }
@@ -14,11 +14,11 @@ var RomoSelect = function(element) {
14
14
  this.doInit();
15
15
  this._bindElem();
16
16
 
17
- this.doSetValue(this.elem[0].value);
17
+ this.doSetValue(this._elemValues());
18
18
 
19
19
  if (this.elem.attr('id') !== undefined) {
20
20
  $('label[for="'+this.elem.attr('id')+'"]').on('click', $.proxy(function(e) {
21
- this.romoSelectDropdown.elem.focus();
21
+ this.romoSelectDropdown.doFocus();
22
22
  }, this));
23
23
  }
24
24
 
@@ -38,8 +38,28 @@ RomoSelect.prototype.doInit = function() {
38
38
  }
39
39
 
40
40
  RomoSelect.prototype.doSetValue = function(value) {
41
- this.romoSelectDropdown.doSetSelectedItem(value);
42
- this._setValue(value);
41
+ var values = undefined;
42
+ if (Array.isArray(value)) {
43
+ values = value;
44
+ } else {
45
+ values = [value];
46
+ }
47
+ values = values.filter($.proxy(function(v) {
48
+ return this.elem.find('OPTION[value="'+v+'"]')[0] !== undefined;
49
+ }, this));
50
+
51
+ this._setValues(values);
52
+ if (this.romoSelectedOptionsList !== undefined) {
53
+ var items = values.map($.proxy(function(value) {
54
+ return {
55
+ 'value': value,
56
+ 'displayText': this.elem.find('OPTION[value="'+value+'"]').text().trim()
57
+ };
58
+ }, this));
59
+ this.romoSelectedOptionsList.doSetItems(items);
60
+ } else {
61
+ this.romoSelectDropdown.doSetSelectedItem(values[0]);
62
+ }
43
63
  this._refreshUI();
44
64
  }
45
65
 
@@ -47,6 +67,7 @@ RomoSelect.prototype.doSetValue = function(value) {
47
67
 
48
68
  RomoSelect.prototype._bindElem = function() {
49
69
  this._bindSelectDropdown();
70
+ this._bindSelectedOptionsList();
50
71
 
51
72
  this.elem.on('select:triggerToggle', $.proxy(function(e) {
52
73
  this.romoSelectDropdown.elem.trigger('selectDropdown:triggerToggle', []);
@@ -59,6 +80,37 @@ RomoSelect.prototype._bindElem = function() {
59
80
  }, this));
60
81
  }
61
82
 
83
+ RomoSelect.prototype._bindSelectedOptionsList = function() {
84
+ this.romoSelectedOptionsList = undefined;
85
+ if (this.elem.prop('multiple') === true) {
86
+ if (this.elem.data('romo-select-multiple-item-class') !== undefined) {
87
+ this.romoSelectDropdown.elem.attr('data-romo-selected-options-list-item-class', this.elem.data('romo-select-multiple-item-class'));
88
+ }
89
+ if (this.elem.data('romo-select-multiple-max-rows') !== undefined) {
90
+ this.romoSelectDropdown.elem.attr('data-romo-selected-options-list-max-rows', this.elem.data('romo-select-multiple-max-rows'));
91
+ }
92
+
93
+ this.romoSelectedOptionsList = new RomoSelectedOptionsList(this.romoSelectDropdown.elem);
94
+ this.romoSelectedOptionsList.elem.on('romoSelectedOptionsList:itemClick', $.proxy(function(e, itemValue, romoSelectedOptionsList) {
95
+ var currentValues = this._elemValues();
96
+ var index = currentValues.indexOf(itemValue);
97
+ if (index > -1) {
98
+ currentValues.splice(index, 1);
99
+ this._setValues(currentValues);
100
+ }
101
+ this.romoSelectedOptionsList.doRemoveItem(itemValue);
102
+ this._refreshUI();
103
+ }, this));
104
+ this.romoSelectedOptionsList.elem.on('romoSelectedOptionsList:listClick', $.proxy(function(e, romoSelectedOptionsList) {
105
+ this.romoSelectDropdown.elem.trigger('dropdown:triggerPopupClose', []);
106
+ this.romoSelectDropdown.doFocus(false);
107
+ }, this));
108
+
109
+ this.elemWrapper.before(this.romoSelectedOptionsList.elem);
110
+ this.romoSelectedOptionsList.doRefreshUI();
111
+ }
112
+ }
113
+
62
114
  RomoSelect.prototype._bindSelectDropdown = function() {
63
115
  this.romoSelectDropdown = this._buildSelectDropdownElem().romoSelectDropdown(this.elem)[0];
64
116
 
@@ -73,11 +125,22 @@ RomoSelect.prototype._bindSelectDropdown = function() {
73
125
  }, this));
74
126
 
75
127
  this.romoSelectDropdown.elem.on('selectDropdown:itemSelected', $.proxy(function(e, itemValue, itemDisplayText, selectDropdown) {
76
- this.romoSelectDropdown.elem.focus();
128
+ this.romoSelectDropdown.doFocus();
77
129
  this.elem.trigger('select:itemSelected', [itemValue, itemDisplayText, this]);
78
130
  }, this));
79
131
  this.romoSelectDropdown.elem.on('selectDropdown:newItemSelected', $.proxy(function(e, itemValue, itemDisplayText, selectDropdown) {
80
- this._setValue(itemValue);
132
+ if (this.romoSelectedOptionsList !== undefined) {
133
+ var currentValues = this._elemValues();
134
+ if (!currentValues.includes(itemValue)) {
135
+ this._setValues(currentValues.concat([itemValue]));
136
+ this.romoSelectedOptionsList.doAddItem({
137
+ 'value': itemValue,
138
+ 'displayText': itemDisplayText
139
+ });
140
+ }
141
+ } else {
142
+ this._setValues([itemValue]);
143
+ }
81
144
  this._refreshUI();
82
145
  this.elem.trigger('select:newItemSelected', [itemValue, itemDisplayText, this]);
83
146
  }, this));
@@ -178,18 +241,47 @@ RomoSelect.prototype._buildSelectDropdownElem = function() {
178
241
  return romoSelectDropdownElem;
179
242
  }
180
243
 
181
- RomoSelect.prototype._setValue = function(value) {
182
- var prevOptElem = this.elem.find('OPTION[value="'+this.elem[0].value+'"]');
183
- var newOptElem = this.elem.find('OPTION[value="'+value+'"]');
244
+ RomoSelect.prototype._setValues = function(newValues) {
245
+ var currentValues = this._elemValues();
184
246
 
185
- prevOptElem.removeAttr('selected');
186
- prevOptElem.prop('selected', false);
187
- newOptElem.attr('selected', 'selected');
188
- newOptElem.prop('selected', true);
247
+ var unsetValues = currentValues.filter(function(value) {
248
+ return newValues.indexOf(value) === -1;
249
+ });
250
+ var setValues = newValues.filter(function(value) {
251
+ return currentValues.indexOf(value) === -1;
252
+ });
253
+ var unsetElems = unsetValues.reduce($.proxy(function(elems, value) {
254
+ return elems.add(this.elem.find('OPTION[value="'+value+'"]'));
255
+ }, this), $());
256
+ var setElems = setValues.reduce($.proxy(function(elems, value) {
257
+ return elems.add(this.elem.find('OPTION[value="'+value+'"]'));
258
+ }, this), $());
259
+
260
+ unsetElems.removeAttr('selected');
261
+ unsetElems.prop('selected', false);
262
+ setElems.attr('selected', 'selected');
263
+ setElems.prop('selected', true);
264
+ }
265
+
266
+ RomoSelect.prototype._elemValues = function() {
267
+ var selectedNodes = this.elem.find('OPTION[selected]').get();
268
+ if (selectedNodes.length === 0 && this.romoSelectedOptionsList === undefined) {
269
+ // if a non-multi select has no selected options, treat the first option as selected
270
+ selectedNodes = [this.elem.find('OPTION')[0]];
271
+ }
272
+ return selectedNodes.map(function(node) {
273
+ return ($(node).attr('value') || '');
274
+ });
189
275
  }
190
276
 
191
277
  RomoSelect.prototype._refreshUI = function() {
192
- var text = this.elem.find('OPTION[selected="selected"]').text().trim();
278
+ var text = undefined;
279
+ if (this.romoSelectedOptionsList !== undefined) {
280
+ text = '';
281
+ this.romoSelectedOptionsList.doRefreshUI();
282
+ } else {
283
+ text = this.elem.find('OPTION[value="'+this._elemValues()[0]+'"]').text().trim();
284
+ }
193
285
  if (text === '') {
194
286
  text = ' '
195
287
  }
@@ -198,7 +290,7 @@ RomoSelect.prototype._refreshUI = function() {
198
290
 
199
291
  RomoSelect.prototype._onCaretClick = function(e) {
200
292
  if (this.elem.prop('disabled') === false) {
201
- this.romoSelectDropdown.elem.focus();
293
+ this.romoSelectDropdown.doFocus();
202
294
  this.elem.trigger('select:triggerPopupOpen');
203
295
  }
204
296
  }
@@ -31,6 +31,14 @@ RomoSelectDropdown.prototype.popupElem = function() {
31
31
  return this.romoOptionListDropdown.popupElem();
32
32
  }
33
33
 
34
+ RomoSelectDropdown.prototype.popupOpen = function() {
35
+ return this.romoOptionListDropdown.popupOpen();
36
+ }
37
+
38
+ RomoSelectDropdown.prototype.popupClosed = function() {
39
+ return this.romoOptionListDropdown.popupClosed();
40
+ }
41
+
34
42
  RomoSelectDropdown.prototype.selectedItemElem = function() {
35
43
  return this.romoOptionListDropdown.selectedItemElem();
36
44
  }
@@ -63,6 +71,10 @@ RomoSelectDropdown.prototype.doSetSelectedItem = function(newValue) {
63
71
  this.romoOptionListDropdown.doSetSelectedItem(newValue);
64
72
  }
65
73
 
74
+ RomoSelectDropdown.prototype.doFocus = function(openOnFocus) {
75
+ this.romoOptionListDropdown.doFocus(openOnFocus);
76
+ }
77
+
66
78
  /* private */
67
79
 
68
80
  RomoSelectDropdown.prototype._bindElem = function() {
@@ -0,0 +1,161 @@
1
+ var RomoSelectedOptionsList = function(focusElem) {
2
+ this.elem = undefined;
3
+ this.focusElem = focusElem; // picker/select dropdown elem
4
+
5
+ this.items = [];
6
+
7
+ this.doInit();
8
+ this._bindElem();
9
+ }
10
+
11
+ RomoSelectedOptionsList.prototype.doInit = function() {
12
+ // override as needed
13
+ }
14
+
15
+ /*
16
+ Options are specified as a list of items. Each 'option' item object
17
+ has display text and a value. They are compatible with the option list
18
+ dropdown option items.
19
+
20
+ Example:
21
+ [ { 'type': 'option', 'value': 'a', 'displayText': 'A' },
22
+ { 'type': 'option', 'value': 'b', 'displayText': 'B' },
23
+ { 'type': 'option', 'value': 'c', 'displayText': 'C' }
24
+ ]
25
+ */
26
+
27
+ RomoSelectedOptionsList.prototype.doSetItems = function(itemsList) {
28
+ this.items = itemsList;
29
+ }
30
+
31
+ RomoSelectedOptionsList.prototype.doClearItems = function() {
32
+ this.items = [];
33
+ }
34
+
35
+ RomoSelectedOptionsList.prototype.doAddItem = function(item) {
36
+ if (!this._getItemValues().includes(item.value)) {
37
+ this.items.push(item);
38
+ }
39
+ }
40
+
41
+ RomoSelectedOptionsList.prototype.doRemoveItem = function(itemValue) {
42
+ var index = this._getItemValues().indexOf(itemValue);
43
+ if (index > -1) {
44
+ this.items.splice(index, 1);
45
+ }
46
+ }
47
+
48
+ RomoSelectedOptionsList.prototype.doRefreshUI = function() {
49
+ var itemValues = this._getItemValues();
50
+ var uiListElem = this.elem.find('.romo-selected-options-list-items');
51
+ var uiItemElems = uiListElem.find('.romo-selected-options-list-item');
52
+ var uiValues = uiItemElems.get().map(function(uiItemNode) {
53
+ return $(uiItemNode).data('romo-selected-options-list-value');
54
+ });
55
+ var rmNodes = uiItemElems.get().filter(function(uiItemNode) {
56
+ return itemValues.indexOf($(uiItemNode).data('romo-selected-options-list-value')) === -1;
57
+ });
58
+ var addItems = this.items.filter(function(item) {
59
+ return uiValues.indexOf(item.value) === -1;
60
+ });
61
+ rmNodes.forEach($.proxy(function(rmNode) {
62
+ $(rmNode).remove();
63
+ }, this));
64
+ addItems.forEach($.proxy(function(addItem) {
65
+ var addElem = this._buildItemElem(addItem);
66
+ uiListElem.append(addElem);
67
+
68
+ var listWidth = parseInt(Romo.getComputedStyle(uiListElem[0], "width"), 10);
69
+ var listLeftPad = parseInt(Romo.getComputedStyle(uiListElem[0], "padding-left"), 10);
70
+ var listRightPad = parseInt(Romo.getComputedStyle(uiListElem[0], "padding-right"), 10);
71
+ var itemBorderWidth = 1;
72
+ var itemLeftPad = parseInt(Romo.getComputedStyle(addElem[0], "padding-left"), 10);
73
+ var itemRightPad = parseInt(Romo.getComputedStyle(addElem[0], "padding-right"), 10);
74
+ addElem.find('DIV').css('max-width', String(listWidth-listLeftPad-listRightPad-(2*itemBorderWidth)-itemLeftPad-itemRightPad)+'px');
75
+ }, this));
76
+
77
+ var focusElemWidth = parseInt(Romo.getComputedStyle(this.focusElem[0], "width"), 10);
78
+ this.elem.css('width', String(focusElemWidth)+'px');
79
+
80
+ var maxRows = undefined;
81
+ var uiListElemHeight = parseInt(Romo.getComputedStyle(uiListElem[0], "height"), 10);
82
+ var firstItemNode = uiListElem.find('.romo-selected-options-list-item')[0];
83
+ if (firstItemNode !== undefined) {
84
+ var itemHeight = parseInt(Romo.getComputedStyle(firstItemNode, "height"), 10);
85
+ var itemMarginBottom = parseInt(Romo.getComputedStyle(firstItemNode, "margin-bottom"), 10);
86
+ var itemBorderWidth = 1;
87
+ var listTopPad = parseInt(Romo.getComputedStyle(uiListElem[0], "padding-top"), 10);
88
+ var listBottomPad = parseInt(Romo.getComputedStyle(uiListElem[0], "padding-bottom"), 10);
89
+
90
+ var maxRows = this.focusElem.data('romo-selected-options-list-max-rows') || 0;
91
+ var maxHeight = listTopPad+(itemHeight*maxRows)+(itemMarginBottom*(maxRows-1))+(2*itemBorderWidth*maxRows)+listBottomPad+(itemHeight/2);
92
+ }
93
+ if (maxRows !== undefined && (uiListElemHeight > maxHeight)) {
94
+ this.elem.css({
95
+ 'height': String(maxHeight)+'px',
96
+ 'overflow-y': 'auto'
97
+ });
98
+ var itemElems = uiListElem.find('.romo-selected-options-list-item');
99
+ var lastItemNode = itemElems[itemElems.length-1];
100
+ this._scrollListTopToItem($(lastItemNode));
101
+ } else {
102
+ this.elem.css({
103
+ 'height': String(uiListElemHeight)+'px',
104
+ 'overflow-y': undefined
105
+ });
106
+ }
107
+ }
108
+
109
+ /* private */
110
+
111
+ RomoSelectedOptionsList.prototype._bindElem = function() {
112
+ this.elem = $('<div class="romo-selected-options-list"><div class="romo-selected-options-list-items"></div></div>');
113
+
114
+ this.elem.on('click', $.proxy(function(e) {
115
+ if (e !== undefined) {
116
+ e.stopPropagation();
117
+ e.preventDefault();
118
+ }
119
+ this.elem.trigger('romoSelectedOptionsList:listClick', [this]);
120
+ }, this));
121
+
122
+ this.doSetItems([]);
123
+ }
124
+
125
+ RomoSelectedOptionsList.prototype._buildItemElem = function(item) {
126
+ var itemClass = this.focusElem.data('romo-selected-options-list-item-class') || '';
127
+ var itemElem = $('<div class="romo-selected-options-list-item romo-pointer romo-pad0-left romo-pad0-right romo-push0-right romo-push0-bottom '+itemClass+'"></div>');
128
+ itemElem.append($('<div class="romo-crop-ellipsis romo-text-strikethrough-hover">'+(item.displayText || '')+'</div>'));
129
+ itemElem.attr('data-romo-selected-options-list-value', (item.value || ''));
130
+ itemElem.on('click', $.proxy(this._onItemClick, this));
131
+
132
+ return itemElem;
133
+ }
134
+
135
+ RomoSelectedOptionsList.prototype._getItemValues = function() {
136
+ return this.items.map(function(item) { return item.value; });
137
+ }
138
+
139
+ RomoSelectedOptionsList.prototype._onItemClick = function(e) {
140
+ var itemElem = $(e.target);
141
+ if (!itemElem.hasClass('romo-selected-options-list-item')) {
142
+ var itemElem = itemElem.closest('.romo-selected-options-list-item');
143
+ }
144
+ if (itemElem[0] !== undefined) {
145
+ var value = itemElem.data('romo-selected-options-list-value');
146
+ this.elem.trigger('romoSelectedOptionsList:itemClick', [value, this]);
147
+ }
148
+ }
149
+
150
+ RomoSelectedOptionsList.prototype._scrollListTopToItem = function(itemElem) {
151
+ if (itemElem[0] !== undefined) {
152
+ var scroll = this.elem;
153
+ scroll.scrollTop(0);
154
+
155
+ var scrollOffsetTop = scroll.offset().top;
156
+ var selOffsetTop = itemElem.offset().top;
157
+ var selOffset = itemElem.height() / 2;
158
+
159
+ scroll.scrollTop(selOffsetTop - scrollOffsetTop - selOffset);
160
+ }
161
+ }
data/lib/romo/dassets.rb CHANGED
@@ -56,6 +56,7 @@ module Romo::Dassets
56
56
  'js/romo/indicator.js',
57
57
  'js/romo/indicator_text_input.js',
58
58
  'js/romo/currency_text_input.js',
59
+ 'js/romo/selected_options_list.js',
59
60
  'js/romo/option_list_dropdown.js',
60
61
  'js/romo/select_dropdown.js',
61
62
  'js/romo/select.js',
data/lib/romo/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Romo
2
- VERSION = "0.19.6"
2
+ VERSION = "0.19.7"
3
3
  end
@@ -58,6 +58,7 @@ module Romo::Dassets
58
58
  'js/romo/indicator.js',
59
59
  'js/romo/indicator_text_input.js',
60
60
  'js/romo/currency_text_input.js',
61
+ 'js/romo/selected_options_list.js',
61
62
  'js/romo/option_list_dropdown.js',
62
63
  'js/romo/select_dropdown.js',
63
64
  'js/romo/select.js',
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: romo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.19.6
4
+ version: 0.19.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kelly Redding
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2017-08-25 00:00:00 Z
13
+ date: 2017-09-06 00:00:00 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: assert
@@ -99,6 +99,7 @@ files:
99
99
  - assets/js/romo/picker.js
100
100
  - assets/js/romo/select.js
101
101
  - assets/js/romo/select_dropdown.js
102
+ - assets/js/romo/selected_options_list.js
102
103
  - assets/js/romo/sortable.js
103
104
  - assets/js/romo/tooltip.js
104
105
  - assets/js/romo/word_boundary_filter.js