<?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>Kickass Labs &#187; HTML</title>
	<atom:link href="http://www.kickasslabs.com/category/html/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.kickasslabs.com</link>
	<description>We &#9829; code.</description>
	<lastBuildDate>Sun, 04 Jul 2010 03:00:07 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Google Maps events in Mobile Safari and PhoneGap for iPhone</title>
		<link>http://www.kickasslabs.com/2009/04/29/google-maps-events-in-mobile-safari-and-phonegap-for-iphone/</link>
		<comments>http://www.kickasslabs.com/2009/04/29/google-maps-events-in-mobile-safari-and-phonegap-for-iphone/#comments</comments>
		<pubDate>Wed, 29 Apr 2009 20:23:27 +0000</pubDate>
		<dc:creator>Brad</dc:creator>
				<category><![CDATA[Google Maps]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[hacks]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[Events]]></category>
		<category><![CDATA[gmaps]]></category>

		<guid isPermaLink="false">http://www.kickasslabs.com/?p=255</guid>
		<description><![CDATA[Having trouble getting your Google Maps div to respond to events like you want in Mobile Safari or a PhoneGap app for iPhone?  So was I.  Disabling pinch-zoom is simple enough, but getting a finger drag to (a) not move the map and (b) draw something on the map was a major pain. [...]]]></description>
			<content:encoded><![CDATA[<p>Having trouble getting your <a href="http://code.google.com/apis/maps/" target="gmaps" title="Google Maps">Google Maps</a> div to respond to events like you want in Mobile Safari or a <a href="http://www.phonegap.com/" target="phonegap" title="PhoneGap">PhoneGap</a> app for iPhone?  So was I.  Disabling pinch-zoom is simple enough, but getting a finger drag to (a) not move the map and (b) draw something on the map was a major pain.  I share my solution below:  Proxying events through a transparent div overlaid on the Google Maps div.</p>
<p>To play along at home, you&#8217;ll need your own <a href="http://code.google.com/apis/maps/signup.html" target="gmaps_key" title="Google Maps API Key signup">Google Maps key</a> or you can just aim your mobile browser to my <a href="http://kickasslabs.com/examples/gmap_events.html" target="gmaps_example" title="Google Maps Event Proxying Example">example code at http://kickasslabs.com/examples/gmap_events.html</a>.  (Note that this will <i>not</i> work in a regular desktop browser.)  Besides a <tt>&lt;script&gt;</tt> tag importing the GMaps JavaScript, you should not need any other libraries or tools besides Mobile Safari to view and use the example page.  If the page is zoomed way out when you start, just double-tap the map tile in the upper-left corner &#8211; it should zoom to fill your viewport.</p>
<p>What you should see is a map tile with a line painted on it.  If you touch the screen, you should see one end of the line follow your finger.</p>
<p>It looks simple but I had a bit of trouble getting it to work, because touch events are not like mouse events (curious as to <a href="http://www.quirksmode.org/blog/archives/2008/08/iphone_events.html" target="mouse_vs_touch" title="Mouse vs. Touch">why?</a>), and GMaps doesn&#8217;t respond to touch events by default.</p>
<p><b>Step by Step</b></p>
<p>First, you need 2 divs:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">    &lt;!-- This div holds our map --&gt;
    &lt;div id=&quot;map&quot; style=&quot;width: 320; height: 320px&quot;&gt;&lt;/div&gt;
&nbsp;
    &lt;!-- This div lies on top of the map and acts as an event proxy --&gt;
    &lt;div id=&quot;mapoverlay&quot; style=&quot;height:320px; width: 320px; position: absolute;&quot;&gt;&lt;/div&gt;</pre></div></div>

<p>And you need to position one div over the other:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">    mapDiv = document.getElementById('map');
    mapOverlayDiv = document.getElementById('mapoverlay');
    mapOverlayDiv.style.top = (mapDiv.offsetTop + 0) + 'px';
    mapOverlayDiv.style.left = (mapDiv.offsetLeft + 0) + 'px';</pre></div></div>

<p>You set up the map div like you would for any other GMaps-enabled page:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">    // the map
    _map = new GMap2(document.getElementById(&quot;map&quot;));
&nbsp;
    // coordinates for home base
    _lat = 37;
    _lng = -95;
    mapCenter = new GLatLng(_lat, _lng);
    _map.setCenter(mapCenter, 15);</pre></div></div>

<p>Set up the overlay div to respond to touch events by firing a custom event for your map, e.g.:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">    mapOverlayDiv.ontouchstart = function(e) {
      GEvent.trigger(_map, 'customTouchStart',
        (e.touches[0].pageX - mapDiv.offsetLeft),
        (e.touches[0].pageY - mapDiv.offsetTop));
    }</pre></div></div>

<p>Now have your map respond to that event:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">    GEvent.addListener(_map, 'customTouchStart', mapTouchStart);</pre></div></div>

<p>&#8230;where <tt>mapTouchStart</tt> is a callback function that does something useful in response to a touch:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">    function mapTouchStart(xPixel, yPixel) {
      redrawLine(xPixel, yPixel);
    }</pre></div></div>

