jquery autocomplete renderItem - jquery-ui

I have the following code. It generates no js errors. Can't get the autocomplete to display any results:
$(function() {
$.ajax({
url: "data.xml",
dataType: "xml",
cache: false,
success: function (xmlResponse) {
var data_results = $("Entry", xmlResponse).map(function () {
return {
var1: $.trim($("Partno", this).text()),
var2: $.trim($("Description", this).text()),
var3: $.trim($("SapCode", this).text()),
var4: $("Title", this).text(),
var5: $.trim($("File", this).text()),
var6: $.trim($("ItemID", this).text())
};
}).get();
$("#searchresults").autocomplete({
source: data_results,
minLength: 3,
select: function (event, ui) {
...
}
}).data( "autocomplete" )._renderItem = function( ul, item ) {
return $( "<li></li>" ).data("item.autocomplete", item)
.append( "<a>" + item.var1 + "<br>" + item.var2 + "</a>")
.appendTo( ul );
};
}
});
Any ideas what I might be missing? Thanks in advance.

It seems that .data('autocomplete') is now .data('ui-autocomplete').
Source: http://jqueryui.com/upgrade-guide/1.10/#removed-data-fallbacks-for-widget-names

By default, autocomplete expects your source array to contain objects with either a label property, a value property, or both.
With that in mind you have two options:
Add a label or value property to your source objects when you process the array from your AJAX call:
var data_results = $("Entry", xmlResponse).map(function () {
return {
var1: $.trim($("Partno", this).text()),
var2: $.trim($("Description", this).text()),
var3: $.trim($("SapCode", this).text()),
var4: $("Title", this).text(),
var5: $.trim($("File", this).text()),
var6: $.trim($("ItemID", this).text()),
value: $.trim($("Description", this).text())
};
}).get();
The value you assign will be used on focus, select, and to search on.
Change the source function to perform custom filtering logic:
$("#searchresults").autocomplete({
source: function (request, response) {
var matcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), "i");
response($.grep(data, function (value) {
return matcher.test(value.var1) ||
matcher.test(value.var2);
/* etc., continue with whatever parts of the object you want */
}));
},
minLength: 3,
select: function (event, ui) {
event.preventDefault();
this.value = ui.var1 + ui.var2;
},
focus: function (event, ui) {
event.preventDefault();
this.value = ui.var1 + ui.var2;
}
}).data( "autocomplete" )._renderItem = function( ul, item ) {
return $( "<li></li>" ).data("item.autocomplete", item)
.append( "<a>" + item.var1 + "<br>" + item.var2 + "</a>")
.appendTo( ul );
};
Note that with this strategy you have to implement custom select and focus logic.

Related

Lack of selecting capacity with if statement / append method

