Can I use data attribute for the source of my autocomplete?
for example
HTML
<input type="text" class="autocomplete" data-source="/search.php" />
Javascript
$(".autocomplete").autocomplete({
source : $(this).data('source'),
minLength:1,
select: function( event, ui ) {
console.log( ui.item ?
"Selected: " + ui.item.value + " aka " + ui.item.id :
"Nothing selected, input was " + this.value );
}
});
I tried it but it always gives me an error.
What's wrong with my code?
Uncaught TypeError: Property 'source' of object #<Object> is not a function
In source you can use this.element which refers to the input
$(".autocomplete").autocomplete({
source : this.element.attr('data-source'),
minLength:1,
select: function( event, ui ) {
console.log( ui.item ?
"Selected: " + ui.item.value + " aka " + ui.item.id :
"Nothing selected, input was " + this.value );
}
});
here's the fix
$('.autocomplete').keypress(function(){
$(this).autocomplete({
source: $(this).data('source'),
minLength: 1,
select: function(event, ui) {
console.log(ui.item ? "Selected: " + ui.item.value + " aka " + ui.item.id : "Nothing selected, input was " + this.value);
}
});
});
I added a keypress function so that it will get the current element.
The this pointer does not refer to the .autocomplete element -- this only equals the selected element inside callbacks executed by jquery. It looks like you want to do something like this:
$(".autocomplete")
.autocomplete({
minLength:1,
select: function( event, ui ) {
console.log( ui.item ?
"Selected: " + ui.item.value + " aka " + ui.item.id :
"Nothing selected, input was " + this.value );
}
})
.each(function() { // Goes through `.autocomplete` elements and sets source
$(this).autocomplete("option", "source", $(this).data('source'));
})
;
every keystroke of autocomplete will trigger a remote request if the source is a url. what you can do to prevent that is to "pre-fetch" the data (make sure to return a JSON-valid array), then add the return data as the source for the autocomplete. that way, data is only fetched once, and autocomplete will reference to that data.
jQuery autocomplete already has a filtering capability. you just need a full list of items and it will filter it for you.
//get all input boxes with class "autocomplete"
$('.autocomplete').each(function(){
//reference input and get it's url
var input = $(this);
var url = input.data('source');
//get list array only ONCE for each input using their specified urls
$.get(url, function(data) {
//when request is received, add autocomplete using the returned data
input.autocomplete({
source: data,
minLength: 1,
select: function(event, ui) {
console.log(ui.item ? "Selected: " + ui.item.value + " aka " + ui.item.id : "Nothing selected, input was " + this.value);
}
});
});
});
Related
This question already has answers here:
jQuery UI autocomplete: enforce selection from list without modifications
(2 answers)
JQuery autocomplete: how to force selection from list (keyboard)
(4 answers)
jQuery UI AutoComplete: Only allow selected valued from suggested list
(9 answers)
Closed 5 years ago.
I have used Jquery Autocomplete to build a search dropdown using the code below.
Right now, if user enters - test and if autocomplete shows
test 123
test 456
test 789
and if user selects "test 123", it redirects to domain.com/test-123 which is good.
But if user just press enter after typing "test" without selecting valid result, it redirects to domain.com/>?s=test. I want to prevent that from happening.
So, even if user press enter after typing "test", user should not be redirected to another URL.
How can I block redirect if user enters a string which is not output of autocomplete?
(function( $ ) {
$(function() {
// Custom autocomplete instance.
$.widget( "app.autocomplete", $.ui.autocomplete, {
// Which class get's applied to matched text in the menu items.
options: {
highlightClass: "ui-state-highlight"
},
_renderItem: function( ul, item ) {
// Replace the matched text with a custom span. This
// span uses the class found in the "highlightClass" option.
var re = new RegExp( "(" + this.term + ")", "gi" ),
cls = this.options.highlightClass,
template = "<span class='" + cls + "'>$1</span>",
label = item.label.replace( re, template ),
$li = $( "<li/>" ).appendTo( ul );
// Create and return the custom menu item content.
$( "<a/>" ).attr( "href", "#" )
.html( label )
.appendTo( $li );
return $li;
}
});
var autocompleteTextbox = '<div class="autocomplete-search autocomplete-search-open">'
+'<i class="search-icon" aria-hidden="true"></i>'
+'<div class="autocomplete-search-sub1">'
+'<form role="search" method="get" action="<?php echo esc_url( home_url( '+"/"+' ) ); ?>">'
+'<input type="text" name="s" class="form01 autocomplete-search-input" id="autocomplete-search-input" placeholder="Type something" autocomplete="off">'
+'<i class="searchx-icon" aria-hidden="true"></i>'
+'</form>'
+'</div>'
+'</div>';
var appendElement = function(){
$('.st-navbar-collapse').append(autocompleteTextbox);
$(this).unbind('click');
$(".st-search .st-btn01 .search-icon").addClass('text-visibility');
};
$(".two-brokers").parent('a').on('click',appendElement);
var removeElement = function(){
$(this).parents('.autocomplete-search').remove();
$(".two-brokers").parent('a').bind('click',appendElement);
$(".st-search .st-btn01 .search-icon").removeClass('text-visibility');
};
$("body").on("click",".st-btn02.autocomplete-search-icon",removeElement);
var searchRequest,timeoutRequest;
$("body").on("keyup",".autocomplete-search-input",function(){
clearTimeout(timeoutRequest);
var _this = $(this);
timeoutRequest = setTimeout(function(){
// create an jq-ui autocomplete on your selected element
_this.autocomplete({
minChars: 2,
highlightClass: "bold-text",
// use a function for its source, which will return ajax response
source: function(request, response){
try { searchRequest.abort(); } catch(e){}
// well use postautocomplete_search.ajax_url which we enqueued with WP
$.post(postautocomplete_search, {
action: 'get_test_pages', // our action is called search
term: request.term // and we get the term form jq-ui
}, function(data) {
if(!data.length){
var result = [{
label: 'No matches found',
value: response.term
}];
response(result);
}else{
response(data);
}
}, 'json');
},
select: function( evt, ui ) {
evt.preventDefault();
window.location = ui.item.link;
}
});
},100);
});
});
})( jQuery );
I wrote this code in jQuery, it's working perfectly, but I need the index value to begin at 1.
How can I do this? This is my code:
$( "span.text" ).each(function( index ) {
console.log( index + ": " + $( this ).attr('name') );
var micaracter= $(this).attr('name');
$( "span.lista a#caracter_" + index).append(micaracter);
});
Then just do the native programming method, add one with the zero based index,
$( "span.lista a#caracter_" + (index + 1)).append(micaracter);
I have the following field inside my asp.net mvc web application:-
<input class="push-up-button searchmargin" placeholder="Search by tag.." name="searchTerm2" data-autocomplete-source= "#Url.Action("AutoComplete", "Home")" type="text" style="margin-top:8px"/>
and i wrote the following autocomplete function:-
$("input[data-autocomplete-source]").each(function () {
var target = $(this);
target.autocomplete({
source: target.attr("data-autocomplete-source"), minLength: 1, delay: 1000,
create: function () {
$(this).data("autocomplete")._renderItem = function (ul, item) {
return $('<li>').append('<a>' + item.label + '<br>' + item.resourcename + ' | ' + item.customername + ' | ' +item.sitename + '<hr>' +'</a>')
.appendTo(ul);
};
}
});
});
Currently the auto complete is working well (the result list will be displayed), but the problem is that if i select an item from the auto complete result it will not be rendered inside the auto complete field.and when i check the firebug i noted the following error , when selecting an auto complete item:-
TypeError: item is undefined
[Break On This Error]
self.element.val( item.value );
For example if i start typing the following words "i am" , then i select "I am writing" from the autocomplete list result , then the autocomplete field will have the "I am" text instead of the select "I am writing". Can any one advice , what is causing this problem?
Thanks
EDIT
i edited my autocomplete as follow, by adding focus & select :-
$("input[data-autocomplete-source]").each(function () {
var target = $(this);
target.autocomplete({
source: target.attr("data-autocomplete-source"), minLength: 1, delay: 1000,
focus: function (event, ui) {
$("input[data-autocomplete-source]").val(ui.item.label);
return false;
},
select: function (event, ui) {
$("input[data-autocomplete-source]").val(ui.item.label);
return false;
},
create: function () {
$(this).data("autocomplete")._renderItem = function (ul, item) {
return $('<li>').append('<a>' + '<b>'+item.label + '</b><br>' + '<span style="color:#8e8e8e ">' + item.resourcename + ' | ' + item.customername + ' | ' + item.sitename + '<hr style="padding: 0px; margin: 0px;">' + '</span></a>')
.appendTo(ul);
};
}
});
});
but i wil get the following error when i am trying to select an autocomplete item:-
TypeError: ui.item is undefined
Please add "Select" event and try below
$( "input[data-autocomplete-source]" ).autocomplete({
select: function( event, ui ) {
$( "input[data-autocomplete-source]" ).val( ui.item.yourValueProperties);
return false;
}
});
***Note : yourValueProperties= like customername ***
http://jsbin.com/renabuvu/1/edit
What I'm doing is I type a css selector, change it's values and as it's values change it applies to the page's html and is applied in real time. (this part works without a problem)
However my problem is when I append the already added values. My newly appended/cloned textarea ends up blank.
I have no idea why this is, nor how to solve this problem.
If anyone can help shed some light on this it'd be greatly appreciated.
$(document).ready(function() {
$(".addvalz").on('click', function() {
// Refresh render before add
$("#testcode").val($(".inputval").val() +" {"+ ( $(".pad").val() === "" ? "" : "\n padding: " + $(".pad").val() + ";" ) + ( $(".bg").val() === "" ? "" : "\n background-color: " + $(".bg").val() + ";" ) + ( $(".boxshadow").val() === "" ? "" : "\n box-shadow: " + $(".boxshadow").val() + ";" ) +"\n}");
// Adds value
$(".val-nester").append($("<div class='holddezvalz'>")
.append("<button class='deldizval'>x</button>")
.append("<button class='grabdezvalz'>"+ $(".inputval").val() +"</button>").append($("#asc #testcode:first-of-type").clone()).append($(".valz2add .inputval:first-of-type").clone()).append($(".cssvalz .pad:first-of-type").clone()).append($(".cssvalz .bg:first-of-type").clone()).append($(".cssvalz .boxshadow:first-of-type").clone())
);
$("#apply-test-code").html("<style type='text/css'>"+ $("#testcode").val() +"</style>");
// Grabs selector value
$(".grabdezvalz").on('click', function() {
$(".valz2add .inputval:first-of-type").val($(this).next().next().val());
$(".cssvalz .pad:first-of-type").val($(this).next().next().next().val());
$(".cssvalz .bg:first-of-type").val($(this).next().next().next().next().val());
$(".cssvalz .boxshadow:first-of-type").val($(this).next().next().next().next().next().val());
});
});
});
http://jsbin.com/renabuvu/2/edit
Because the values are being mirrored to the textarea and not applied, clone will only apply the textarea to it's set values not what's being mirrored/reflected upon it.
I had to add it as a string and then it worked perfectly.
$(".val-nester").append($("<div class='holddezvalz'>")
.append("<button class='deldizval'>x</button>")
.append("<button class='grabdezvalz'>"+ $(".inputval").val() +"</button>")
.append("<textarea>"+ $("#asc #testcode:first-of-type").val() +"</textarea>")
.append($(".valz2add .inputval:first-of-type").clone())
.append($(".cssvalz .pad:first-of-type").clone())
.append($(".cssvalz .bg:first-of-type").clone())
.append($(".cssvalz .boxshadow:first-of-type").clone())
);
I'm stumped with this one, I've been at it hours, trying to get jQuery autocomplete to go to another page on the site when an item is clicked in the suggestions list.
Anyone know how to do this? Here is my code :
$(':input[data-autocomplete]').autocomplete({
source: $(':input[data-autocomplete]').attr("data-autocomplete"),
delay: 0,
select: function (event, item) {
//window.location.replace("http://www.example.com/Profile/Details/1");// Works but totally unacceptable, browser history lost etc..
//alert("Item Clicked"); //Fires Ok
}
}).data("autocomplete")._renderItem = function (ul, item) {
var MyHtml = '<a id="ItemUrl" href="/Profile/Details/' + item.PartyId + '"' + ">" +
"<div class='ac' >" +
"<div class='ac_img_wrap' >" +
'<img src="../../uploads/' + item.imageUrl + '.jpg"' + 'width="40" height="40" />' +
"</div>" +
"<div class='ac_mid' >" +
"<div class='ac_name' >" + item.value + "</div>" +
"<div class='ac_info' >" + item.info + " PartyId :" + item.PartyId + "</div>" +
"</div>" +
"</div>" +
"</a>";
return $("<li></li>").data("item.autocomplete", item).append(MyHtml).appendTo(ul);
};
As you can see I have used custom HTML in the _renderItem event, my custom HTML creates an anchor tag with the id passed in from the source, this looks ok, the link is formed correctly in the browser bottom left corner (I'm using Chrome)
<a href='/Profile/Details/id' >some other divs & stuff</a>
The problem is that when I click the link nothing happens, I have tried using the select event but item is null so can't get item.PartyId to force a manual jump.
How can I get the click event working?
It might late to answer it, but I have done this with the following code:
$(document).ready(function() {
$('#txtSearch').autocomplete({
minLength: 3,
source: "handlers/SearchAutoComplete.ashx?loc=" + $('#hfLocation').val(),
select: function(event, ui) {
doSearch(ui.item.label, ui.item.city);
}
});
});
function doSearch(term, location) {
window.location.href = 'Search.aspx?q=' + term + '&loc=' + location;
}
After a few days of head banging (not moshing kind) I've come up with the following:
$(':input[data-autocomplete]').autocomplete({
source: $(':input[data-autocomplete]').attr("data-autocomplete"),
delay: 0,
select: function (event, ui) {
var q = ui.item.PartyId;
if (q != "") {
$('#hidPID').val(q);
$('#ac_submit').trigger('click');
}
}).data("autocomplete")._renderItem // -->>> the rest of the code same as above
The issue was (event, item) should have been (event, ui) and to get the value of the item you use ui.item.PartyId (in my case PartyId is declared in the source : above)
So on my original form I had two html inputs 1-hidden ID, 2-Submit & as you can see in the select : function above I set the ID & trigger the submit (so now the user just picks an item and off they go to the controller which performs the RedirectToView & NOT this code as it doesn't seem correct to use location in this instance)
I Hope this saves someone some time as the jQuery autocomplete docs dont make it too clear.