<p>And&#8230; well, then you&#8217;re done.  My example also responds to the touchMove event and has a little code for drawing lines, but you&#8217;ve seen all you need to know to get event proxying up and running for your app.</p>
<p>Got a question?  Got working code for an easier way?  Drop me a line in the comments!</p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.kickasslabs.com%2F2009%2F04%2F29%2Fgoogle-maps-events-in-mobile-safari-and-phonegap-for-iphone%2F&amp;linkname=Google%20Maps%20events%20in%20Mobile%20Safari%20and%20PhoneGap%20for%20iPhone"><img src="http://www.kickasslabs.com/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share/Bookmark"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.kickasslabs.com/2009/04/29/google-maps-events-in-mobile-safari-and-phonegap-for-iphone/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>InvalidAuthenticityToken, Forms, Tables, and Rails</title>
		<link>http://www.kickasslabs.com/2009/03/01/invalidauthenticitytoken-forms-tables-and-rails/</link>
		<comments>http://www.kickasslabs.com/2009/03/01/invalidauthenticitytoken-forms-tables-and-rails/#comments</comments>
		<pubDate>Sun, 01 Mar 2009 19:12:41 +0000</pubDate>
		<dc:creator>gabe</dc:creator>
				<category><![CDATA[HTML]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[forms]]></category>
		<category><![CDATA[invalidauthenticitytoken]]></category>
		<category><![CDATA[tables]]></category>

		<guid isPermaLink="false">http://www.kickasslabs.com/?p=167</guid>
		<description><![CDATA[Recently, while pairing with Abel as we hacked on some code for his budget tracking app, we came across an interesting problem while trying to acomplish what seems like a pretty straightforward task.

The Context: We had a table of records were using remote_form_for to output an edit form for each row so that we could [...]]]></description>
			<content:encoded><![CDATA[<p>Recently, while pairing with Abel as we hacked on some code for his budget tracking app, we came across an interesting problem while trying to acomplish what seems like a pretty straightforward task.</p>
<p><span id="more-167"></span></p>
<p><strong>The Context</strong>: We had a table of records were using remote_form_for to output an edit form for each row so that we could allow inline editing of any row via AJAX.  The code looked something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="haml" style="font-family:monospace;">-remote_form_for(person) do |f|
  %tr
    %td
      =f.text_field :first_name
    %td
      =f.text_field :last_name
    %td
      =f.submit 'Save'</pre></div></div>

<p>If you prefer straight HTML, the relevant code looked something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;form&gt;
&lt;input name=&quot;person[first_name]&quot; type=&quot;text&quot; /&gt;
&lt;input name=&quot;person[last_name]&quot; type=&quot;text&quot; /&gt;
&lt;input type=&quot;submit&quot; value=&quot;Save&quot; /&gt;
&lt;/form&gt;</pre></div></div>

<p><strong>The Problem</strong>: When submitting an edit on any of the people rows, we would see an ActionController::InvalidAuthenticityToken exception in the server log.  This error is usually a sign of a configuration problem with your environment, but our case seemed different.  Firebug showed us that the browser didn&#8217;t appear to be passing any params to the server during it&#8217;s update post and the server log didn&#8217;t show any params coming through, either.  So, it wasn&#8217;t an invalid authenticity token being passed; no token was being pased at all.  I would prefer if Rails gave us a MissingAuthenticityToken error instead but I digress.</p>
<p><strong>The Discovery</strong>: After whipping up a test case where we had a remote form on a page working fine with no errors, we discovered that the problem only occured when the form was wrapping the record&#8217;s table row tag in the view.  And, well, this makes a good deal of sense.  Here&#8217;s what the <a href="http://www.w3.org/TR/html401/sgml/dtd.html#block">HTML 4.01 spec</a> says about FORMs and TABLEs (relevant lines from the spec have been pasted below in a convenient order):</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;!--ELEMENT TABLE - -
     (CAPTION?, (COL*|COLGROUP*), THEAD?, TFOOT?, TBODY+)--&gt;
&lt;!--ELEMENT TBODY O O (TR)+   table body  --&gt;
&lt;!--ELEMENT TR       - O (TH|TD)+          table row  --&gt;
&lt;!--ELEMENT (TH|TD)  - O (%flow;)*         table header cell, table data cell --&gt;
&lt;!--ENTITY % flow &quot;%block; | %inline;&quot;--&gt;
&lt;!--ENTITY % block
     &quot;P | %heading; | %list; | %preformatted; | DL | DIV | NOSCRIPT |
      BLOCKQUOTE | FORM | HR | TABLE | FIELDSET | ADDRESS&quot;--&gt;</pre></div></div>

<p>If you&#8217;re not used to looking at DTDs, all that synax can be hard to grok.  Here&#8217;s what the relevant parts of it say, in plain English:</p>
<ul>
<li>TABLEs must have a TBODY</li>
<li>TBODYs must have a TR</li>
<li>TRs must have THs or TDs</li>
<li>TDs can have any elements inside them as long as those elements belong to the <em>flow</em> group</li>
<li>The <em>flow</em> group consists of elements inside the <em>block</em> group and the <em>inline</em> group</li>
<li>FORM elements are part of the <em>block</em> group.</li>
</ul>
<p>So, what was happening was that the browser saw our FORM element defined as a sibling to the TR.  That&#8217;s not allowed in the spec, so it makes some bit of sense that the browser wouldn&#8217;t pass the form data to the server the way we expect it would.  After all, the browser is dealing with invalid markup here.</p>
<p><strong>The Solution</strong>: The solution we found was to wrap the form input controls inside one big table that&#8217;s wrapped by the form tag, like this:</p>

<div class="wp_syntax"><div class="code"><pre class="haml" style="font-family:monospace;">%table
  -@people.each do |person|
    %tr
      %td
        -remote_form_for(person) do |f|
          %table
            %tr
              %td
                =f.text_field :first_name
              %td
                =f.text_field :last_name
              %td
                =f.submit 'Save'</pre></div></div>

<p>Again, in HTML:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;table border=&quot;0&quot;&gt;
  &amp;lt;% @people.each do |person| %&amp;gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;form&gt;
&lt;table border=&quot;0&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;input name=&quot;person[first_name]&quot; type=&quot;text&quot; /&gt;&lt;/td&gt;
&lt;td&gt;
&lt;input name=&quot;person[last_name]&quot; type=&quot;text&quot; /&gt;&lt;/td&gt;
&lt;td&gt;
&lt;input type=&quot;submit&quot; value=&quot;Save&quot; /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/form&gt;&lt;/td&gt;
&lt;/tr&gt;
&amp;lt;% end %&amp;gt;&lt;/tbody&gt;&lt;/table&gt;</pre></div></div>

<p>Note: at this point we&#8217;re using a table for layout, and it&#8217;s nasty as all hell.  <strong>I don&#8217;t recommend that you structure your markup this way.</strong></p>
<p>But, <strong>this example illustrates is how you can use a FORM element inside of a TABLE and have it actually work</strong>.  And, more importantly, now we know why we were getting an InvalidAuthenticityToken error when everything seemed like it should have worked.</p>
<p>Hope this helps anyone else in the same situation.</p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.kickasslabs.com%2F2009%2F03%2F01%2Finvalidauthenticitytoken-forms-tables-and-rails%2F&amp;linkname=InvalidAuthenticityToken%2C%20Forms%2C%20Tables%2C%20and%20Rails"><img src="http://www.kickasslabs.com/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share/Bookmark"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.kickasslabs.com/2009/03/01/invalidauthenticitytoken-forms-tables-and-rails/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