I want to propose an autocomplete list (jquery ui 1.8) with some words in bold font.
The JSON source looks like :
{"especes":[{"fk_sp":number,"nom_espece":name,"nom_valide":0 or 1}].
My script is like that :
$(function(){
$('#id').autocomplete({
source: function(request, response) {
$.getJSON("fichier.php", {
term: request.term
}, function(data) {
var array = data.error ? [] : $.map(data.especes, function(m) {
return {
label: m.nom_espece,
value: m.fk_sp,
valid: m.nom_valide
};
});
response(array);
});
},
select: function (event, ui) {
$("#espece").val(ui.item.label);
$("#fk_sp").val(ui.item.value);
}
}).data( "ui-autocomplete" )._renderItem = function( ul, item ) {
return $( "<li></li>" )
.data( "item.autocomplete", item )
.append( item.valid == '1' ? "<b>" + item.label + "</b>" : item.label)
.appendTo( ul );
};
});
If I use :
.data( "ui-autocomplete" ) => I have the good selectable list without the bold lines,
.data( "ui-Autocomplete" ) ou .data( "uiAutocomplete" ) => nothing works,
and if I juste write ._renderItem without .data( "ui-autocomplete" ) => I have a pretty list with the good names in bold, but I can't select any name of the list !
I don't find where is my error (I suppose it is somwhere with the "select :" part).

jquery autocomplete call function if only 1 record returned

I am wanting to run a function of the jQuery autocomplete below only returns 1 result. I am not sure how to check that there is only 1 result in the list.
Please help.
$(function() {
function log(message) {
$("<div>").text(message).prependTo("#log");
$("#log").scrollTop(0);
}
$("#inputBox2").autocomplete({
source: "searchsalonproduct.php",
cacheLength: 0,
minLength: 1,
select: function(event, ui) {
addcharge(ui.item.id);
return false;
}
}).data("ui-autocomplete")._renderItem = function(ul, item) {
return $("<li></li>")
.data("item.autocomplete", item)
.append("<a>" + item.label + "</a>")
.appendTo(ul);
};
});
Use the response event to check. The results found are stored in ui.content (ui is an argument in the event handler).
$("#inputBox2").autocomplete({
source: "searchsalonproduct.php",
cacheLength: 0,
minLength: 1,
select: function(event, ui) {
addcharge(ui.item.id);
return false;
},
response: function(event, ui) {
if(ui.content.length === 1) {
//do stuff
}
}
}).data("ui-autocomplete")._renderItem = function(ul, item) {
return $("<li></li>")
.data("item.autocomplete", item)
.append("<a>" + item.label + "</a>")
.appendTo(ul);
};

jquery ui autocomplete with autoselect plugin

I am using a jquery ui autocomplete. when the user types in their own value, rather than selecting an item from the list, the textbox clears. This is ok (I don't want the user to be able to enter their own values) except if the user types in a value that does exist on the list.
I tried using the autoSelect plugin as detailed in this post, but it is not working - I added the plugin but when I type in a value that IS on the list and hit tab, I get the same results as before - the textbox clears.
Here is my autocomplete:
$(function () {
$('[id$="txtDocType').autocomplete({
source: function (request, response) {
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "/MyPage.aspx/myFunction",
data: "{'prefixText':'" + request.term.toLowerCase() + "', 'ddvId':'" + this.element.data('autocomplete') + "'}",
dataType: "json",
success: function (data) {
response(data.d);
},
error: function (result) { }
});
},
minlength: 1,
select: function (event, ui) {
$('#divOtherFields input[type=text], input[type=password]').prop("disabled", false).removeClass("disabled");
$('[id$="btnSaveNext"],[id$="btnSaveClose"]').prop("disabled", false);
$('[id$="txtReceiptDate"]').datepicker("setDate", new Date());
}
});
});
Here is the plugin:
(function( $ ) {
$.ui.autocomplete.prototype.options.autoSelect = true;
$( ".ui-autocomplete-input" ).on( "blur", function( event ) {
var autocomplete = $( this ).data( "autocomplete" );
if ( !autocomplete.options.autoSelect || autocomplete.selectedItem ) { return; }
var matcher = new RegExp( "^" + $.ui.autocomplete.escapeRegex( $(this).val() ) + "$", "i" );
autocomplete.widget().children( ".ui-menu-item" ).each(function() {
var item = $( this ).data( "item.autocomplete" );
if ( matcher.test( item.label || item.value || item ) ) {
autocomplete.selectedItem = item;
return false;
}
});
if ( autocomplete.selectedItem ) {
autocomplete._trigger( "select", event, { item: autocomplete.selectedItem } );
}
});
}( jQuery ));
I set a breakpoint in the plugin on this line - "$( ".ui-autocomplete-input" ).on( "blur", function( event )" and the breakpoint was hit, yet the code would not step through. When I set a breakpoint to this line - "var autocomplete = $( this ).data( "autocomplete" );" the breakpoint was NOT hit.
Any ideas? I am at my wits end with this.
I solved this by making a couple of tweaks to the autoSelect plugin. Here is the code that eventually worked for me:
$(".ui-autocomplete-input").bind("focusout", function (event) {
var autocomplete = $(this).data("ui-autocomplete");
if (!autocomplete.options.autoSelect || autocomplete.selectedItem) { return; }
var matcher = new RegExp("^" + $.ui.autocomplete.escapeRegex($(this).val()) + "$", "i");
autocomplete.widget().children(".ui-menu-item").each(function () {
var item = $(this).data("ui-autocomplete-item");
if (matcher.test(item.label || item.value || item)) {
autocomplete.selectedItem = item;
return false;
}
});
if (autocomplete.selectedItem) {
autocomplete._trigger("select", event, { item: autocomplete.selectedItem });
}
});
I used the focus event to set the first value to a hidden variable. The same hidden variable also got updated in the select event. And then this was the hidden variable which I posted to the ajax call.
Why I did not use focus to set the value in the autocomplete input box, was because doing so populated the autocomplete input box even while I was typing in this box.
focus: function (event, ui) {
if($("#streetid")) $("#streetid").val(ui.item.label); //this was my hidden variable
}
},

