<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>inventive title : ajax.toolkit.calendar</title><link>http://blogs.msdn.com/rbuckton/archive/tags/ajax.toolkit.calendar/default.aspx</link><description>Tags: ajax.toolkit.calendar</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>DOM Event inconsistencies between browsers</title><link>http://blogs.msdn.com/rbuckton/archive/2007/09/11/dom-event-inconsistencies-between-browsers.aspx</link><pubDate>Tue, 11 Sep 2007 23:48:33 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:4869814</guid><dc:creator>Ron Buckton</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/rbuckton/comments/4869814.aspx</comments><wfw:commentRss>http://blogs.msdn.com/rbuckton/commentrss.aspx?PostID=4869814</wfw:commentRss><wfw:comment>http://blogs.msdn.com/rbuckton/rsscomments.aspx?PostID=4869814</wfw:comment><description>&lt;p&gt;I've been working on some bugs in the &lt;a href="http://ajax.asp.net/ajaxtoolkit/calendar" target="_blank"&gt;Calendar&lt;/a&gt; extender from the &lt;a href="http://ajax.asp.net/ajaxtoolkit" target="_blank"&gt;ASP.NET AJAX Control Toolkit&lt;/a&gt; and have been resolving some of the focus/blur events.&amp;nbsp; I've been trying to make the calendar work consistently across all of the browsers and found some frustrating differences in event firing order between the browsers.&lt;/p&gt; &lt;p&gt;Here are a list of some of the DOM events supported by the various browsers I tested:&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h5&gt;&lt;/h5&gt; &lt;h4&gt;Table 1 - DOM Events by Browser&lt;/h4&gt; &lt;table cellspacing="0" cellpadding="2" width="418" border="1"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="122"&gt;Event&lt;/td&gt; &lt;td align="middle" width="69"&gt;DOM Level&lt;/td&gt; &lt;td align="middle" width="53"&gt;IE&lt;/td&gt; &lt;td align="middle" width="55"&gt;FF&lt;/td&gt; &lt;td align="middle" width="56"&gt;OP&lt;/td&gt; &lt;td align="middle" width="61"&gt;SF&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="122"&gt;DOMActivate&lt;/td&gt; &lt;td align="middle" width="69"&gt;Level 2&lt;/td&gt; &lt;td align="middle" width="53"&gt;&amp;nbsp;&lt;/td&gt; &lt;td align="middle" width="55"&gt;&amp;nbsp;&lt;/td&gt; &lt;td align="middle" width="56"&gt;&amp;nbsp;&lt;/td&gt; &lt;td align="middle" width="61"&gt;*&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="122"&gt;activate&lt;/td&gt; &lt;td align="middle" width="69"&gt;&lt;sup&gt;&lt;i&gt;2&lt;/i&gt;&lt;/sup&gt;&lt;/td&gt; &lt;td align="middle" width="53"&gt;*&lt;/td&gt; &lt;td align="middle" width="55"&gt;&amp;nbsp;&lt;/td&gt; &lt;td align="middle" width="56"&gt;&amp;nbsp;&lt;/td&gt; &lt;td align="middle" width="61"&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="122"&gt;DOMFocusIn&lt;/td&gt; &lt;td align="middle" width="69"&gt;Level 2&lt;/td&gt; &lt;td align="middle" width="53"&gt;&amp;nbsp;&lt;/td&gt; &lt;td align="middle" width="55"&gt;&amp;nbsp;&lt;/td&gt; &lt;td align="middle" width="56"&gt;&lt;sup&gt;&lt;i&gt;1&lt;/i&gt;&lt;/sup&gt;&lt;/td&gt; &lt;td align="middle" width="61"&gt;&lt;sup&gt;&lt;i&gt;1&lt;/i&gt;&lt;/sup&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="122"&gt;focusin&lt;/td&gt; &lt;td align="middle" width="69"&gt;&lt;sup&gt;&lt;i&gt;2&lt;/i&gt;&lt;/sup&gt;&lt;/td&gt; &lt;td align="middle" width="53"&gt;*&lt;/td&gt; &lt;td align="middle" width="55"&gt;&amp;nbsp;&lt;/td&gt; &lt;td align="middle" width="56"&gt;&amp;nbsp;&lt;/td&gt; &lt;td align="middle" width="61"&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="122"&gt;focus&lt;/td&gt; &lt;td align="middle" width="69"&gt;Level 0&lt;/td&gt; &lt;td align="middle" width="53"&gt;*&lt;/td&gt; &lt;td align="middle" width="55"&gt;&lt;sup&gt;&lt;i&gt;1&lt;/i&gt;&lt;/sup&gt;&lt;/td&gt; &lt;td align="middle" width="56"&gt;&lt;sup&gt;&lt;i&gt;1&lt;/i&gt;&lt;/sup&gt;&lt;/td&gt; &lt;td align="middle" width="61"&gt;&lt;sup&gt;&lt;i&gt;1&lt;/i&gt;&lt;/sup&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="122"&gt;DOMDeactivate&lt;/td&gt; &lt;td align="middle" width="69"&gt;Level 2&lt;/td&gt; &lt;td align="middle" width="53"&gt;&amp;nbsp;&lt;/td&gt; &lt;td align="middle" width="55"&gt;&amp;nbsp;&lt;/td&gt; &lt;td align="middle" width="56"&gt;&amp;nbsp;&lt;/td&gt; &lt;td align="middle" width="61"&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="122"&gt;deactivate&lt;/td&gt; &lt;td align="middle" width="69"&gt;&lt;sup&gt;&lt;i&gt;2&lt;/i&gt;&lt;/sup&gt;&lt;/td&gt; &lt;td align="middle" width="53"&gt;*&lt;/td&gt; &lt;td align="middle" width="55"&gt;&amp;nbsp;&lt;/td&gt; &lt;td align="middle" width="56"&gt;&amp;nbsp;&lt;/td&gt; &lt;td align="middle" width="61"&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="122"&gt;DOMFocusOut&lt;/td&gt; &lt;td align="middle" width="69"&gt;Level 2&lt;/td&gt; &lt;td align="middle" width="53"&gt;&amp;nbsp;&lt;/td&gt; &lt;td align="middle" width="55"&gt;&amp;nbsp;&lt;/td&gt; &lt;td align="middle" width="56"&gt;&lt;sup&gt;&lt;i&gt;1&lt;/i&gt;&lt;/sup&gt;&lt;/td&gt; &lt;td align="middle" width="61"&gt;&lt;sup&gt;&lt;i&gt;1&lt;/i&gt;&lt;/sup&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="122"&gt;focusout&lt;/td&gt; &lt;td align="middle" width="69"&gt;&lt;sup&gt;&lt;i&gt;2&lt;/i&gt;&lt;/sup&gt;&lt;/td&gt; &lt;td align="middle" width="53"&gt;*&lt;/td&gt; &lt;td align="middle" width="55"&gt;&amp;nbsp;&lt;/td&gt; &lt;td align="middle" width="56"&gt;&amp;nbsp;&lt;/td&gt; &lt;td align="middle" width="61"&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="122"&gt;blur&lt;/td&gt; &lt;td align="middle" width="69"&gt;Level 0&lt;/td&gt; &lt;td align="middle" width="53"&gt;*&lt;/td&gt; &lt;td align="middle" width="55"&gt;&lt;sup&gt;&lt;i&gt;1&lt;/i&gt;&lt;/sup&gt;&lt;/td&gt; &lt;td align="middle" width="56"&gt;&lt;sup&gt;&lt;i&gt;1&lt;/i&gt;&lt;/sup&gt;&lt;/td&gt; &lt;td align="middle" width="61"&gt;&lt;sup&gt;&lt;i&gt;1&lt;/i&gt;&lt;/sup&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="122"&gt;mousedown&lt;/td&gt; &lt;td align="middle" width="69"&gt;Level 0&lt;/td&gt; &lt;td align="middle" width="53"&gt;*&lt;/td&gt; &lt;td align="middle" width="55"&gt;*&lt;/td&gt; &lt;td align="middle" width="56"&gt;*&lt;/td&gt; &lt;td align="middle" width="61"&gt;*&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="122"&gt;mouseup&lt;/td&gt; &lt;td align="middle" width="69"&gt;Level 0&lt;/td&gt; &lt;td align="middle" width="53"&gt;*&lt;/td&gt; &lt;td align="middle" width="55"&gt;*&lt;/td&gt; &lt;td align="middle" width="56"&gt;*&lt;/td&gt; &lt;td align="middle" width="61"&gt;*&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td width="122"&gt;click&lt;/td&gt; &lt;td align="middle" width="69"&gt;Level 0&lt;/td&gt; &lt;td align="middle" width="53"&gt;*&lt;/td&gt; &lt;td align="middle" width="55"&gt;*&lt;/td&gt; &lt;td align="middle" width="56"&gt;*&lt;/td&gt; &lt;td align="middle" width="61"&gt;*&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p style="font-size: x-small"&gt;&lt;i&gt;IE: Internet Explorer 7.0&lt;br&gt;FF: Firefox 2.0.0.6&lt;br&gt;OP: Opera 9.23&lt;br&gt;SF: Safari 3.03 Beta (Windows)&lt;br&gt;*: Implemented on any element&lt;br&gt;1: Implemented only on specific elements&lt;br&gt;2: IE-only implementation&lt;br&gt;&lt;/i&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Internet Explorer uses activate/focusin/focusout instead of DOMActivate/DOMFocusIn/DOMFocusOut for events.&amp;nbsp; Interestingly only IE and Safari support DOMActivate/activate on any element.&amp;nbsp; Another thing I saw was that IE is the only browser which fires focus/blur events for any element.&amp;nbsp; Other browsers can support the focus/blur events on any element that has a tab index however.&lt;/p&gt; &lt;p&gt;The next version of Calendar needs to support the following activation scenarios depending on whether it is also associated with a button:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;No Button&lt;/li&gt; &lt;ul&gt; &lt;li&gt;Show Popup when textbox receives focus&lt;/li&gt; &lt;li&gt;Show Popup when textbox is clicked &lt;/li&gt; &lt;li&gt;Hide Popup when textbox loses focus&lt;/li&gt; &lt;li&gt;Hide Popup when textbox receives ESC keypress&lt;/li&gt; &lt;li&gt;Hide Popup when a date is selected&lt;/li&gt;&lt;/ul&gt; &lt;li&gt;Button&lt;/li&gt; &lt;ul&gt; &lt;li&gt;Show Popup when the button is clicked&lt;/li&gt; &lt;li&gt;Hide Popup when the button loses focus&lt;/li&gt; &lt;li&gt;Hide Popup when the button receives ESC keypress&lt;/li&gt; &lt;li&gt;Hide Popup when a date is selected&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt; &lt;p&gt;The issue is that when the textbox or button loses focus the popup should hide &lt;strong&gt;unless &lt;/strong&gt;the focus is being directed at the popup itself.&amp;nbsp; The problem is that only IE recognizes a &lt;em&gt;focus&lt;/em&gt; event on the popup's DIV tag when the popup is not part of the tab order (and we don't want the popup in the tab order). I was curious the order of DOM events fired in each browser so I wrote a small test page and stepped through for each.&amp;nbsp; The results are as follows:&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h4&gt;Table 2 - DOM Event Order by browser&lt;/h4&gt; &lt;table cellspacing="0" cellpadding="2" width="764" border="1"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td valign="top" width="191"&gt;IE&lt;/td&gt; &lt;td valign="top" width="187"&gt;FF&lt;/td&gt; &lt;td valign="top" width="187"&gt;OP&lt;/td&gt; &lt;td valign="top" width="197"&gt;SF&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" width="190"&gt; &lt;ol&gt; &lt;li&gt;&lt;strong&gt;// click on INPUT&lt;/strong&gt;  &lt;li&gt;INPUT: mousedown  &lt;li&gt;INPUT: activate  &lt;li&gt;INPUT: focusin  &lt;li&gt;INPUT: focus  &lt;li&gt;INPUT: mouseup  &lt;li&gt;INPUT: click  &lt;li&gt;&lt;strong&gt;// click on DIV&lt;/strong&gt;  &lt;li&gt;DIV: mousedown  &lt;li&gt;INPUT: deactivate  &lt;li&gt;INPUT: focusout  &lt;li&gt;DIV: activate  &lt;li&gt;DIV: focusin  &lt;li&gt;INPUT: blur  &lt;li&gt;DIV: focus  &lt;li&gt;DIV: mouseup  &lt;li&gt;DIV: click  &lt;li&gt;&lt;strong&gt;// click away&lt;/strong&gt;  &lt;li&gt;DIV: deactivate  &lt;li&gt;DIV: focusout  &lt;li&gt;DIV: blur&lt;/li&gt;&lt;/ol&gt;&lt;/td&gt; &lt;td valign="top" width="187"&gt; &lt;ol&gt; &lt;li&gt;&lt;strong&gt;// click on INPUT&lt;/strong&gt;  &lt;li&gt;INPUT: mousedown  &lt;li&gt;INPUT: focus  &lt;li&gt;INPUT: mouseup  &lt;li&gt;INPUT: click  &lt;li&gt;&lt;strong&gt;// click on DIV&lt;/strong&gt;  &lt;li&gt;DIV: mousedown  &lt;li&gt;INPUT: blur  &lt;li&gt;DIV: mouseup  &lt;li&gt;DIV: click  &lt;li&gt;&lt;strong&gt;// click away&lt;/strong&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/td&gt; &lt;td valign="top" width="188"&gt; &lt;ol&gt; &lt;li&gt;&lt;strong&gt;// click on INPUT&lt;/strong&gt;  &lt;li&gt;INPUT: focus  &lt;li&gt;INPUT: DOMFocusIn  &lt;li&gt;INPUT: mousedown  &lt;li&gt;INPUT: mouseup  &lt;li&gt;INPUT: click  &lt;li&gt;&lt;strong&gt;// click on DIV&lt;/strong&gt;  &lt;li&gt;INPUT: blur  &lt;li&gt;INPUT: DOMFocusOut  &lt;li&gt;DIV: mousedown  &lt;li&gt;DIV: mouseup  &lt;li&gt;DIV: click  &lt;li&gt;&lt;strong&gt;// click away&lt;/strong&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/td&gt; &lt;td valign="top" width="197"&gt; &lt;ol&gt; &lt;li&gt;&lt;strong&gt;// click on INPUT&lt;/strong&gt;  &lt;li&gt;INPUT: mousedown  &lt;li&gt;INPUT: focus  &lt;li&gt;INPUT: DOMFocusIn  &lt;li&gt;INPUT: mouseup  &lt;li&gt;INPUT: click  &lt;li&gt;INPUT: DOMActivate  &lt;li&gt;&lt;strong&gt;// click on DIV&lt;/strong&gt;  &lt;li&gt;DIV: mousedown  &lt;li&gt;INPUT: blur  &lt;li&gt;INPUT: DOMFocusOut  &lt;li&gt;DIV: mouseup  &lt;li&gt;DIV: click  &lt;li&gt;DIV: DOMActivate  &lt;li&gt;&lt;strong&gt;// click away&lt;/strong&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Immediately a few things become obvious. First, I obviously cannot rely on focus/blur on the other browsers. IE would allow me to capture &lt;em&gt;focusin &lt;/em&gt;on the DIV before the &lt;em&gt;blur&lt;/em&gt; fires on the INPUT but that's just IE. Second, on all browsers except Opera the &lt;em&gt;mousedown&lt;/em&gt; event of the DIV fires &lt;strong&gt;before&lt;/strong&gt; the &lt;em&gt;blur&lt;/em&gt; event of the INPUT. There's no clean sequential way to handle the focus transition in all browsers.&lt;/p&gt; &lt;p&gt;In the current version of Calendar we're making use of a "threading" class I created for the toolkit called DeferredOperation.&amp;nbsp; DeferredOperation wraps a delegate and executes it asynchronously using setTimout.&amp;nbsp; It has some built-in synchronization semantics and was used to handle the focus changes while the popup DIV was part of the tab order (which again, we don't really want). This introduces a subtle delay between activation requests and is problematic on Safari (we had to wait a full second before processing the deferred operation to let safari to catch up).&lt;/p&gt; &lt;p&gt;What I've opted for now is to do the best I can in three out of four of the browsers.&amp;nbsp; I track &lt;em&gt;mousedown/mouseup&lt;/em&gt; using a flag and in Internet Explorer, Firefox, and Safari and monitor the flag in the &lt;em&gt;blur&lt;/em&gt; event of the textbox. To handle the Opera inconsistency I again use a DeferredOperation to asynchronously handle the &lt;em&gt;blur&lt;/em&gt; event which fixes the issue in that browser.&lt;/p&gt; &lt;p&gt;The final issue I discovered was that in all browsers, clicking on the popup causes the textbox (or button) to lose focus which again causes problems with the tab order.&amp;nbsp; On the new Calendar I reset the focus to the textbox (or button) on &lt;em&gt;mouseup&lt;/em&gt; on the popup.&lt;/p&gt; &lt;p&gt;Hopefully these changes should make the next toolkit release so keep an eye out for the next update.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=4869814" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/rbuckton/archive/tags/ajax/default.aspx">ajax</category><category domain="http://blogs.msdn.com/rbuckton/archive/tags/scripting/default.aspx">scripting</category><category domain="http://blogs.msdn.com/rbuckton/archive/tags/ajax.toolkit.calendar/default.aspx">ajax.toolkit.calendar</category><category domain="http://blogs.msdn.com/rbuckton/archive/tags/ajax.toolkit/default.aspx">ajax.toolkit</category></item><item><title>Skinning model for Calendar and Tabs in Ajax Control Toolkit</title><link>http://blogs.msdn.com/rbuckton/archive/2007/08/24/skinning-model-for-calendar-and-tabs-in-ajax-control-toolkit.aspx</link><pubDate>Sat, 25 Aug 2007 05:53:26 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:4551898</guid><dc:creator>Ron Buckton</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/rbuckton/comments/4551898.aspx</comments><wfw:commentRss>http://blogs.msdn.com/rbuckton/commentrss.aspx?PostID=4551898</wfw:commentRss><wfw:comment>http://blogs.msdn.com/rbuckton/rsscomments.aspx?PostID=4551898</wfw:comment><description>&lt;p&gt;This article was originally posted on 2/2/2007. The original host of the article is no longer available.&amp;nbsp; Due to the high demand for the content I am reproducing it in its entirety.&amp;nbsp; Click below for the full article.&lt;/p&gt; &lt;p&gt;&lt;a title="Skinning model for Calendar and Tabs in Ajax Control Toolkit" href="http://blogs.msdn.com/rbuckton/pages/ajaxskinning.aspx"&gt;Read 'Skinning model for Calendar and Tabs in Ajax Control Toolkit'...&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=4551898" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/rbuckton/archive/tags/ajax/default.aspx">ajax</category><category domain="http://blogs.msdn.com/rbuckton/archive/tags/asp.net/default.aspx">asp.net</category><category domain="http://blogs.msdn.com/rbuckton/archive/tags/ajax.toolkit.calendar/default.aspx">ajax.toolkit.calendar</category><category domain="http://blogs.msdn.com/rbuckton/archive/tags/ajax.toolkit/default.aspx">ajax.toolkit</category><category domain="http://blogs.msdn.com/rbuckton/archive/tags/ajax.toolkit.dropdown/default.aspx">ajax.toolkit.dropdown</category></item></channel></rss>