Zanderwar Zanderwar - 6 months ago 11
Javascript Question

Binding dynamic elements to a function; left with only one bind

My config (as an example) is setup like so:

this.config = [
{
element: '#Amount',
type: "money",
notNull: true,
error: "You must specify an amount"
},
{
element: '#Type',
type: "string",
notNull: true,
error: "You must specify whether you want a 6 week loan or a 12 month loan"
}
]


I have a bind function that should bind a validation function to each element in the list:

this.bind = function () {
for (var i = 0; i < _this.config.length; i++) {
var arr = _this.config[i];
console.log('Binding ' + arr.element + ' to single input validation')
// bind single validation to each element
$(document).on('keyup', arr.element, function () {
_this.validate(arr.element)
})
}
}


And in the console I am presented with:

Binding #Amount to single input validation
Binding #Type to single input validation
Binding #LoanPurpose to single input validation


The config actually consists of 47 elements, however I am certain that only the last bind remains after iterating through the config so it's as if it's replacing the previous bind each time.

Any pointers would be greatly appreciated

Thanks

Answer

This is a classic javascript error. Your nested keyup handler function references a variable arr, which is getting overwritten by the for loop every iteration. So when the keyup handler finally does execute, it's using the arr that is referencing the last element in this.config array.

This link explains why it's bad to make functions within loops. And provides a solution for it.

Here's how your code should probably look:

this.bind = function () {
    for (var i = 0; i < _this.config.length; i++) {
        var arr = _this.config[i];
        console.log('Binding ' + arr.element + ' to single input validation')
        // bind single validation to each element
        _this.makeBind(arr.element)
    }
}

this.makeBind = function (el) {
    $(document).on('blur', el, function () {
        _this.validate(el)
    })
}