jQueryUI Autocomplete - Multiple controls - One function

I am using the jQueryUI autocomplete, have used it many times before, but I now have a more complex requirement.
I have a variable amount of Autocomplete fields to setup, using a JSON datasource and want to use an $().each to set these up. The problem appears to be the data: property of the AJAX call is always defaulting to values the final Autocomplete I setup.
$('[id$=CheckMethod]').each(function(index) {
if ($(this).val() === 'List') {
fieldToSetup = ($(this).attr('id').replace('txt',''));
fieldToSetup = left(fieldToSetup,(fieldToSetup.length - 11));
alert(fieldToSetup);
$('#txt' + fieldToSetup + 'CodeRoom' + escape(inRoomID)).autocomplete({
source: function (request, response) {
var src,
arrayData;
src = 'AJAXCheckCode.asp?actionType=List&GUID=' + $('#txtGUID').val();
$.ajax({
url: src,
datatype: 'json',
data: 'inCode=' + request.term + '&inType=' + $(this).attr('id'),
success: function (outData) {
arrayData = $.parseJSON(outData);
response($.map(arrayData, function (item) {
var theLabel = (item.Notes.length > 0) ? item.TheCode + ' - ' + item.Notes : item.TheCode;
return {
label: theLabel,
value: item.TheCode
};
}));
}
});
},
minLength: 1,
open: function (event, ui) {
$(".ui-slider-handle ui-state-default ui-corner-all").hide();
$(".ui-autocomplete.ui-menu").width(400);
$(".ui-autocomplete.ui-menu").css('z-index', 1000);
},
close: function (event, ui) {
$(".ui-slider-handle ui-state-default ui-corner-all").show();
},
focus: function (event, ui) {
return false;
},
select: function (event, ui) {},
search: function (event, ui) {
}
});
}
});//each CheckMethod
This code results in the 1st Autocomplete field using the inType parameter from the last field setup.
I'd rather not code for a maximum of 4 x 6 Autocomplete fileds and am trying to create one function to setup all the fields, is this possible?
Therefore my AJAX URL for my 1st Autocomplete looks like this
http://foo.com/AJAXCheckCode.asp?actionType=List&GUID={838138D6-A329-40F1-924B-58965842ECF8}&inCode=es&inType=A3&_=1335875408670
when "inType" should actually be A2, not A3 which is the last item of the outer $.each()
Hope this makes some sense!
Solved in the end by adding a class to the text box and then using live() on any text box with the given class that hasn't been bound before...works a charm
$('.foo:not(.ui-autocomplete-input)').live('focus', function(){
var fieldToReSource = ($(this).attr('id').replace('txt',''));
fieldToReSource = left(fieldToReSource,(fieldToReSource.length - 5));
$(this).autocomplete({
source: function (request, response) {
var src,
arrayData;
src = 'AJAXCheckCode.asp?inType=' + fieldToReSource + '&actionType=List&GUID=' + $('#txtGUID').val();
$.ajax({
url: src,
datatype: 'json',
data: 'inCode=' + request.term,
success: function (outData) {
arrayData = $.parseJSON(outData);
response($.map(arrayData, function (item) {
var theLabel = (item.Notes.length > 0) ? item.TheCode + ' - ' + item.Notes : item.TheCode;
return {
label: theLabel,
value: item.TheCode
};
}));
}
});
},
minLength: 1,
open: function (event, ui) {
$(".ui-slider-handle ui-state-default ui-corner-all").hide();
$(".ui-autocomplete.ui-menu").width(400);
$(".ui-autocomplete.ui-menu").css('z-index', 1000);
},
close: function (event, ui) {
$(".ui-slider-handle ui-state-default ui-corner-all").show();
},
focus: function (event, ui) {
return false;
},
select: function (event, ui) {
},
search: function (event, ui) {
}
});
});

