I would like to have validation on a text input field with Twitter Bootstrap typeahead. So I tried implementing it as follows. The validation on the name field works correctly. If you start typing in it and clear the field again, validation kicks in. On the location field however, which has data-provide="typeahead"
on it, this does not happen. Validation does kick in when you click the submit button however.
I tried debugging it, but as far as I can see both Bootstrap and jQuery Validate register their event handlers correctly. Even stranger, the typeahead is installed before validate. So one would expect typeahead to be broken. But it isn't...
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" type="text/css" href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.1.0/css/bootstrap-combined.min.css" />
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.js"></script>
<script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.10.0/jquery.validate.js"></script>
<script type="text/javascript" src="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.1.0/js/bootstrap.js"></script>
<script type="text/javascript">
$(function() {
$('[data-provide="typeahead"]').each(function() {
var url = $(this).attr('data-url');
$(this).typeahead({
source : function(query, process) {
return $.get(url, {
name : query
}, function(data) {
var json = JSON.parse(data);
return process(json.locations);
});
},
items : 5
});
});
$('#settings-form').validate({
rules: {
name: {
required: true
},
location: {
required: true
}
},
highlight: function(label) {
var controlGroup = $(label).closest('.control-group');
controlGroup.addClass('error');
var buttons = controlGroup.find('button');
buttons.addClass('btn-danger');
buttons.attr('disabled', 'disabled');
},
success: function(label) {
var controlGroup = $(label).closest('.control-group');
controlGroup.removeClass('error');
var buttons = controlGroup.find('button');
buttons.removeClass('btn-danger');
buttons.removeAttr('disabled');
},
errorPlacement: function(error, element) {
error.appendTo(element.closest('.control-group'));
}
});
});
</script>
<style type="text/css">
body {
margin: 20px;
}
label.error {
margin-left: 160px;
margin-bottom: 0;
}
</style>
</head>
<body>
<form id="settings-form" class="form-horizontal" action="#" method="GET">
<fieldset>
<div class="control-group">
<label class="control-label" for="name">Name</label>
<div class="controls">
<input type="text" id="name" name="name" autocomplete="off" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="location">Location</label>
<div class="controls">
<input type="text" id="location" name="location" autocomplete="off" data-provide="typeahead" data-url="locations.json" />
</div>
</div>
</fieldset>
<div class="control-group">
<div class="controls">
<button class="btn" data-dismiss="modal">Cancel</button>
<button class="btn btn-primary" type="submit">Save changes</button>
</div>
</div>
</form>
</body>
</html>
locations.json:
{
"locations": [
"Berlin",
"London",
"Madrid",
"New York",
"Paris"
]
}
Yes - it is because Twitter Bootstrap Typeahead hides events from the validator by e.stopPropagation()
in function Typeahead.prototype.keyup()
Add a keyup-handler to #location
to invoke validation "manually", for it to work:
<input type="text" id="location" name="location" autocomplete="off"
data-provide="typeahead" onkeyup="$(this).validate();" data-url="locations.json" />
It doesnt change the behaviour / validation settings, simply just ensuring validation is called at all..
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With