<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>Peer Assembly Blog</title>
    <link href="http://peerassembly.com/atom.xml" rel="self"/>
    <link href="http://peerassembly.com/"/>
    <updated>2010-07-15T22:12:33+01:00</updated>
    <id>http://peerassembly.com/</id>
    <author>
        <name>Denis Hennessy</name>
        <email>denis@peerassembly.com</email>
    </author>
    
    <entry>
        <title>Forcing IE to Redraw List Items</title>
        <link href="http://peerassembly.com/2010/01/06/forcing-ie-to-redraw-list-items.html"/>
        <updated>2010-01-06T00:00:00+00:00</updated>
        <id>http://peerassembly.com/2010/01/06/forcing-ie-to-redraw-list-items</id>
        <content type="html">&lt;h3 id='forcing_ie_to_redraw_list_items'&gt;Forcing IE to Redraw List Items&lt;/h3&gt;

&lt;p&gt;Javascript is essential in allowing developers to tailor an intuitive and accessible experience for users. Web sites are becoming a lot more dynamic and javascript is key to this progression &lt;em&gt;(side note: I&amp;#8217;m not a fan of Flash, it makes my Mac work too hard)&lt;/em&gt;. However, as usual developers encounter lots of browser interop issues &amp;#8212; most of them with Internet Explorer.&lt;/p&gt;

&lt;p&gt;Recently I was using javascript to dynamically add extra data to an unordered list item. This worked fine in FireFox and Safari. However, it turns out Internet Explorer 6 &amp;#38; 7 are very intolerant of content being added, or removed, from &lt;code&gt;&amp;lt;li&amp;gt;&lt;/code&gt; elements. The problem is they don&amp;#8217;t recognize the list item has resized and therefore don&amp;#8217;t redraw it.&lt;/p&gt;

&lt;p&gt;Luckily it is possible to give IE a nudge, so that it redraws the list. To do this you need to dynamically add a new child element to the list&amp;#8230; and then remove it again. Here is an example javascript function, based on Prototype, which does exactly this. This function is now part of my toolbox and I call it after I add extra content to a list item.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='cm'&gt;/* IE 6 &amp;amp; 7 are very intolerant of extra content being&lt;/span&gt;
&lt;span class='cm'&gt; * added/removed to &amp;lt;li&amp;gt; elements so a redraw needs to be&lt;/span&gt;
&lt;span class='cm'&gt; * forced.&lt;/span&gt;
&lt;span class='cm'&gt; */&lt;/span&gt;
&lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='nx'&gt;forceListRedraw&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;listItem&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;Prototype&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;Browser&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;IE&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;try&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
      &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;n&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nb'&gt;document&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;createTextNode&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39; &amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
      
      &lt;span class='nx'&gt;listItem&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;appendChild&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;n&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
      &lt;span class='nx'&gt;listItem&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;removeChild&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;n&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;

      &lt;span class='nx'&gt;list&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;listItem&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;up&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;ul&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
      &lt;span class='nx'&gt;list&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;appendChild&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;n&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
      &lt;span class='nx'&gt;list&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;removeChild&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;n&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='p'&gt;}&lt;/span&gt; &lt;span class='k'&gt;catch&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;e&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;
  &lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;</content>
    </entry>
    
    <entry>
        <title>Grouped Links in a Rails application</title>
        <link href="http://peerassembly.com/2008/09/26/grouped-links-in-a-rails-application.html"/>
        <updated>2008-09-26T00:00:00+01:00</updated>
        <id>http://peerassembly.com/2008/09/26/grouped-links-in-a-rails-application</id>
        <content type="html">&lt;h3 id='background__grouped_links'&gt;Background - grouped links&lt;/h3&gt;

&lt;p&gt;Normally, when people talk about paging in a web application, they mean providing next/previous links and direct links to particular page numbers. Here are some examples you should be familiar with:&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/digg.png' alt='Digg' /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/google.png' alt='Google' /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/flickr.png' alt='Flickr' /&gt;&lt;/p&gt;

