<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>VinylFox &#187; ExtJS Overrides</title>
	<atom:link href="http://www.vinylfox.com/tag/extjs-overrides/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.vinylfox.com</link>
	<description>The Playground of VinylFox (Shea Frederick)</description>
	<lastBuildDate>Thu, 29 Jul 2010 16:37:06 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Forwarding Mouse Events Through Layers</title>
		<link>http://www.vinylfox.com/forwarding-mouse-events-through-layers/</link>
		<comments>http://www.vinylfox.com/forwarding-mouse-events-through-layers/#comments</comments>
		<pubDate>Wed, 30 Sep 2009 15:05:46 +0000</pubDate>
		<dc:creator>Shea Frederick</dc:creator>
				<category><![CDATA[ExtJS]]></category>
		<category><![CDATA[ExtJS Plugins]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[ExtJS Overrides]]></category>

		<guid isPermaLink="false">http://www.vinylfox.com/?p=499</guid>
		<description><![CDATA[Anyone who has worked with web apps has likely created a masking element at some point, and the great thing about a masking element is that it intercepts user interaction, letting us create a pseudo-modal user interface. The masking element enables us to mask the entire screen, bringing focus to a particular element, or just [...]]]></description>
			<content:encoded><![CDATA[<p>Anyone who has worked with web apps has likely created a masking element at some point, and the great thing about a masking element is that it intercepts user interaction, letting us create a pseudo-modal user interface. The masking element enables us to mask the entire screen, bringing focus to a particular element, or just create a window like effect. This behavior is demonstrated in the ExtJS libraries <em>Ext.Window</em> when <em>modal </em>is set to true, among other places.</p>
<h3>Yeah, so what?</h3>
<p><img src="http://www.vinylfox.com/wp-content/uploads/2009/09/layers-masked1.png" alt="layers-masked1" title="layers-masked1" width="250" height="163" class="alignright size-full wp-image-543" />The problem comes when we want to mask a part of the screen, but also want the elements behind that mask to continue responding to user interaction. This behavior is counter to most native behavior. What we are left with, is having to forward mouse events through the masking layer to the layer below, an option that simply does not exist in the standard JavaScript/DOM API.</p>
<h3>Why do this?</h3>
<p>A plugin that I recently wrote &#8211; <a href="http://code.google.com/p/ext-ux-datadrop/" target="_blank">DataDrop </a>- used a <em>textarea </em>overlaying a grid to act as the receiver of dragged data from spreadsheet type programs. One of the limitations that I was not so happy about was the fact that this overlay could only exist in the &#8216;empty&#8217; area of the grid, not over rows of data, headers, toolbars, etc. otherwise it would cause all of those elements below to become unresponsive to user input. If our <em>textarea</em> that receives the data were positioned over the entire grid area, our <em>GridPanel</em> could not be controlled using the mouse anymore.</p>
<h3>How to fix this?</h3>
<p>This is where my friend Nige White (Animal) came in to help, it turns out that he had an idea about how to forward these mouse events using a couple of not well understood methods in the JavaScript/DOM API used for creating mouse events. Here are the steps taken:</p>
<ol>
<li>The <em>textarea </em> (my masking element) that is positioned over the grid receives <em>mouseover</em>, <em>mousemove</em>, <em>mousedown </em>, <em>mouseup </em> and other events.</li>
<li>The top masking layer is hidden for a moment, so we can figure out what element is below the mask at the event location.</li>
<li>The event is re-fired &#8211; this is where the <a href="http://www.w3.org/TR/DOM-Level-2-Events/ecma-script-binding.html" target="_blank">W3 DOM Event model</a> and the simpler <a href="http://msdn.microsoft.com/en-us/library/ms536423(VS.85).aspx" target="_blank">Microsoft equivalent</a> come into play.</li>
<li>Start the process again &#8211; ready for the next event.</li>
</ol>
<p><img src="http://www.vinylfox.com/wp-content/uploads/2009/09/layers-steps1.png" alt="layers-steps1" title="layers-steps1" width="500" height="326" class="alignright size-full wp-image-557" /></p>
<h3>What&#8217;s element to fire upon?</h3>
<p>Knowing the cursor position and event that occurred, the only obstacle now is determining what DOM element to fire the simulated event through. It turns out that finding which element is the topmost element at a certain document coordinate position is quite simple in modern browsers. The <b>document.elementFromPoint</b> method is supported in <a href="http://msdn.microsoft.com/en-us/library/ms536417(VS.85).aspx" target="_blank">IE</a>, <a href="https://developer.mozilla.org/en/DOM/document.elementFromPoint" target="_blank">Mozilla</a>, Webkit and Opera.</p>
<p>So it is possible to capture the document coordinates of a mouse event fired on the masking element, momentarily hide that masking element, and then ask the document what is under that coordinate position before showing the mask again.</p>
<p>A new event can be then fired on the found element. Obviously there are some complexities such as firing <em>mouseover </em>and <em>mouseout </em>events when the found element is different from the last time, but that is the gist of the technique. To <a href="http://screencast.com/t/4bZevAUwEuj" target="_blank">see it in action, check out the screencast</a> or play with the <a href="http://www.vinylfox.com/lib/latest/examples/grid/array-grid-datadrop.html" target="_blank">live Grid DataDrop example</a> or <a href="http://www.vinylfox.com/lib/latest/examples/core/evt-forwarding.html" target="_blank">simple DOM element example</a> yourself.</p>
<p>I have posted an <a href="http://code.google.com/p/ext-ux-datadrop/source/browse/trunk/src/Override.js"target="_blank">override of Ext.Element that Nigel created</a> on my Google Code site for all to enjoy, it is now a requirement for the ExtJS <a href="http://code.google.com/p/ext-ux-datadrop/"target="_blank">DataDrop plugin</a>. A big thanks goes out to Nige (Animal) for digging into the nuts and bolts of JavaScript to find a solution to my problem.</p>
<h3>The Next Step</h3>
<p>Having the data that is dropped into the grid automatically insert into the grids rows at the correct position is my next task for the ever-improving <a href="http://code.google.com/p/ext-ux-datadrop/"target="_blank">DataDrop plugin</a>. Should be fun :/</p>
<p>UPDATE (12-1-09): Seems that <a href="http://hacks.mozilla.org/2009/12/pointer-events-for-html-in-firefox-3-6/">Mozilla has also noticed this issue</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.vinylfox.com/forwarding-mouse-events-through-layers/feed/</wfw:commentRss>
		<slash:comments>24</slash:comments>
		</item>
	</channel>
</rss>
