asp.net ajax property value timestamp is undefined - javascript

I have a problem with the value assignment and retrieval in asp.net ajax. The value of timestamp is undefined
Code:
/// <reference name="MicrosoftAjax.js"/>
Type.registerNamespace("LabelTimeExtender1");
LabelTimeExtender1.ClientBehavior1 = function(element) {
LabelTimeExtender1.ClientBehavior1.initializeBase(this, [element]);
this._testelement=this.get_element();
this._timestamp= this.get_element().attributes['TimeStamp'].value;
alert(_timestamp);
},
LabelTimeExtender1.ClientBehavior1.prototype = {
initialize: function() {
LabelTimeExtender1.ClientBehavior1.callBaseMethod(this, 'initialize');
setInterval (this.timer,1000);
alert("after");
},
dispose: function() {
//Add custom dispose actions here
LabelTimeExtender1.ClientBehavior1.callBaseMethod(this, 'dispose');
},
timer: function(){
alert(this.timestamp);
var splitdate=this._timestamp.split(/[:]+/);
alert(splitdate);
var date= new Date(this._timestamp);
alert( date.toString());
var datenow= new Date ();
alert(datenow.toString());
this._element.innerText=" ";
alert(this._element);
if(date.getUTCFullYear<datenow.getUTCFullYear)
{
alert("year");
var myelement= this.get_element();
myelement .innerHTML= date.getUTCFullYear.toString();
}
if(date.getUTCMonth<datenow.getUTCMonth)
{
alert("month");
this.get_element().innerHTML=date.getUTCMonth.toString();
}
if(date.getUTCDay<datenow.getUTCDay)
{
this.get_element().innerHTML=date.getUTCDay.toString();
}
if(date.getUTCHours <datenow.getUTCHours )
{
this.get_element().innerHTML=date.getUTCHours .toString();
}
if(date.getUTCMinutes<datenow.getUTCMinutes)
{
this.get_element().innerHTML=date.getUTCMinutes.toString();
}
},
set_timestamp: function(value)
{
this._timestamp=value;
},
get_timestamp: function()
{
return this._timestamp;
}
}
LabelTimeExtender1.ClientBehavior1.registerClass('LabelTimeExtender1.ClientBehavior1', Sys.UI.Behavior);
if (typeof(Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();
Why is the value of _timestamp undefined?

I would suggest moving the code which sets this._timestamp into your initialize function.
My other suggestion is to use the getters and setters even within your own code to ensure encapsulation. So, the alerts would actually be alert(this.get_timestamp()). And, in your initialize function, you would call this.set_timestamp(this.get_element().attributes['TimeStamp'].value).
Thanks to the comment I see the problem is actually in the setInterval call. When you call window.setInterval(this.timer, 1000);, when the timer function is called this refers to window, not to your object. So instead, do something like this:
var self = this;
window.setInterval(function () {
self.timer();
}, 1000);
That will make this inside of timer() refer to the correct object.

Related

Intercept a function in javascript

Following is my javaScript code.
var myObjfn = {
before : function(){
console.log("before");
},
loadA: function(){
console.log("loadA");
},
loadB: function(){
console.log("loadB");
},
loadC: function(){
console.log("loadC");
}
}
Whenever I call myObjfn.loadA(), it should call myObjfn.before() method before executing loadA method. Same for loadB() & loadC(). I don't want to explicitly call before() method in all loadA,loadB and loadC methods. Is there any option to achive this in javascript ?
You could do something like this. Which creates a wrapper function for each function in the object except the before function.
var myObjfn = { ... };
Object.keys(myObjfn).forEach(key => {
if (key === "before") return;
var oldFunc = myObjfn[key];
myObjfn[key] = function() {
myObjfn.before();
return oldFunc.apply(this, arguments);
};
});
myObjfn.loadA();
// "before"
// "loadA"

how do I call sibling functions in a singleton class?

In the following code, .refresh could call .add, but I get Uncaught TypeError: undefined is not a function
My guess is because it is not defined at the time class is created, but if this is true, without replicating the code, is there a way to call a sibling public function from the same class?
var fileSelector = (function () {
var self = this;
function callback (data,status,xhr) {
$("#File_Selector_Container").html(data);
utils.setItem ("fileSelector", "TRUE");
}
return {
refresh : function () {
if (utils.getItem ("fileSelector") == "TRUE") {
self.add();
}
},
add : function () {
$.get(script_name ,"AddFileSelector",callback,"html");
},
remove : function () {
$("#File_Selector_Container").html("");
}
}
})();
I started this from: Simplest/Cleanest way to implement singleton in JavaScript? and I can't find it now, but another question where I got self=this from.
this (and hence self) simply refers to the global object (i.e. window). That's why you get the error, there is no global add function. I recommend to read the MDN documentation to learn how this works.
One solution is to keep a reference to the object you are returning and use that instead:
var fileSelector = (function () {
function callback (data,status,xhr) {
$("#File_Selector_Container").html(data);
utils.setItem ("fileSelector", "TRUE");
}
var fileSelector = {
refresh : function () {
if (utils.getItem ("fileSelector") == "TRUE") {
fileSelector.add();
}
},
add : function () {
$.get(script_name ,"AddFileSelector",callback,"html");
},
remove : function () {
$("#File_Selector_Container").html("");
}
};
return fileSelector;
})();

Trouble with setInterval in an object's method

I can't figure out why when I call the reset method of the object, the timer is still null. I simplified version of my object is below, followed by the jQuery that constructs a new object and runs the code. See UPPERCASE comments for my specific question points. Thanks!
var countdownTimer = {
// Default vars
milliseconds: 120000,
interval: 1000,
timer: false,
/* ... stuff ... */
countdown: function () {
var root = this;
var originalTime = root.milliseconds;
/* ... stuff */
// IN MY MIND THIS NEXT LINE SETS THE INSTANCE OF THIS OBJECT'S TIMER PROPERTY TO THE setIterval's ID. BUT DOESN'T SEEM TO BE CORRECT. WHY?
root.timer = setInterval(function () {
if (root.milliseconds < 1) {
clearInterval(root.timer); // THIS LINE SEEMS TO WORK
root.countdownComplete(); // callback function
return false;
}
root.milliseconds = root.milliseconds - root.interval;
/* .... stuff ... */
}, root.interval);
},
start: function (ms) {
if (ms) {
this.milliseconds = ms;
}
if(this.timer) {
clearInterval(this.timer); // NOT SURE IF THIS WORKS OR NOT
}
this.countdown();
},
reset: function (ms) {
var root = this;
if(root.timer) {
clearInterval(root.timer); // THIS DOES NOT WORK
} else {
console.log('timer not exist!!!!'); // ALWAYS END UP HERE. WHY?
}
/* .... stuff ... */
},
countdownComplete: function() { }
};
// Setting up click events to create instances of the countdownTimer
$(function () {
var thisPageCountdown = 4000;
$('[data-countdown]').on('click', '[data-countdown-start], [data-countdown-reset]', function () {
var $this = $(this);
var $wrap = $this.closest('[data-countdown]');
// create instance of countdownTimer
var myCountdown = Object.create(countdownTimer);
if ($this.is('[data-countdown-start]')) {
$this.hide();
$('[data-countdown-reset]', $wrap).css('display', 'block');
myCountdown.$wrap = $wrap;
myCountdown.start(thisPageCountdown);
// myCountdown.countdownComplete = function() {
// alert("Updated Callback!");
// };
}
if ($this.is('[data-countdown-reset')) {
$this.hide();
$('[data-countdown-start]', $wrap).css('display', 'block');
// RESET CALLED HERE BUT DOESN'T WORK RIGHT. SAYS myCountdown.timer IS STILL null. WHY?
myCountdown.reset(thisPageCountdown);
}
});
});
When you use var myCountdown = Object.create(countdownTimer); inside of your click function callback you are scoping it only to that callback and once the callback has executed it is garbage collected. You need to only create one instance of the countdownTimer, and it should be outside of your click event handler.
var thisPageCountdown = 4000;
// create instance of countdownTimer
var myCountdown = Object.create(countdownTimer);
$('[data-countdown]').on('click', '[data-countdown-start], [data-countdown-reset]', function () {
var $this = $(this);
var $wrap = $this.closest('[data-countdown]');
TL;DR You can fix your issue by avoiding use of the keyword this in static methods.
When you use the keyword this in a static javascript method, it refers to the item before the last dot from the call point. Example:
foo.bar(); // inside, this will refer to foo
foo.bar.foobar(); //inside, this will refer to foo.bar
var a = foo.bar.foobar();
a(); //this will refer to either null or window - oops
To prevent this behavior, you should always use the fully qualified name reference in static methods instead of relying on the this keyword.
Example from above:
reset: function (ms) {
//var root = this; // don't do this
if(countdownTimer.timer) {
clearInterval(countdownTimer.timer);
} else {
console.log('timer not exist!!!!');
}
/* .... stuff ... */
}

How do I call a nested JavaScript function properly

I'm trying to set up function a nested function that I can call throughout my script, but I keep getting "error undefined is not a function". Perhaps someone can help me with how to do this correctly.
First I set global my variables:
var trigger = document.getElementById('trigger');
var subject = document.getElementById('subject');
Then I create a show/hide function:
var toggleVis = function() {
function showSomething() {
trigger.classList.add("active");
subject.classList.add("active");
}
function hideSomething() {
trigger.classList.remove("active");;
subject.classList.remove("active");
}
}
Then I set my event listener:
trigger.addEventListener('click', function() {
if ( subject.classList.contains("active") ) {
toggleVis.hideSomething();
}
else {
togglePicker.showPicker();
}
});
The reason I'm trying to do it this way is that there will be other triggers for subject on the page that will need access to the show/hide functions.
You can't access the functions inside the function, they are out of scope, you could attach them as properties to the wrapping function, but it looks like you just need an object
var toggleVis = {
showSomething: function() {
trigger.classList.add("active");
subject.classList.add("active");
},
hideSomething: function() {
trigger.classList.remove("active");;
subject.classList.remove("active");
}
}
Your togleVis variable is a function and not an object so you can't do toggleVis.hideSomething(). Try updating your code to :
var toggleVis = (function() {
return {
showSomething : function () {
trigger.classList.add("active");
subject.classList.add("active");
},
hideSomething : function () {
trigger.classList.remove("active");;
subject.classList.remove("active");
}
};
}());
With this toggleVis is now an object with two properties showSomething and hideSomething functions.

Javascript prototypal inheritance prototype function call

Have a question about calling one prototype function in another prototype function.
for instance lets say I have a basic slider with two prototype functions.
function Slider() {
}
Slider.prototype.transition = function() {
}
Slider.prototype.setTargets = function() {
}
What is the proper way of calling the setTargets function inside of the transition function so something like this:
Slider.prototype.transition = function() {
this.target.fadeOut('normal', function() {
// call setTargets?
this.setTargets(); // errors when i do this
});
}
thanks for the help
If this.target is an jQuery Object the callback of fadeOut will be called with this as the DOMNode.
Do this instead:
Slider.prototype.transition = function() {
var me = this;
this.target.fadeOut('normal', function() {
me.setTargets(); // <-- See me
});
}
I have chosen the name that me for all my initialized references to this. I never used that me for DomNodes, etc. makes sence for me.
Please see comments for furture views on this point.
EDIT:
Acually i used me not that - Dont know what im thinking ?? !
And for comment:
Slider.prototype.transition = function() {
var me = this;
this.target.fadeOut('normal', function() {
var domThis = this;
me.setTargets(); // <-- See me
setTimeout(function() {
// Use domThis [Dom Node]
}, 123);
});
}
Or:
You can make a jQuery object of this:
var $this = $(this);
me.setTargets(); // <-- See me
setTimeout(function() {
// Use $this [jQuery Object]
}, 123);
If you need the jQuery Object of this you can refer to: me.target
me.setTargets(); // <-- See me
setTimeout(function() {
// Use me.target [jQuery Object]
}, 123);
The fadeOut function is not called in the context of your slider object.
Slider.prototype.transition = function() {
var slider = this;
this.target.fadeOut('normal', function() {
// call setTargets?
slider.setTargets(); // should work now.
});
}

Categories

Resources