I want to set values for objects after the DOM has loaded pletely. Problem is, I'm getting a null pointer exception after calling a OnBlur
and OnFocus
event from a textbox. What am I doing wrong?
javascript:
$(document).ready(function () {
var sumThursdayHrs = $('span[id*="lblThursdayHrs"]').last()
});
var tempThursdayHrs = 0.0;
function BlurThursdayHrs(sender, args) { sumThursdayHrs.text(tempThursdayHrs + sender.get_value()); }
function FocusThursdayHrs(sender, args) { tempThursdayHrs = sumThursdayHrs.text() - sender.get_value(); }
markup:
<telerik:RadNumericTextBox ID="txtThursdayHrs" runat="server" NumberFormat-DecimalDigits="1"
Width="25px" MinValue="0" Type="Number" DbValue='<%# Eval("ThursdayHrs") %>'>
<ClientEvents OnBlur="BlurThursdayHrs" OnFocus="FocusThursdayHrs" />
</telerik:RadNumericTextBox>
error:
Microsoft JScript runtime error: 'sumThursdayHrs' is undefined
I want to set values for objects after the DOM has loaded pletely. Problem is, I'm getting a null pointer exception after calling a OnBlur
and OnFocus
event from a textbox. What am I doing wrong?
javascript:
$(document).ready(function () {
var sumThursdayHrs = $('span[id*="lblThursdayHrs"]').last()
});
var tempThursdayHrs = 0.0;
function BlurThursdayHrs(sender, args) { sumThursdayHrs.text(tempThursdayHrs + sender.get_value()); }
function FocusThursdayHrs(sender, args) { tempThursdayHrs = sumThursdayHrs.text() - sender.get_value(); }
markup:
<telerik:RadNumericTextBox ID="txtThursdayHrs" runat="server" NumberFormat-DecimalDigits="1"
Width="25px" MinValue="0" Type="Number" DbValue='<%# Eval("ThursdayHrs") %>'>
<ClientEvents OnBlur="BlurThursdayHrs" OnFocus="FocusThursdayHrs" />
</telerik:RadNumericTextBox>
error:
Share Improve this question edited Apr 17, 2012 at 21:06 Jean-François Beaulieu asked Apr 17, 2012 at 21:01 Jean-François BeaulieuJean-François Beaulieu 4,45522 gold badges77 silver badges113 bronze badges 3Microsoft JScript runtime error: 'sumThursdayHrs' is undefined
- Are you sure that $('span[id*="lblThursdayHrs"]') is selecting anything? – Andrey Commented Apr 17, 2012 at 21:06
- @Andrey, yes I tested in google chrome's console – Jean-François Beaulieu Commented Apr 17, 2012 at 21:10
- @Engineer, both are client-side... the two methods are events defined in the markup, they are used in Telerik's UI framework for ASP.NET AJAX – Jean-François Beaulieu Commented Apr 17, 2012 at 21:11
4 Answers
Reset to default 3As you said in the heading, the values are set in a function (the ready-event-handler function). But JavaScript has function scope, and as you declared sumThursdayHrs
to be a local (not to say "private") variable by using the var
keyword, it is undefined from outside. Two possibilites:
- Make sumThursdayHrs a global variable (remove "var") (and eventually declare it outside). Note that global variables should be avoided where possible to preclude naming conflicts and co
- or take all functions using it into the same scope. Watch out, then these function will also be no more globally available so you need to set the blur/focus handlers in the same context (as Patrick Scott suggested).
if you are using jquery already why not bind the events with jquery?
$('span[id$="txtThursdayHrs"]:first').on("focus", FocusThursdayHrs)
.on("blur", BlurThursdayHrs);
Also, declare those function inside the doc ready function, so they can access sumThursdayHrs
, or use anonymous functions in the same place instead of calling the functions
Ex:
$(document).ready(function () {
var sumThursdayHrs = $('span[id*="lblThursdayHrs"]').last();
var tempThursdayHrs = 0.0;
$('span[id$="txtThursdayHrs"]:first').on("focus", function() {
sumThursdayHrs.text(tempThursdayHrs + $(this).val());
})
.on("blur", function() {
tempThursdayHrs = sumThursdayHrs.text() - $(this).val();
});
});
Or move sumThursdayHrs
to a global object... For sanity's sake, I remend not putting it in window though.
Instead define a global namespace to hold your app specific global variables. This is called global abatement.
Ex.
var MyApp = {};
$(document).ready(function () {
MyApp.sumThursdayHrs = $('span[id*="lblThursdayHrs"]').last();
//...
--
MyApp.tempThursdayHrs = 0.0;
function BlurThursdayHrs(sender, args) { MyApp.sumThursdayHrs.text(MyApp.tempThursdayHrs + sender.get_value()); }
function FocusThursdayHrs(sender, args) { MyApp.tempThursdayHrs = MyApp.sumThursdayHrs.text() - sender.get_value(); }
The error is due to scoping:
$(document).ready(function () {
// sumThursdayHrs is a *local* variable to the function
var sumThursdayHrs = $('span[id*="lblThursdayHrs"]').last()
});
// ... so this will fail because it is trying to use
// window.sumThursdayHrs (the property sumThursdayHrs on the window object),
// which is not set and thus the Reference Error
function BlurThursdayHrs(sender, args) {
sumThursdayHrs.text(tempThursdayHrs + sender.get_value());
}
The "simple fix" (which may or may not be valid) is:
$(document).ready(function () {
// Set the "global variable" sumThursdayHrs
// "window." isn't technically required, but it is to show a point.
window.sumThursdayHrs = $('span[id*="lblThursdayHrs"]').last()
});
Happy coding.
I'm not sure if that code example you gave are in the same bag or not but if you've defined a variable inside the $(document).ready()
, know that the variable is inside a closure. Outside of it, it'll be undefined.
So why not do this:
$(document).ready(function () {
var sumThursdayHrs = $('span[id*="lblThursdayHrs"]').last();
var tempThursdayHrs = 0.0;
function BlurThursdayHrs(sender, args) {
sumThursdayHrs.text(tempThursdayHrs + sender.get_value());
}
function FocusThursdayHrs(sender, args) {
tempThursdayHrs = sumThursdayHrs.text() - sender.get_value();
}
});
In the above code, it should pick up the value you intended because everything is inside the $(document).ready()
closure. And in addition, you've assigned a jquery object, $('span[id*="lblThursdayHrs"]')
, into a variable, so it must be used inside the jquery environment not outside... In 1 word, if you're using jquery then keep it in jquery environment.
What you did is, you've signed a contract with jquery that you'll be using all its methods and properties by doing var sumThursdayHrs = $('span[id*="lblThursdayHrs"]').last()
. Once you use $(something)
, that's it, it must be used inside the jquery environment.