Below please find a mod for adding an option to AutoComplete.
The option is 'afterNoMatch'. It specifies a function to call if the
value provided does not match any value in the dropdown box. This has
been mentioned as a problem, and I needed a solution. So, here it is.
If the autocomplete cannot return a value (it's not found by the JSON
lookup), the callback is called. At this point, I reset the values of
a div and a hidden field holding the ID of the thing I was looking
for.
This may not be perfect, but it does get the job done.
NOTE: This code is also on by blogspot blog ('justanyone') at
http://justanyone.blogspot.com .
First, how to call it:
<script type="text/javascript">
var autocompleteJSON = function(raw) {
var json = typeof(raw) === "array" ? raw : raw.resultSet;
var parsed = [];
for (var i=0; i <json.length; i++) {
var row =json[i];
parsed.push({
data: row,
value: row["orgName"] + ' [' + row["id"] + ']',
result: row["orgName"]
});
}
return parsed;
};
function afterNoMatch() {
document.forms[0].mcOrgID.value = 'nomatch';
locationDiv = document.getElementById('mcOrgLocationDiv')
locationDiv.innerHTML = "<b>Manually Entered Organization Name -
No location.</b>";
return;
}
function formatCompanyName(row) {
ret = row["orgName"] + " (id: " + row["id"] + ") " + row
["orgCity"] + ", " + row["orgState"]
document.forms[0].mcOrgID.value = row['id'];
return ret
}
</script>
<script>
$(document).ready(function(){
var data = "Core Selectors Attributes Traversing Manipulation CSS
Events Effects Ajax Utilities".split(" ");
$("#mcOrgName").autocomplete('BrowseOrgsJSON.py')
.result(function(event, data, formatted) {
//alert("Got data back from server: name=" + data['orgName'] +
", id=" + data['id'] + ", city=" + data['orgCity'] + ", state=" + data
['orgState'] + ", formatted=" + formatted);
$("#mcOrgLocationDiv").html('Location: ' + data['orgCity'] +
', ' + data['orgState'] + ' (Textura Organization id: ' + data['id']
+ ')' );
document.forms[0].mcOrgID.value = data['id'];
});
$("#mcOrgName").setOptions({scrollHeight :
400 });
$("#mcOrgName").setOptions({queryArgument :
"search" });
$("#mcOrgName").setOptions({formatItem :
formatCompanyName });
// $("#mcOrgName").setOptions({autoFill :
true }); CANNOT DO THIS WITH SUBSTRING
SEARCH.
$("#mcOrgName").setOptions({mustMatch :
false });
$("#mcOrgName").setOptions({dataType :
"json" });
$("#mcOrgName").setOptions({parse :
autocompleteJSON });
$("#mcOrgName").setOptions({selectFirst :
false });
$("#mcOrgName").setOptions({extraParams : {'includeOffSystem':
'False'} });
$("#mcOrgName").setOptions({afterNoMatch :
afterNoMatch });
});
</script>
Now, here's the code. I'll start off with the diff and then cut/paste
the section the code is in case the code changes between now and the
time you're reading this.
In jquery.autocomplete.js, the function hideResultsNow() is changed to
be the following:
function hideResultsNow() {
var wasVisible = select.visible();
select.hide();
clearTimeout(timeout);
stopLoading();
if (options.mustMatch) {
// call search and run callback
$input.search(
function (result){
// if no value found, clear the input
box
if( !result ) {
if (options.multiple) {
var words =
trimWords($input.val()).slice(0, -1);
$input.val(
words.join(options.multipleSeparator) +
(words.length ? options.multipleSeparator : "") );
}
else
$input.val( "" );
}
}
);
}
else
{
// call search and run callback
$input.search(
function (result){
if( !result ) {
options.afterNoMatch();
}
}
);
}
if (wasVisible)
// position cursor at end of input field
$.Autocompleter.Selection(input, input.value.length,
input.value.length);
};
and one option is added to the options section:
...
max: 100,
mustMatch: false,
afterNoMatch: function() { return; },
extraParams: {},
selectFirst: true,
...
Now for the technical diff:
Index: resources/js/jquery/autocomplete/jquery.autocomplete.js
==============================================================
307a308,319
> else
> {
> // call search and run callback
> $input.search(
> function (result){
> if( !result ) {
> options.afterNoMatch();
> }
> }
> );
> }
>
310a323
>
403a417
> afterNoMatch: function() { return; },