Is it possible to limit a user\'s selection to the predefined data-source items for a Bootstrap Typeahead item? So if the user types something that is not in the data-source
Using jquery and Samuel's solution I think you will overcome the IE problem. Change your validateSelecion function to:
function validateSelection() {
if ($.inArray($(this).val(), myData) === -1)
alert('Error : element not in list!');
}
Leave the rest as Samuel pointed out.
I ran into the same issue but in my situation all my my data was remote. Bloodhound doesn't really have any good hooks that i am currently aware of that lets you do this, but you can hook into the ajax complete callback and manually build up a valid input cache, and then check against that on change/blur.
var myData = new Bloodhound({
remote: {
url: '/my/path/%QUERY.json',
ajax: {
complete: function(response){
response.responseJSON.forEach(function (item) {
if (myData.valueCache.indexOf(item.value) === -1) {
myData.valueCache.push(item.value);
}
});
}
}
}
});
myData.valueCache = [];
myData.initialize();
$('#artists .typeahead').typeahead(null, {
source: myData.ttAdapter()
}).bind('change blur', function () {
if (myData.valueCache.indexOf($(this).val()) === -1) {
$(this).val('');
}
});
I solved this problem a little differently - most of the time you need to capture the id of the suggested options, to post to a subsequent web service call, etc.
I decided to blank out a hidden field when the typeahead async call starts, and set the value of the hidden field to the datum.id on the autocompleted or selected typehead events.
When submitting the form, I simply check if the hidden field has a value or not, if it doesn't, then the user never selected a suggested option.
I named the hidden field by adding a _id to it based on the name of the typeahead field, and then used this code in the onAutocompleted and onSelected functions
I specified those functions by adding:
.on('typeahead:selected', onAutocompleted)
.on('typeahead:autocompleted', onSelected)
in the code that adds the .typeahead functionality to the input field.
var n = $(this).attr('name')+'_id';
$('input[name="' + n + '"]').val(datum.id);
The typeahead documentation talks about there being three parameters that are passed to the autocompleted and selected functions, the event, the datum, and the name, but I never saw the name being passed, and that's why I used the $(this).attr('name') mechanism to get the name of the field.
If I understand, when the typeahead component loses the focus, the user should be alerted that its input is invalid if it is not in the list?
The code will thus be something like this :
var myData = [...]; // This array will contain all your possible data for the typeahead
$("#my-type-ahead").typeahead({source : myData})
.blur(validateSelection);
function validateSelection() {
if(source.indexOf($(this).val()) === -1)
alert('Error : element not in list!');
}
Just be careful about the fact that indexOf
is not implemented in IE6-8. But shims can be found, for example : Best way to find if an item is in a JavaScript array? .