This was an interesting question sent to me by Joel:
I have a text input that it used for a search criteria, and I only want to enable the search button when at least 5 characters have been entered. (The list of possible matches is huge, and I don't want 25,000 results returned to the browser.)Apparently dealing with a browser's autocomplete isn't quite as simple as one would think. I did a quick example to prove this (and I wanted a non-jQuery UI one to test):
Suppose the text input is called "searchBox". With jQuery, I can do this:
$("#searchBox").keyup(function() {
$("#btnGo").button("option", "disabled", $(this).val().length < 5 );
});
(It's a jQuery UI button, which is why the syntax for enabling is different from a normal button).
Most browsers keep a form input history. So If I start to type "apple" and I've typed it before, I can just click and choose it from the list. This does not fire the keyup event. I can bind "change" also, but that only fires when the input loses focus. Any thoughts on how to bind the selection of form history to enable the button?
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script>
$(document).ready(function() {
$("#search").keyup(function() {
$("#searchBtn").attr("disabled", $(this).val().length < 5 );
});
})
</script>
</head>
<body>
<form action="test.html" method="post">
<input type="text" name="search" id="search"> <input type="submit" value="Search" id="searchBtn" disabled="true">
</form>
If you run this (online demo here) and enter a few values, you should be able to see the "manual" approach work, but as soon as you use something from the browser's autocomplete history, it doesn't register. In my initial Google search, the first result I found suggested simply turning it off. That's doable but not exactly a solution. What about using the change handler?
$("#search").change(function() {
$("#searchBtn").attr("disabled", $(this).val().length < 5 );
});
That works - but not immediately. The user has to click elsewhere to register the change. After a bit more searching I found this comment on the jQuery docs for change. The user, Robin, mentioned listening for a new HTML5, input. (This was the first time I'd heard of this. I thought I knew about all the HTML5 Form stuff. Guess I was wrong. Looks to be documented here.) I gave this a try:
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script>
$(document).ready(function() {
$("#search").keyup(function() {
$("#searchBtn").attr("disabled", $(this).val().length < 5 );
});
$("#search").live("input",function() {
$("#searchBtn").attr("disabled", $(this).val().length < 5 );
});
})
</script>
</head>
<body>
<form action="test.html" method="post">
<input type="text" name="search" id="search"> <input type="submit" value="Search" id="searchBtn" disabled="true">
</form>
You can demo this one here. Good news! Works in Chrome. Works in Firefox. Works in - oh crap. Not IE. Since apparently IE9 doesn't support anything Form-related in HTML5. sigh At this point, I'm willing to just give up on IE and just use "change" - as I said, it doesn't work immediately, but by this point, IE users are probably used to a substandard experience. Here is the "final" template I used.
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script>
$(document).ready(function() {
$("#search").keyup(function() {
$("#searchBtn").attr("disabled", $(this).val().length < 5 );
});
$("#search").change(function() {
$("#searchBtn").attr("disabled", $(this).val().length < 5 );
});
$("#search").live("input",function() {
$("#searchBtn").attr("disabled", $(this).val().length < 5 );
});
})
</script>
</head>
<body>
<form action="test.html" method="post">
<input type="text" name="search" id="search"> <input type="submit" value="Search" id="searchBtn" disabled="true">
</form>
You can try this demo here. So - does anyone have a nicer solution?