So, I'm trying to use HTML links in my catcomplete results, but jquery automatically transforms my html code into text, like on the image:
And my jQuery code is:
$( "#global-search" ).catcomplete({
delay: 0,
source: "globalsearch.php"
});
Please, dont say to me to use select: function( event, ui ) {
window.location.href = ui.item.value;
}, because it works only once when using ajax (I really don't know why, but it just doesn't work), and I asked some questions here yesterday asking how to fix it, and nobody helped me with it.
So, back with the html transformed into text, how can I add an html hyperlink to my results?
globalsearch.php:
Take a look at the Custom Data and Display example. You will see that they have replaced the _renderItem method with a custom one. You'll need to do the same thing to override how your items are displayed.
$('#global-search').data( "autocomplete" )._renderItem = function( ul, item ) {
return $( "<li>" )
.data( "item.autocomplete", item )
.append((item.link) ? "<a href='" + item.link + "'>" + item.label + "</a>" : "<a>" + item.label + "</a>" )
.appendTo( ul );
};
Without seeing the output of your globalsearch.php I can't tell you exactly how to set it up, but basically you'd want to add a link attribute to your returned JSON and if the link exists, print the anchor with the link as its href.
How you handle the selection links vs outside links is left as an exercise to the OP.
From the autocomplete widget documentation
Independent of the variant you use, the label is always treated as
text. If you want the label to be treated as html you can use Scott
González' html extension. The demos all focus on different variations
of the source option - look for one that matches your use case, and
check out the code.
Scott González' html extension is https://github.com/scottgonzalez/jquery-ui-extensions/blob/master/autocomplete/jquery.ui.autocomplete.html.js. I have also posted the code below.
/*
* jQuery UI Autocomplete HTML Extension
*
* Copyright 2010, Scott González (http://scottgonzalez.com)
* Dual licensed under the MIT or GPL Version 2 licenses.
*
* http://github.com/scottgonzalez/jquery-ui-extensions
*/
(function( $ ) {
var proto = $.ui.autocomplete.prototype,
initSource = proto._initSource;
function filter( array, term ) {
var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
return $.grep( array, function(value) {
return matcher.test( $( "<div>" ).html( value.label || value.value || value ).text() );
});
}
$.extend( proto, {
_initSource: function() {
if ( this.options.html && $.isArray(this.options.source) ) {
this.source = function( request, response ) {
response( filter( this.options.source, request.term ) );
};
} else {
initSource.call( this );
}
},
_renderItem: function( ul, item) {
return $( "<li></li>" )
.data( "item.autocomplete", item )
.append( $( "<a></a>" )[ this.options.html ? "html" : "text" ]( item.label ) )
.appendTo( ul );
}
});
})( jQuery );
EDIT try the code below while using the extension
$( "#global-search" ).catcomplete({
delay: 0,
html: true,
source: "globalsearch.php"
});
Related
I already read all the topics there about a similar issue but no real solution.
I just received an old project using Jquery UI, the form has a autocomplete input, it works perfectly on computers & phones, when you type 3 letters minimum, it suggests a list of words.
BUT when you try the same form on iPad, nothing happens. It suggests nothing.
Here the code (based on Jquery 2.2.3 & Jquery UI 1.11.4) :
HTML :
<input type="text" class="form-control autocomplete-multiple-theme-name ui-autocomplete-input" style="width: 100%;" autocomplete="off">
<input type="hidden" class="autocomplete-multiple-theme-id">
JS :
$(".autocomplete-multiple-theme-name").autocomplete({
minLength: 3,
source: 'themes/themes_json.php',
focus: function( event, ui ) {
$(this).val( ui.item.label );
return false;
},
select: function( event, ui ) {
$(this).val( ui.item.label);
return false;
}
})
.autocomplete( "instance" )._renderItem = function( ul, item ) {
return $( "<li>" )
.append( "<div>" + item.label + "</div>" )
.appendTo( ul );
};
Any idea to fix that ?
Thanks a lot everybody !
I am using jquery ui 1.10.3 and jquery 2.0.3.
I am trying to use the autocomplete function to change text of another text box on selecting an option from the suggested options from autocomplete.
Below is my code for the autocomplete function. I do get the results as needed but when I select an option from it, I get the TypeError: ui.item is undefined error.
<script language="javascript">
$(document).ready(function(){
$('#item_code').autocomplete({
source: "http://localhost/test/item/search_item",
minLength: 1,
select: function( event, ui ) {
$( "#item_description" ).val(ui.item.description );
return false;
}
}).data("ui-autocomplete" )._renderItemData = function( ul, item ) {
return $( "<li></li>" )
.data( "item.autocomplete", item )
.append( "<a>" + item.value + " - " + item.description + "</a>" )
.appendTo( ul );
};
});
</script>
I have scoured the net but I have come to a point where I find banging my head on the table.
Any help is greatly appreciated.
You should only need to change the one data property:
.data('item.autocomplete')
was deprecated in favour of
.data('ui-autocomplete-item')
As of jQuery UI 1.9 and removed as of jQuery UI 1.10
http://jqueryui.com/upgrade-guide/1.10/#removed-item-autocomplete-data-use-ui-autocomplete-item
I had a similar problem, but this was because the jQuery documentation now shows the usage for jQuery UI 1.10 and our website is still using jQuery UI 1.8.20.
This is what worked for me in the end.
.data("autocomplete")._renderItem = function (ul, item) {
return $("<li>")
.data("item.autocomplete", item)
.append("<a>" + item.label + "<br><b>" + item.category + "</b></a>").appendTo(ul);
};
turns out I had to change
data("ui-autocomplete" )._renderItemData = function( ul, item ) {
and
.data( "item.autocomplete", item )
to
data("ui-autocomplete" )._renderItem = function( ul, item ) {
and
.data( "item.autocomplete-item", item )
hope this helps anyone who has migration issues with jQuery UI
I have to use two jquery API's, "jquery-1.8.3.js" and "jquery-ui.js" in my code.
But there are already older versions of jquery. And because of this the form is not working properly.
So I search on net for solution and found, we can use
<script>
var jq13 = jQuery.noConflict(true);
</script>
But I have to api's, so I created two variables but still it is not working.
This is my code:-
<script>
(function( $ ) {
$.widget( "ui.combobox", {
_create: function() {
var input,
that = this,
select = this.element.hide(),
selected = select.children( ":selected" ),
value = selected.val() ? selected.text() : "",
wrapper = this.wrapper = $( "<span>" )
.addClass( "ui-combobox" )
.insertAfter( select );
function removeIfInvalid(element) {
var value = $( element ).val(),
matcher = new RegExp( "^" + $.ui.autocomplete.escapeRegex( value ) + "$", "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
$( element )
.val( "" )
.attr( "title", value + " didn't match any item" )
.tooltip( "open" );
select.val( "" );
setTimeout(function() {
input.tooltip( "close" ).attr( "title", "" );
}, 2500 );
input.data( "autocomplete" ).term = "";
return false;
}
}
input = $( "<input>" )
.appendTo( wrapper )
.val( value )
.attr( "title", "" )
.addClass( "ui-combobox-input" )
.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;
that._trigger( "selected", event, {
item: ui.item.option
});
},
change: function( event, ui ) {
if ( !ui.item )
return removeIfInvalid( this );
}
})
.addClass( "ui-widget ui-widget-content ui-corner-left" );
input.data( "autocomplete" )._renderItem = function( ul, item ) {
return $( "<li>" )
.data( "item.autocomplete", item )
.append( "<a>" + item.label + "</a>" )
.appendTo( ul );
};
$( "<a>" )
.attr( "tabIndex", -1 )
//.attr( "title", "Show All Items" )
.tooltip()
.appendTo( wrapper )
.button({
icons: {
primary: "ui-icon-triangle-1-s"
},
text: false
})
.removeClass( "ui-corner-all" )
.addClass( "ui-corner-right ui-combobox-toggle" )
.click(function() {
// close if already visible
if ( input.autocomplete( "widget" ).is( ":visible" ) ) {
input.autocomplete( "close" );
removeIfInvalid( input );
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.wrapper.remove();
this.element.show();
$.Widget.prototype.destroy.call( this );
}
});
})( jQuery );
$(function() {
$( "#driver_uuidHOS" ).combobox();
});
</script>
And I have declared two variables:-
<script src="js/new/jquery-1.8.3.js"></script>
<script>
var jq13 = jQuery.noConflict(true);
</script>
<script src="js/new/jquery-ui.js"></script>
<script>
var jq131 = jQuery.noConflict(true);
</script>
So please tell me where I have to use jq13 and where jq131 in my code. This code is for searchable autosuggest.
Thanks in advance.
After you load the first version, you can assign it to a variable.
var jq13 = jQuery.noConflict(true); // as you did
And then load your second jQuery version. The first one you load can be accessed with jq13(...) while the second one can be accessed with $(...).
No need for assgning variable to second script...
You want to load one version of jQuery, then all the plugins for that version, then turn on no conflict mode. You can repeat this process as many times as you'd like (once for each version of jQuery core that you need to load).
So, for your specific case what you want to do is:
<script src="js/new/jquery-1.8.3.js"></script>
<script src="js/new/jquery-ui.js"></script>
<script src="path/to/your/code.js"></script>
<script>jQuery.noConflict(true);</script>
The path/to/your/code.js refers to the block of code you have above which defines the combobox widget. In terms of supporting multiple jQuery version, it doesn't matter if this is included in-page as your example does, or as an external file as my example does. The anonymous function wrapper that you have (and all plugins should have), which stores the reference to jQuery is what makes this work. At the time those files are executed, jQuery points to the correct version, and the files stores a local reference to it as $. Later, when you can jQuery.noConflict(true), those files continue to hold their references, even though the global jQuery variable has changed. If you follow this pattern of invoking no conflict mode after loading all other files, you don't need to assign jQuery to a new variable, since all of your code will already have the necessary references. The benefit to this approach, is that you never end up with variable-specific names in your wrapper functions, and it's guaranteed to work with all existing plugins that were developed with this model, which is all official jQuery projects and likely any plugin that has thought about no conflict support.
One last thing: At the bottom of your script, you're referring to jQuery as $, but you're outside of the function wrapper that is storing the $ reference. If this is really two separate files in your app, make sure to include the wrapper in each file. If this is actually a single script as shown above, make sure to move the document ready block inside the wrapper.
I'm using the following code to render my jQuery UI autocomplete items as HTML.
The items render correctly in the autocomplete control, but I keep getting this javascript error and can't move past it.
Firefox Could not convert JavaScript argument
Chrome Cannot set property '_renderItem' of undefined
donor.GetFriends(function (response) {
// setup message to friends search autocomplete
all_friends = [];
if (response) {
for (var i = 0; i < response.all.length - 1; i++) {
all_friends.push({
"label":"<img style='padding-top: 5px; width: 46px; height: 46px;' src='/uploads/profile-pictures/" +
response.all[i].image + "'/><br/><strong style='margin-left: 55px; margin-top: -40px; float:left;'>" +
response.all[i].firstname + " " + response.all[i].lastname + "</strong>",
"value":response.all[i].firstname + " " + response.all[i].lastname,
"id":response.all[i].user_id});
}
}
$('#msg-to').autocomplete({
source:all_friends,
select:function (event, ui) {
// set the id of the user to send a message to
mail_message_to_id = ui.item.id;
}
}).data("autocomplete")._renderItem = function (ul, item) {
return $("<li></li>")
.data("item.autocomplete", item)
.append($("<a></a>").html(item.label))
.appendTo(ul);
};
});
Not sure why it is throwing this error, or what I have to do to get past it...Any help is appreciated.
Since I just joined and can't comment on drcforbin's post above, I guess I have to add my own answer.
drcforbin is correct, although it is really a different problem than the one that the OP had. Anyone coming to this thread now is probably facing this issue due to the new version of jQuery UI just released. Certain naming conventions relating to autocomplete were deprecated in jQuery UI in v1.9 and have been completely removed in v1.10 (see http://jqueryui.com/upgrade-guide/1.10/#autocomplete).
What is confusing, however, is that they only mention the transition from the item.autocomplete data tag to ui-autocomplete-item, but the autocomplete data tag has also been renamed to ui-autocomplete. And it's even more confusing because the demos are still using the old syntax (and thus are broken).
The following is what needs to change in the _renderItem function for jQuery UI 1.10.0 in the Custom Data demo here: http://jqueryui.com/autocomplete/#custom-data
Original code:
.data( "autocomplete" )._renderItem = function( ul, item ) {
return $( "<li>" )
.data( "item.autocomplete", item )
.append( "<a>" + item.label + "<br>" + item.desc + "</a>" )
.appendTo( ul );
};
Fixed code:
.data( "ui-autocomplete" )._renderItem = function( ul, item ) {
return $( "<li>" )
.data( "ui-autocomplete-item", item )
.append( "<a>" + item.label + "<br>" + item.desc + "</a>" )
.appendTo( ul );
};
Note the changes for both autocomplete and item.autocomplete. I've verified that this works in my own projects.
I ran into the same problem...seems in later versions, it has to be .data("ui-autocomplete") instead of .data("autocomplete")
I know I'm late with my answer but if people in the future still don't get
.data( "ui-autocomplete-item", item )
to work then try this insted
$(document).ready(function(){
$('#search-id').autocomplete({
source:"search.php",
minLength:1,
create: function () {
$(this).data('ui-autocomplete')._renderItem = function (ul, item) {
return $('<li>')
.append( "<a>" + item.value + ' | ' + item.label + "</a>" )
.appendTo(ul);
};
}
})
});
It worked for me and I was having problem with the login funktion.. I could not login because it said
Uncaught TypeError: Cannot set property '_renderItem' of undefined
Hope this does help someone :)
/kahin
I'm using jquery 1.10.2 and it work using:
.data( "custom-catcomplete" )._renderItem = function( ul, item ) {
return $( "<li>" )
.data( "ui-autocomplete-item", item )
.append( "<a>" + item.label + "<br>" + item.desc + "</a>" )
.appendTo( ul );
};
And now, with jQuery-2.0.0, it's the name of your new module, but replacing the "." (dot) by the "-" (dash) :
jQuery.widget ('custom.catcomplete', jQuery.ui.autocomplete, {
'_renderMenu': function (ul, items) {
// some work here
}
});
$this.catcomplete({
// options
}).data('custom-catcomplete')._renderItem = function (ul, item) {}
Posting for the sake of any person who stumbles across this post.
This error will also manifest itself if you don't put the .autocomplete inside the document ready event.
The code below will fail:
<script type="text/javascript">
$('#msg-to').autocomplete({
source:all_friends,
select:function (event, ui) {
// set the id of the user to send a message to
mail_message_to_id = ui.item.id;
}
}).data("autocomplete")._renderItem = function (ul, item) {
return $("<li></li>")
.data("item.autocomplete", item)
.append($("<a></a>").html(item.label))
.appendTo(ul);
};
</script>
while the code below will work:
<script type="text/javascript">
$(function(){
$('#msg-to').autocomplete({
source:all_friends,
select:function (event, ui) {
// set the id of the user to send a message to
mail_message_to_id = ui.item.id;
}
}).data("autocomplete")._renderItem = function (ul, item) {
return $("<li></li>")
.data("item.autocomplete", item)
.append($("<a></a>").html(item.label))
.appendTo(ul);
};
});
</script>
Depending on the version of jquery ui you're using it will either be "autocomplete" or "ui-autocomplete", I made this update to the combobox plugin to fix the problem (~ln 78-85)
var autoComplete = input.data("ui-autocomplete");
if(typeof(autoComplete) == "undefined")
autoComplete = input.data("autocomplete");
autoComplete._renderItem = function(ul, item) {
...
I run into a problem with jQuery UI - Autocomplete and IE8.
I'm using combobox method which you can find on jQuery UI website - here
Basically, it is creating autocomplete input + select menu from select/option list.
I'm using jQuery 1.6.4 and jQuery UI 1.8.16; both from google server.
It is working perfectly on Chrome / FF / Opera, but does not work on IE8.
On IE8 - once you select something (after typing), or use dropdown button IE will reload the page. Please not that IE will not crash till you use arrows or try to select something.
res://ieframe.dll/acr_error.htm#, in the URL, in front of the actual path
or a message this tab has been reloaded; a problem with the page causes IE to close and reopen the page
Live example here
Any idea what is causing IE to act like that? Any suggestion much appreciated.
jQuery code:
<script>
(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({
text: false
})
.removeClass( "ui-corner-all" )
.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 );
$(document).ready( function() {
$("#combobox").combobox();
});
</script>
I'm still trying to work out why IE8 is crashing but it does work for me when you add a jQueryUI theme to the page, for example:
<link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/themes/cupertino/jquery-ui.css">
Edit: I think I know which line it is crashing on, but I still do not know why! In the jQueryUI code activate: function( event, item ) {
is the following code which adds style and an attribute to the active item.
this.active = item.eq(0)
.children("a")
.addClass("ui-state-hover")
.attr("id", "ui-active-menuitem")
.end();
For some reason, IE8 crashes here, although for me sometimes does not crash when I remove the .addClass and .attr lines.
Edit 2: OK, for some reason IE is crashing with your .ui-autocomplete style. If you change overflow:scroll; to overflow:auto; then IE8 does not crash. Alternatively change max-height to just height, which also fixes it. Guess it's a bug in IE either with max-height (maybe IE8 overflow:auto with max-height) or overflow.
From the first glance this line look strange to me:
if ( this.value && ( !request.term || matcher.test(text) ) )
return {
But its working fine for me in ie8, in ie7 its not working at all.
Try if(){return{...}}.
quick look finds your script tag is missing required type attribute
<script type="text/javascript">
I reproduced the issue, copied the file local with no CSS and no fails.
Odd, IF on the original page, I disable CSS using the IE developer tools, it does not crash.