Reputation: 10390
I made a simple autocomplete feature as follows:
$(document).ready(function(){
$('#search-field').keyup(function(e) {
ajaxAutocomplete(e);
});
});
function ajaxAutocomplete(e) {
var hash_tag = $.trim($(this).val());
$.ajax({
url : 'autocomplete.php',
method : 'GET',
dataType: 'html',
data : {tag : hash_tag}
})
.done(function(response) {
if (response) {
$('.datalistPlaceholder').html(response).show();
} else {
$('.datalistPlaceholder').hide();
}
})
.fail(function() {
alert('Something went wrong');
});
}
I am trying to use the event object in ajaxAutocomplete
function as described by jQuery: https://learn.jquery.com/about-jquery/how-jquery-works/
The above set up does not work and returns this: jquery.js:7328 Uncaught TypeError: Cannot read property 'toLowerCase' of undefined
This does work after removing the callback from above:
$(document).ready(function(){
$('#search-field').keyup(ajaxAutocomplete);
});
function ajaxAutocomplete() {
var hash_tag = $.trim($(this).val());
$.ajax({
url : 'autocomplete.php',
method : 'GET',
dataType: 'html',
data : {tag : hash_tag}
})
.done(function(response) {
if (response) {
$('.datalistPlaceholder').html(response).show();
} else {
$('.datalistPlaceholder').hide();
}
})
.fail(function() {
alert('Something went wrong');
});
}
Upvotes: 0
Views: 85
Reputation: 337626
The problem with your first example is because you wrap the call to ajaxAutocomplete()
in an anonymous function which means that you lose the reference of this
within your called function (it will point to the window
instead of the #search-field
element). This in turn means that $(this).val()
returns nothing - hence the error coming from jQuery.
You need to either use .call(this)
when calling your function to maintain the scope of this
within the function:
$(document).ready(function(){
$('#search-field').keyup(function(e) {
ajaxAutocomplete.call(this);
});
});
Alternatively you can use your second method which passes the ajaxAutocomplete
function reference to the event handler which then maintains scope:
$(document).ready(function(){
$('#search-field').keyup(ajaxAutocomplete);
});
Personally I prefer the latter approach for its brevity.
Upvotes: 0
Reputation: 10390
After combining Rory's answer above and reading about .call() from MDN I came up with the following that works:
$(document).ready(function(){
$('#search-field').keyup(function(e) {
ajaxAutocomplete.call(this, e);
});
});
function ajaxAutocomplete(e) {
console.log(e)
var hash_tag = $.trim($(this).val());
$.ajax({
url : 'autocomplete.php',
method : 'GET',
dataType: 'html',
data : {tag : hash_tag}
})
.done(function(response) {
if (response) {
$('.datalistPlaceholder').html(response).show();
} else {
$('.datalistPlaceholder').hide();
}
})
.fail(function() {
alert('Something went wrong');
});
}
Result on typing 'a':
j…y.Event {originalEvent: KeyboardEvent, type: "keyup", timeStamp: 1292.2500000000002, jQuery21406902543265129839: true, keyCode: 65…}
Upvotes: 1
Reputation: 3362
When calling a function, the context this
gets lost. If you use the callback directly, the context is available.
Upvotes: 0