&lt;p&gt;This style of paging is supported very well by the &lt;strong&gt;will_paginate&lt;/strong&gt; plugin. However, some types of information don&amp;#8217;t readily lend themselves to this type of paging. When listing people, for instance, it&amp;#8217;s natural to want to jump directly to the &amp;#8216;M&amp;#8217; names, just like you would with a telephone directory. For this type of information, what you want is a set of links that take you directly to the page with the first occurrence of a particular letter:&lt;/p&gt;

&lt;p&gt;&lt;img src='/images/letters.png' alt='Letters' /&gt;&lt;/p&gt;

&lt;p&gt;The greyed letters indicate that there are no entries beginning with that letter.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;ve needed this for a recent project and implemented it as a patch to &lt;strong&gt;will_paginate&lt;/strong&gt;, it&amp;#8217;s available at &lt;a href='http://github.com/dhennessy/will_paginate/tree/master'&gt;http://github.com/dhennessy/will_paginate/tree/master&lt;/a&gt; for anyone who feels like trying it out.&lt;/p&gt;

&lt;h3 id='adding_grouped_links_to_an_existing_project'&gt;Adding grouped links to an existing project&lt;/h3&gt;

&lt;p&gt;The grouped links plugin depends on you having a grouping attribute on the data you want to display. For the example above, this might be the first letter of the name; for a recipe application, it might be the primary ingredient. The point is that this has to exist in the database as a separate column. One easy way to maintain this is to add a &lt;strong&gt;before_save&lt;/strong&gt; filter to your model that computes the grouping attribute:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='n'&gt;before_save&lt;/span&gt; &lt;span class='ss'&gt;:update_group_letter&lt;/span&gt;

&lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;update_group_letter&lt;/span&gt;
  &lt;span class='nb'&gt;self&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;first_letter&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nb'&gt;name&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;In your controller, you create a list of results as follows:&lt;/p&gt;

&lt;p&gt;&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='vi'&gt;@people&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;Person&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;paginate&lt;/span&gt; &lt;span class='ss'&gt;:page&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;params&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:page&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:group_by&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;first_letter&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;  &lt;span class='ss'&gt;:order&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;name ASC&amp;#39;&lt;/span&gt;
&lt;span class='vi'&gt;@people&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;add_missing_links&lt;/span&gt;&lt;span class='p'&gt;((&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;A&amp;#39;&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;.&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;Z&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;to_a&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;&lt;/p&gt;

&lt;p&gt;Normally, the paginate method will add a grouped link for every distinct value of the &lt;strong&gt;group_by&lt;/strong&gt; attribute. The &lt;strong&gt;add_missing_links&lt;/strong&gt; method in this example will add additional links for letters that don&amp;#8217;t already exist (which looks better in this case).&lt;/p&gt;

&lt;p&gt;Finally, add the following to your view:&lt;/p&gt;

&lt;p&gt;&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='cp'&gt;&amp;lt;%=&lt;/span&gt; &lt;span class='n'&gt;will_paginate&lt;/span&gt; &lt;span class='vi'&gt;@people&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:draw_if_single&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='kp'&gt;true&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:next_previous_links&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='kp'&gt;false&lt;/span&gt; &lt;span class='cp'&gt;%&amp;gt;&lt;/span&gt;&lt;span class='x' /&gt;
&lt;/pre&gt;
&lt;/div&gt;&lt;/p&gt;

&lt;p&gt;The draw_if_single option forces the links to be displayed, even if the results all fit on a single page. Note that the resulting links will have #A, #B, etc appended to them so that you can jump to a particular row (providing you set the anchor when the first letter changes in your list). As you can see, this is very similar to the way you&amp;#8217;re already using the &lt;strong&gt;will_paginate&lt;/strong&gt; plugin.&lt;/p&gt;

&lt;p&gt;Health Warning: this plugin should probably be treated as experimental as I may change things a bit as I get feedback from real users.&lt;/p&gt;</content>
    </entry>
    
</feed>