jQuery UI autocomplete, show something when no results

I have the following code:
// Autocomplete search
$("#shop_search").autocomplete({
source: '<%= spotify_search_path(:json) %>',
minLength: 1,
select: function(event, ui) {
append_place(ui.item.name, ui.item.id, ui.item.shop_type, ui.item.address_geo, ui.item.contact, ui.item.email, ui.item.web);
$("#shop_search").val('');
}
}).data( "autocomplete" )._renderItem = function( ul, item ) {
return $( "<li></li>" )
.data( "item.autocomplete", item )
.append( "<a>" + "<span class='autocomplete_link'>" + item.name + "</span>" + "<br />" + "<span class='autocomplete_address'>" + item.address_geo + "</span>" + "</a>" )
.appendTo( ul );
$(".ui-autocomplete-loading").ajaxStart(function(){
$(this).show();
});
$(".ui-autocomplete-loading").ajaxStop(function(){
$(this).hide();
});
};
Currently it only shows the drop down autocomplete when there is search result. I want it to show "No matches found" when nothing could be found. What should I add into the code?
Thanks.
If you use a jQuery ajax call for the source, you can append "No results found" to the results if there aren't any. Then on the select method, you can simply check to see if the item is the "no results found" item that you added and if so, do nothing. Here I identified that by checking to see if the id was equal to zero.
$("#shop_search").autocomplete({
source: function (request, response) {
$.ajax({
url: "<%= spotify_search_path(:json) %>",
data: {
term: request.term
},
success: function (data) {
if (data.length == 0) {
data.push({
id: 0,
label: "No results found"
});
}
response(data);
}
});
},
select: function (event, ui) {
if (ui.item.id != 0) {
append_place(ui.item.name, ui.item.id, ui.item.shop_type, ui.item.address_geo, ui.item.contact, ui.item.email, ui.item.web);
$("#shop_search").val('');
}
}
});
You'll need to do some work on your template to get the "no results found" to display properly, but this should get you on the right track.
You can just check if item is null or 0.
If item is 0 or null append "No matches found" else append the item. That's basically the whole logic.
May be this helps
source: function( request, response ) {
$.getJSON( url, {
term: extractLast( request.term )
}, response )
.error(function() {
console.log("no results");
});
},
$( "#jsonNameSearch" ).autocomplete({
// This is the source of the autocomplete, in the success method if the
// length of the response is zero then highlight the field indicating no match.
source: function( request, response ) {
$.getJSON( 'jsonAutocomplete.ajax?dataType=drivers', {
term: request.term
}, response )
.success(function(data) {
(data.length == 0) ? $( "#jsonNameSearch" ).addClass('nomatch') : $( "#jsonNameSearch" ).removeClass('nomatch');
});
},
select: function( event, ui ) {
if (ui.item) self.location.replace('driverModify.htm?id='+ui.item.id);
}
});

Resources