I have got the autocomplete to work but with errors. How would i format the response code correctly?
Response Code:
{
label: "Label 1",
value: "27"
},
{
label: "Label 2",
value: "18"
},
{
label: "Dave",
value: "25"
},
{
label: "Jacqui Potatoes",
value: "17"
}
Javascript:
$("#account_search .ac_input").autocomplete({
minLength: 0,
source: base_url + "accounts/ac_results/account_name",
dataType: "json",
type: "POST",
}).data( "autocomplete" )._renderItem = function( ul, item ) {
.data( "item.autocomplete", item )
.append( "<a>" + item.label + "<br>" + item.desc + "</a>" )
.appendTo( ul );
return $( "<li></li>" );
};
I think the .data() function is the problem although it is working somehow. I would like to access both the label and value
You've got an error in the _renderItem function (you should call .data on the newly created <li></li>):
.data( "autocomplete" )._renderItem = function( ul, item ) {
return $( "<li></li>" )
.data( "item.autocomplete", item )
.append( "<a>" + item.label + "<br>" + item.value + "</a>" )
.appendTo( ul );
};
I also replaced item.desc which did not exist on your JSON response with item.value.
As a sidenote, you may not need to override that function at all. You only need to use it if you want to change the way each item looks in the suggestion list.
Also, make sure to remove that extra comma in the options object. Additionally, the options dataType and type are not valid options anyway:
$("#account_search .ac_input").autocomplete({
minLength: 0,
source: base_url + "accounts/ac_results/account_name"
});
Example (local data source): http://jsfiddle.net/nG8Q4/
Related
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).
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.
I tried to use jQuery combobox (fiddle) in my Mozilla Firefox addon. But AMO editors rejected my Addon after reviewing stating that my javascript does unsafe HTML insertion with unsanitized data. Parts of the code stated as unsafe all belong to the code on official jQuery Ui page for combobox. I am also writing the code below. Removing this piece of code throws error if I try to create a combobox.
It makes me wonder why combobox isn't already included in jQuery and why do I have to put this snippet inside my code? Am I doing anything wrong here. Alternatively Can someone suggest me how can I make this code taken from official jquery page safe and sanitized?
(function( $ ) {
$.widget( "ui.combobox", {
_create: function() {
var self = this,
select = this.element.hide(),
selected = select.children( ":selected" ),
value = selected.val() ? selected.text() : "";
var input = this.input = $( "<input>" )
.insertAfter( select )
.val( value )
.autocomplete({
delay: 0,
minLength: 0,
source: function( request, response ) {
var matcher = new RegExp( $.ui.autocomplete.escapeRegex(request.term), "i" );
response( select.children( "option" ).map(function() {
var text = $( this ).text();
if ( this.value && ( !request.term || matcher.test(text) ) )
return {
label: text.replace(
new RegExp(
"(?![^&;]+;)(?!<[^<>]*)(" +
$.ui.autocomplete.escapeRegex(request.term) +
")(?![^<>]*>)(?![^&;]+;)", "gi"
), "<strong>$1</strong>" ),
value: text,
option: this
};
}) );
},
select: function( event, ui ) {
ui.item.option.selected = true;
self._trigger( "selected", event, {
item: ui.item.option
});
},
change: function( event, ui ) {
if ( !ui.item ) {
var matcher = new RegExp( "^" + $.ui.autocomplete.escapeRegex( $(this).val() ) + "$", "i" ),
valid = false;
select.children( "option" ).each(function() {
if ( $( this ).text().match( matcher ) ) {
this.selected = valid = true;
return false;
}
});
if ( !valid ) {
// remove invalid value, as it didn't match anything
$( this ).val( "" );
select.val( "" );
input.data( "autocomplete" ).term = "";
return false;
}
}
}
})
.addClass( "ui-widget ui-widget-content ui-corner-left" );
input.data( "autocomplete" )._renderItem = function( ul, item ) {
return $( "<li></li>" )
.data( "item.autocomplete", item )
.append( "<a>" + item.label + "</a>" )
.appendTo( ul );
};
this.button = $( "<button type='button'> </button>" )
.attr( "tabIndex", -1 )
.attr( "title", "Show All Items" )
.insertAfter( input )
.button({
icons: {
primary: "ui-icon-triangle-1-s"
},
text: false
})
.removeClass( "ui-corner-all" )
.addClass( "ui-corner-right ui-button-icon" )
.click(function() {
// close if already visible
if ( input.autocomplete( "widget" ).is( ":visible" ) ) {
input.autocomplete( "close" );
return;
}
// work around a bug (likely same cause as #5265)
$( this ).blur();
// pass empty string as value to search for, displaying all results
input.autocomplete( "search", "" );
input.focus();
});
},
destroy: function() {
this.input.remove();
this.button.remove();
this.element.show();
$.Widget.prototype.destroy.call( this );
}
});
})( jQuery );
Anyone know why the following does not work?
$.each( data.d, function( index, item ) {
// creates the tabs with custom ids
$( "#tabs" ).tabs( "add", "page.aspx?id=" + item.id, item.name )
.find('>ul>li:last')
.attr('id', 'tab_' + item.id);
// creates the buttons
$( "#buttons" ).append( "<input type='button' id='buttona" + item.id + "' value='" + item.name + "'>" );
// link buttons with tabs
$( "#buttona" + item.id ).live('click', function() {
$( "#tabs" ).tabs( "select" , "#tab_" + item.id );
});
});
I am trying to assign id's to the tabs, then select the tabs using their id's.
The above does nothing when a button is clicked and it returns no errors at all.
It works fine when using the index as shown below, but I need to use an id for various reasons:
$.each( data.d, function( index, item ) {
// creates the tabs
$( "#tabs" ).tabs( "add", "page.aspx?id=" + item.id, item.name );
// creates the buttons
$( "#buttons" ).append( "<input type='button' id='button" + index + "' value='" + item.name + "-" + index + "'>" );
// link buttons with tabs
$( "#button" + index ).live('click', function() {
$( "#tabs" ).tabs( "select" , index );
});
});
You can use the index() method to get the index of the tab from the id of its header:
$("#button" + item.id).live("click", function() {
$("#tabs").tabs("select", $("#tab_" + item.id).index());
});
Since index() is called without arguments in the code above, it will return the index of the element relative to its siblings, i.e. the other tab headers.
you can switch the tabs with the id of the tab:
var $tabs = $("#tabs").tabs();
$("button").click(function() {
$tabs.tabs( "select", "#tabs-6" );
});
It seems to me that .index() returns an index from 1 so that if I have 3 tabs and want to select the third one, I should return :
$("#button" + item.id).live("click", function() {
$("#tabs").tabs("select", $("#tab_" + item.id).index()-1);
});
This answer -- jQueryUI: how can I custom-format the Autocomplete plug-in results? -- describes how to monkeypatch the jqueryUI autocomplete widget, so that it displays things in a particular way. The approach it uses is to replace a function on the $.ui.autocomplete.prototype.
This means that all autocomplete widgets will get this patch.
Is there a way to patch the autocomplete widget for just one input element?
What is it?
When I examine $('$input').autocomplete , I don't see any of the autocomplete fns there (_renderItem, _renderMenu, _search, etc).
Check out the custom data and display demo. This demo is not modifying the prototype object of the autocomplete widget, meaning that only that instance of the widget is effected:
$("selector").autocomplete({ ... }).data( "autocomplete" )._renderItem = function( ul, item ) {
return $( "<li></li>" )
.data( "item.autocomplete", item )
.append( "<a>" + item.label + "<br>" + item.desc + "</a>" )
.appendTo( ul );
};
Here's a working demo: http://jsfiddle.net/vJSwq/
The code from Andrew Whitaker just work for one autocomplete input. If you select more than one input-element, the second autocomplete widget dosn't show any entrys.
You have to add a foreach to handel all selected input elements like mentioned here
$("selector")
.autocomplete({ ... })
.each(function () {
$(this).data("autocomplete")._renderItem = function( ul, item ) {
return $("<li></li>")
.data("item.autocomplete", item)
.append("<a>" + item.label + "<br>" + item.desc + "</a>")
.appendTo(ul);
};
);
For recent versions of jQuery(1.8+) / jQuery UI (1.10+), you should use:
$("selector").autocomplete({ ... }).data('uiAutocomplete')._renderItem = function( ul, item ) {
return $( "<li></li>" )
.data( "item.autocomplete", item )
.append( "<a>" + item.label + "<br>" + item.desc + "</a>" )
.appendTo( ul );
};