Calendar onChange fired on selector click?

Hi there, I’m using calendar 3.0 and I found something weird with the onChange event. It seems to be fired on the click of the selector. Here’s the example code I use:

<input type="text" id="txtCalendrier" />

<script type="text/javascript">
//var dateCourante = new Date();
if (typeof(dhtmlXCalendarObject) !== 'undefined')
{
	dhtmlXCalendarObject.prototype.langData["fr"] = {
		dateformat: '%Y.%m.%d',
			monthesFNames: ["Janvier","Février","Mars","Avril","Mai","Juin","Juillet","Août","Septembre","Octobre","Novembre","Décembre"],
			monthesSNames: ["Jan","Fév","Mars","Avr","Mai","Juin","Juil","Août","Sept","Oct","Nov","Déc"],
			daysFNames: ["Dimanche","Lundi","Mardi","Mercredi","Jeudi","Vendredi","Samedi"],
			daysSNames: ["Di","Lu","Ma","Me","Je","Ve","Sa"],
			weekstart: 7 // Chiffre de 1(Lundi) à 7(Dimanche)
	}
}

calendrier = new dhtmlXCalendarObject('txtCalendrier');

calendrier.loadUserLanguage("fr");
calendrier.setSkin('dhx_skyblue');
calendrier.hideTime();

calendrier.attachEvent("onChange", function(date, state)
{												 
	alert("A change was made"); 
});

</script>

As the documentation explains, the “onChange” event should be fired when the year, month or day in the selector changes, which is indeed the case, as should be expected. What isn’t however is that the “onChange” is also fired when I click on the selector to make the calendar appear. I mean, I haven’t even changed anything, I just clicked and the event triggered. Is this behavior intentional?

If you could help me with this, I’d be grateful.

Thanks in advance,

Osu

Also, I should mention that the “state” parameter is always true and that the “onChange” event is not triggered if I select a different date on the calendar itself (though after reading a bit on the forum, I gathered that this latter behavior seemed to be intentional).

Anyway, thanks again,

Osu

Okay, a bit of snooping around in the calendar’s code led me to the “_updateDateStr” method. The problem was that this method was calling the “_doOnSelectorChange” without checking whether an actual change was made. So I’ve made the following correction:

this._updateDateStr = function(str) {
		
		// check if valid str
		if (str == "") {
			this.setDate(new Date());
			this.callEvent("onChange",[null,true]);
			return;
		} else {
			if (!this._dateFormatRE || !str.match(this._dateFormatRE)) return;
		}
		
		var r = this._strToDate(str, true);
		var hasChanged = false;
		var newDate = new Date(this._activeMonth.getFullYear(), this._activeMonth.getMonth(), this._activeDate.getDate(), this._activeDate.getHours(), this._activeDate.getMinutes(), this._activeDate.getSeconds());
		
		if (r.Y !== false && r.Y != newDate.getFullYear()) {this._activeDate.setFullYear(r.Y); hasChanged = true;}
		if (r.m !== false) {r.m--; if (r.m != newDate.getMonth()) {this._activeDate.setMonth(r.m); hasChanged = true;} }
		if (r.d !== false && r.d != newDate.getDate()) {this._activeDate.setDate(r.d); hasChanged = true;}
		if (r.H !== false && r.H != newDate.getHours()) {this._activeDate.setHours(r.H); hasChanged = true;}
		if (r.i !== false && r.i != newDate.getMinutes()) {this._activeDate.setMinutes(r.i); hasChanged = true;}
		if (r.s !== false && r.s != newDate.getSeconds()) {this._activeDate.setSeconds(r.s); hasChanged = true;}
		
		this._drawMonth(this._activeDate);
		
		this._updateVisibleMinutes();
		this._updateVisibleHours();
		
		if (this._sel && this._isSelectorVisible()) this._doOnSelectorShow(this._sel._t);
		if (hasChanged)	this._doOnSelectorChange(true);
		
	}

Namely, I’ve added the “hasChanged” variable which is set to true when there really is a change and bingo! The onChange started working as expected. I hope this helps :slight_smile:.

Osu

good idea but it still doesn’t trigger the user function when you change a date. :cry:

Yeah, I noticed it too. The _updateDateStr method is called when the calendar appears, which is why the onChange is never fired once it’s been opened (a bit strange if you ask me). The only way I could find to circumvent this is to memorize the value of the calendar when it appears and then bind a custom method to the onClick event that checks whether the new value is identical to the one in memory. That’s a bit of a hassle, but I don’t really have time to dig into the code at the moment. Since I’m using Jquery, I encapsulated this treatment in a class and used the framework’s ability to fire custom events, so I’m using my own “change” event which fires when I need.

If you want to do the digging, my best bet would be the _doOnClick method (which I believe is executed when you click on the calendar), but I can’t confirm that since I don’t have time to test things out.

I hope I was able to help you out.

Osu

oh well… I don’t have time to modify their code either. they even posted a response to me that had an example they say works, but it doesn’t.

I just need to find a popup calendar that works as expected. [sigh]

thanks…

Well, have you tried the Anytime datepicker? I know I have and it always worked well when I needed it. Just type “Anytime datepicker” in google and it should show up in the first results.