bootstrap-combobox
bootstrap-combobox copied to clipboard
Two same labels in options
<select>
<option value="1">First</option>
<option value="2">Second</option>
<option value="3">First</option>
</select>
In combobox will be two values, but they will return 3 in two cases
Whats the use case for this?
We make combobox with user names. We can have two "John" in base with different ids. And in combobox we have 2 John with one id
How would you be able to tell them apart to begin with without different text anyways?
Going to bump this thread because I'm running into the same issue. A new use case and where/how to tell them apart:
Much like Google's Postman client, when you create a new Collection, there's a little sidebar on the left which keeps track of them in chronological order. A user can add to an existing collection or create a new one. The new ones can have existing labels but since they are in chronological order to the user, and in the combobox, then they're easily distinguishable.
So to tell them apart, the user looks to the sidebar and knows that the first repeated collection is the same as the one in a particular position on the dropdown.
There's an easy solution which is to use the index of the selected option rather than the value as the identifier, this will help link back to the selected value.
I'll implement it outside the plugin and then post my solution but it'd be nice if it was implemented this way to begin with.
EDIT: here's the changed source. Changes are in the comments but it was basically changing map to an array, pushing the values of each select option, and then in the select method, retrieve the index of the active option and then use the map with this index.
parse: function() {
var that = this,
map = [], // make map an array instead
source = [],
selected = false,
selectedValue = '';
this.$source.find('option').each(function() {
var option = $(this);
if (option.val() === '') {
that.options.placeholder = option.text();
return;
}
map.push(option.val()); // push the value
source.push(option.text());
if (option.prop('selected')) {
selected = option.text();
selectedValue = option.val();
}
})
this.map = map;
if (selected) {
this.$element.val(selected);
this.$target.val(selectedValue);
this.$container.addClass('combobox-selected');
this.selected = true;
}
return source;
},
select: function() {
var val = this.$menu.find('.active').attr('data-value');
var index;
// not the most efficient way of finding the index, but you get the idea
this.$menu.children().each(function(i, li) {
if (li.className === 'active') {
index = i;
}
})
this.$element.val(this.updater(val)).trigger('change');
this.$target.val(this.map[index]).trigger('change'); // now they're sourced correctly
this.$source.val(this.map[index]).trigger('change'); // now they're sourced correctly
this.$container.addClass('combobox-selected');
this.selected = true;
return this.hide();
}
Second EDIT: the code I posted won't actually work since when using the autocomplete, the indices are wrong. Still hoping to find an answer
I will probably add some additional number to duplicate names in my case.
Still, I think that this is something to be fixed in the combobox. As currently, combobox displays all the options with the same name for selection, but no matter which one I select, only one option of those is actually selected (only one of the values are used). So, there is no way to select some of the displayed options.
I can't see this being a case of anything other than GIGO (garbage in, garbage out); as @thephw noted, users wouldn't have any way of knowing which value they're actually selecting if multiple options have the same display text.
This feels like something that should be fixed earlier in the pipeline (when the select itself is generated) than expecting the combobox plugin to clean up the data - any implementation here is likely to be wrong for someone's usage.
Yes. Maybe only console warning.
I can look into how much effort a console warning would be. It's been a while since I've had to look at the code, but I'll try to get to it this weekend.