Reputation: 6203
FYI, I already read the related thread Uncaught TypeError: Cannot read property 'toLowerCase' of undefined and tried to implement the idea. Still, I'm getting the classic
Uncaught TypeError: Cannot read property 'toLowerCase' of undefined
error and I don't know which line in my code it's coming from because the error points within jQuery. My code is
ReadinessColorSetter = (function () {
this.ColorToRange = {
'#f65314': [0, 30],
'#ffbb00': [31, 70],
'#7cbb00': [70, 100]
}
this.SetReadiness = function (ipt) {
// ipt: input element containing
var val = $(this).val(),
newcolor = "#FFF"; // default
for (var hexcode in this.ColorToRange) {
var range = this.ColorToRange[hexcode];
if (val >= range[0] && val < range[1]) {
newcolor = hexcode;
break;
}
}
$(ipt).parent().children().last().css('background-color', newcolor);
}
return this;
})();
// On page load, set the color of the readiness
$(function () {
$('input[class="completeness"]').each(function (el) {
ReadinessColorSetter.SetReadiness(this);
});
});
// When the readiness value is changed, set the color of the readiness
//$('input[class="completeness"]').change(function () {
//ReadinessColorSetter.SetReadiness(this);
//});
$(document).on('change', $('input[class="completeness"]'), function (el) {
ReadinessColorSetter.SetReadiness($(el.target));
});
$('#change-submitted').click(function () {
alert('Change submitter clicked'); // TEST
});
and as you see I've commented out what I thought was the problem and tried to implement the correct fix.
Any guidance on this issue?
Upvotes: 0
Views: 1110
Reputation: 36
Looking at :
// On page load, set the color of the readiness
$(function () {
$('input[class="completeness"]').each(function (el) {
ReadinessColorSetter.SetReadiness(this);
});
});
The $.each() closure has the parameters of [index,elements], you are sending in unwrapped element to your SetReadiness function, you should instead do something like:
(function () {
$('input[class="completeness"]').each(function (index, elem) {
ReadinessColorSetter.SetReadiness(elem);
});
})();
There is also another mistake in your code where you wrap elements within a jQuery element object multiple times, this results in two different types of objects being sent to your SetReadiness function which is a standard element object in one case and a jQuery element object in another case.
Normalise your function input to be either a standard element object or a jQuery element object, doing this you can eliminate cluttered code ie.
this.SetReadiness = function (ipt) {
// ipt: element pre wrapped inside of a jQuery object.
var val = ipt.val(),
newcolor = "#FFF"; // default
for (var hexcode in this.ColorToRange) {
var range = this.ColorToRange[hexcode];
if (val >= range[0] && val < range[1]) {
newcolor = hexcode;
break;
}
}
ipt.parent().children().last().css('background-color', newcolor);
}
Leaving you with a function that takes a pure jQuery element object as a parameter or you could send in a standard element object and then wrap it within a jQuery element object within you SetReadiness function.
Hope this clears up some of the issues you are having, whenever you receive an undefined error always check whether you are wrapping a valid object in $(object).
Standardizing everything like this will clear up your error and will give you clean and readable code. I have not looked at the functionality of your code, and only focused on clearing up your undefined error.
Upvotes: 0
Reputation: 74738
This seems to be invalid:
$(document).on('change', $('input[class="completeness"]'), function (el) {
//-----------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^----it should be a string
As you can see you have passed a jquery object while in the description you should see that it requires a string of css selector like:
$(document).on('change', 'input.completeness', function (el) {
and in the method:
var val = $(ipt).val(),
and the if condition should be:
if (val >= range[0] && val <= range[1]) {
newcolor = hexcode;//--^^----------------should be less than equal instead
break;
}
Upvotes: 5