Robert Rocha Robert Rocha - 7 months ago 20
Javascript Question

jQuery Cannot read property 'toLowerCase' of undefined

I am reading a chapter from PHP Ajax Cookbook. Here is the code:

HTML:

<form class='simpleValidation'>
<div class='fieldRow'>
<label for='title'>Title *</label>
<input type='text' id='title' name='title' class='required'>
</div>
<div class='fieldRow'>
<label for='url'>URL</label>
<input type='text' id='url' name='url' value='http://'>
</div>
<div class='fieldRow'>
<label for='labels'>Labels</label>
<input type='text' id='labels' name='labels'>
</div>
<div class='fieldRow'>
<label for='textarea'>Text *</label>
<textarea id='textarea' class='required'></textarea>
</div>
<div class='fieldRow'>
<input type='submit' id='formSubmitter' value='Submit'>
</div>
</form>


jQuery:

$(document).ready(function() {
var timerId = 0;

$('.required').keyup(function() {
clearTimeout(timerId);

timerId = setTimeout(function() {
ajaxValidation($(this));
}, 200);
});
});

var ajaxValidation = function (object) {
var $this = $(object);
var param = $this.attr('name');
var value = $this.val();

$.get(
'inputValidation.php',
{'param' : param, 'value' : value },
function (data) {
if (data.status == 'OK') {
validateRequiredInputs();
} else {
$this.addClass('failed');
}
},
'json'
);

var validateRequiredInputs = function() {
var numberOfMissingInputs = 0;

$('.required').each(function(i) {
var $item = $(this);
var itemValue = $item.val();

if (itemValue.length) {
$item.removeClass('failed');
} else {
$item.addClass('failed');
numberOfMissingInputs++;
}
});

var $submitButton = $('#formSubmitter');

if (numberOfMissingInputs > 0) {
$submitButton.prop('disabled', true)
} else {
$submitButton.prop('disabled', false)
}
}
}


PHP (inputValidation.php):

<?php
$result = array();

if (isset($_GET['param'])) {
$result['status'] = 'OK';
$result['message'] = 'Input is valid!';
} else {
$result['status'] = 'ERROR';
$result['message'] = 'Input IS NOT valid';
}

echo json_encode($result)
?>


When I start typing in the
Title *
field I get the following error from the console:
Uncaught TypeError: Cannot read property 'toLowerCase' of undefined


Note: I am using jQuery 2.2.1

So far I have checked the code for mis-spelling but cannot find any.

Answer

The this bit in ajaxValidation($(this)) isn't what you think it is: it's actually window, since it's being called by setTimeout().

One solution is to assign $(this) to a variable outside the function, like so:

$('.required').keyup(function() {
    clearTimeout(timerId);
    var $this = $(this);

    timerId = setTimeout(function() {
        ajaxValidation($this);
    }, 200);
});