romo 0.19.6 → 0.19.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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