arcy arcy - 1 month ago 4
Javascript Question

jQuery error "cannot read property 'call' of undefined"

I'm a Java programmer trying to write a little javaScript. Bear with me.

I would like a function that updates a total when a digit is entered in any one of the input fields in a table. I have the following line in

$(document).ready(function() { ... }


$("#lineCountTable").find('input').each().bind('keyup', function() {
updateTotal(this);
});


In Chrome's debug screen, I get:


Uncaught TypeError: cannot read property 'call' of undefined". The line number pointed to is jQuery-1.8.2.js:611.


I figure I have a syntax error in defining the function to be called. The
updateTotal(inputVar)
function is duly defined later in the JS file; in case someone's interested, it is:

function updateTotal(inputVar) {
var row = inputVar.closest('tr');
var lineCharge = row.find("dlsRowCharge").html().trim();
var total = 0.0
var lineCount = inputVar.val();
if (isNumeric(lineCount)) {
total = math.abs(lineCount * lineCharge).toFixed(2);
row.children(".dlsRowTotal").html("$ " + total);
}
}


I know these functions are usually put inline; I would rather define them separately and call them, unless that's impossible.

Answer

You have a few issues here:

  • each() requires a handler function and is the cause of your error. That said, it's not needed in this instance.
  • you should use on() over bind() since jQuery 1.7.
  • this will be a DOM Element which you cannot call jQuery's closest() method on. Admittedly there is a native closest() method, but it's not well supported yet. For the code to work reliably you need to wrap this in a jQuery object.
  • find() requires a valid selector, which dlsRowCharge is not. Presumably this should be .dlsRowCharge
  • math should be Math

With all that said, try this:

$("#lineCountTable").find('input').on('keyup', function() { 
    updateTotal($(this)); 
});

function updateTotal($inputVar) {
    var $row = $inputVar.closest('tr');
    var lineCharge = $row.find("dlsRowCharge").html().trim();
    var lineCount = parseFloat($inputVar.val()) || 0;
    var total = Math.abs(lineCount * lineCharge).toFixed(2);
    $row.children('.dlsRowTotal').html('$ ' + total);
}