<?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>Vinsol - Leading Ruby on Rails Development and Consulting Firm in India &#187; jquery</title>
	<atom:link href="http://vinsol.com/blog/tag/jquery/feed/" rel="self" type="application/rss+xml" />
	<link>http://vinsol.com/blog</link>
	<description></description>
	<lastBuildDate>Wed, 11 Jan 2012 06:07:52 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Jquery Full Calendar with Ruby on Rails</title>
		<link>http://vinsol.com/blog/2010/03/29/jquery-full-calendar-with-rails/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=jquery-full-calendar-with-rails</link>
		<comments>http://vinsol.com/blog/2010/03/29/jquery-full-calendar-with-rails/#comments</comments>
		<pubDate>Mon, 29 Mar 2010 12:17:25 +0000</pubDate>
		<dc:creator>Akhil Bansal</dc:creator>
				<category><![CDATA[RubyonRails]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby on rails]]></category>
		<category><![CDATA[calendar]]></category>

		<guid isPermaLink="false">http://vinsol.com/blog/?p=834</guid>
		<description><![CDATA[Contrary to popular belief, working on a client project gives us a generous margin of creativity and explore innovative solutions. Take the example of a recent project I was working on. The client required a collaboration-based calendar module for their application similar to Google Calendar. Initially we started developing it from scratch , but then, [...]


No related posts.

Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p>Contrary to popular belief, working on a client project gives us a generous margin of creativity and explore innovative solutions. Take the example of a recent project I was working on. The client required a collaboration-based calendar module for their application similar to Google Calendar. Initially we started developing it from scratch , but then, we found an awesome Jquery plugin. <br/> <br/></p>
<p>&#8220;<a href="http://arshaw.com/fullcalendar/">FullCalendar</a>&#8221; provides a full-sized, drag &amp; drop calendar. It uses AJAX to fetch events on-the-fly for each month. It also supports an intuitive interface to manage events that spans over multiple days or weeks. It is visually customizable and exposes hooks for user-triggered events (like clicking or dragging an event). <br/> <br/></p>
<p>I decided to give it a try and utilize its hooks for user triggered events within our Rails application. This small effort resulted in a barebone Rails app that might provide a good base for your project which require calendar, scheduling or appointment features.  I called it fullcalendar_rails  and it is now available on <a href="http://github.com/vinsol/fullcalendar_rails">github</a> with a working demo at <a href="http://fullcalendar.vinsol.com">http://fullcalendar.vinsol.com</a>.<br/><br/></p>
<p>Feel free to give your valuable feedback. I hope you will find this useful. <br/><br/></p>
<p><b>Update:</b> On popular demand, I have added recurring events functionality with daily, weekly and monthly frequencies. It also allows for exceptions to recurring events including delete and edit features.</p>
<p><br/><br/></p>


<p>No related posts.</p>
<p>Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://vinsol.com/blog/2010/03/29/jquery-full-calendar-with-rails/feed/</wfw:commentRss>
		<slash:comments>25</slash:comments>
		</item>
		<item>
		<title>Ruby on Rails Caching And JavaScript Techniques</title>
		<link>http://vinsol.com/blog/2009/09/07/rails-caching-and-javascript-techniques/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=rails-caching-and-javascript-techniques</link>
		<comments>http://vinsol.com/blog/2009/09/07/rails-caching-and-javascript-techniques/#comments</comments>
		<pubDate>Mon, 07 Sep 2009 06:47:20 +0000</pubDate>
		<dc:creator>sid</dc:creator>
				<category><![CDATA[ajax]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[caching]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[ruby on rails]]></category>

		<guid isPermaLink="false">http://vinsol.com/blog/?p=704</guid>
		<description><![CDATA[Cross posted from darthsid
While implementing caching in a recent rails project I came across some typical caching issues. In a lot of pages the content is same for all users but certain components in them have user specific actions. As an example, I have a page listing all public messages that users have posted(similar to [...]


No related posts.

Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p>Cross posted from <a title="Sid's Blog" href="http://darthsid.com/blog">darthsid</a></p>
<p>While implementing caching in a recent rails project I came across some typical caching issues. In a lot of pages the content is same for all users but certain components in them have user specific actions. As an example, I have a page listing all public messages that users have posted(similar to the <a href="http://twitter.com/public_timeline">public timeline</a> in <a href="http://twitter.com">twitter</a>) but actions on those messages are user specific(eg: only owner or admin can delete a message). Also, most of these actions use ajax and the rails <a href="http://ryandaigle.com/articles/2007/9/24/what-s-new-in-edge-rails-better-cross-site-request-forging-prevention">authenticity token</a> in them also gets cached resulting in subsequent failures if the session changes. Another issue was that the timestamps in most pages is fuzzy and they become irrelevant if a page gets cached for too long. I could have created separate caches for each user but if the user base really grows managing the caches would become a nightmare and that would still not solve the authenticity token and the timestamp problem. The simplest solution was to use JavaScript, more specifically <a href="http://jquery.com">jQuery</a>.<br />
<span id="more-704"></span><br />
I have been a big fan of jQuery since I started using it about a year and a half ago and try to use it in all my projects. There is an excellent Rails plugin called <a href="http://ennerchi.com/projects/jrails">jRails</a> that replaces Prototype with jQuery and provides all the default Rails helpers for JavaScript making jQuery even more tempting to use. The examples I use below all use jQuery.</p>
<p><big><big><strong>1. Handling User Specific Components</strong></big></big></p>
<p>Taking the delete action as explained in the example above, the code in the cached view looks something like this:</p>
<pre class="brush: ruby;">
&amp;lt;% if logged_in? %&amp;gt;
&amp;lt;li class=&amp;quot;delete &amp;lt;%= 'only_' + (message.owner.login) + '_delete_allowed' %&amp;gt;&amp;quot;&amp;gt;
  &amp;lt;%= link_to_remote &amp;quot;Delete&amp;quot;,
    :url =&amp;gt; user_message_path(current_user, message)
    :method =&amp;gt; :delete,
    :confirm =&amp;gt; &amp;quot;Are you sure you wish to delete this message?&amp;quot;,
    :html =&amp;gt; { :title =&amp;gt; &amp;quot;Delete Post&amp;quot; } %&amp;gt;
&amp;lt;/li&amp;gt;
&amp;lt;% end %&amp;gt;
</pre>
<p>This will create an li element with class &#8220;delete&#8221; and &#8220;only_kratos_delete_allowed&#8221; if the username of the message owner is &#8220;kratos&#8221;</p>
<p>In the non-cached part of the view I have the following code:</p>
<pre class="brush: ruby;">
&amp;lt;% if logged_in? %&amp;gt;
  &amp;lt;% if current_user.is_admin? %&amp;gt;
    &amp;lt;%= javascript_tag &amp;quot;$(document).ready(function() { MessageView.removeInvalidDeteteButtons('only_#{current_user.login}_delete_allowed', 'true'); });&amp;quot; %&amp;gt;
  &amp;lt;% else %&amp;gt;
    &amp;lt;%= javascript_tag &amp;quot;$(document).ready(function() { MessageView.removeInvalidDeteteButtons('only_#{current_user.login}_delete_allowed'); });&amp;quot; %&amp;gt;
  &amp;lt;% end %&amp;gt;
&amp;lt;% end %&amp;gt;
</pre>
<p>If the current user is an admin I pass the JavaScript function an additional parameter.</p>
<p>In the application.js file I have the following code:</p>
<pre class="brush: jscript;">
var MessageView = {
  removeInvalidDeteteButtons: function(element_class, admin) {
    if (admin == undefined)
    {
      $('.delete').each(function() { if (!$(this).hasClass(element_class)) { $(this).remove(); } });
    }
  }
}
</pre>
<p>If the second parameter is passed(in the case of an admin) the function does nothing, else it iterates over all li elements with class &#8220;delete&#8221; and removes all elements that do not also have, in this case, the &#8220;only_kratos_delete_allowed&#8221; class.</p>
<p><big><big><strong>2. Handling Rails Authenticity Token</strong></big></big></p>
<p>This part describes how to take care of the authenticity token problem:</p>
<p>I added the following code to the layout:</p>
<pre class="brush: ruby;">
&amp;lt;%= javascript_tag &amp;quot;var AUTH_TOKEN = #{form_authenticity_token.inspect};&amp;quot; if protect_against_forgery? %&amp;gt;
</pre>
<p>This code creates a JavaScript variable named &#8220;AUTH_TOKEN&#8221; that contains the current authentication token. Since this section is not cached it always get the correct token.</p>
<p>Next I added the following code to application.js:</p>
<pre class="brush: jscript;">
$(document).ajaxSend(function(event, request, settings) {
  if (settings.type == 'get' || settings.type == 'GET' || typeof(AUTH_TOKEN) == &amp;quot;undefined&amp;quot;) return;
  var authTokenRegExp = /authenticity_token=\w{40}/
  settings.data = settings.data || &amp;quot;&amp;quot;;
  if (authTokenRegExp.test(settings.data))
  {
    settings.data=settings.data.replace(authTokenRegExp, &amp;quot;authenticity_token=&amp;quot; + encodeURIComponent(AUTH_TOKEN));
  }
  else
  {
    settings.data += (settings.data ? &amp;quot;&amp;amp;&amp;quot; : &amp;quot;&amp;quot;) + &amp;quot;authenticity_token=&amp;quot; + encodeURIComponent(AUTH_TOKEN);
  }
})
</pre>
<p>This code is a slight modification of the code posted <a href="http://henrik.nyh.se/2008/05/rails-authenticity-token-with-jquery">here</a>. <a href="http://docs.jquery.com/Ajax/ajaxSend">ajaxSend</a> is jQuery function that is executed before every ajax request is sent and I use it here to replace or append the authenticity token to the request, unless the request is GET or the AUTH_TOKEN variable is not defined.</p>
<p><big><big><strong>3. Handling Fuzzy Timestamps</strong></big></big></p>
<p>The code for timestamps in the cached view looks like this:</p>
<pre class="brush: ruby;">
&amp;lt;span&amp;gt;
  &amp;lt;%= process_message_body_timestamp(message) %&amp;gt;
&amp;lt;/span&amp;gt;
</pre>
<p>And the helper code is:</p>
<pre class="brush: ruby;">
def process_message_body_timestamp(message)
  link_to &amp;quot;#{message.created_at}&amp;quot;, show_message_url(message), :class =&amp;gt; &amp;quot;timestamps&amp;quot;
end
</pre>
<p>I put the following code in the layout(non-cached):</p>
<pre class="brush: ruby;">
&amp;lt;%= javascript_tag &amp;quot;$(document).ready(function() { CustomDate.datify(#{get_custom_date_arguments}) });&amp;quot; %&amp;gt;
</pre>
<p>The get_custom_date_arguments helper is defined in application helper and returns a string containing the current time arguments needed for the JavaScript function:</p>
<pre class="brush: ruby;">
def get_custom_date_arguments
  current_time = Time.zone.now
  &amp;quot;#{current_time.year},#{current_time.month-1},#{current_time.day},#{current_time.hour},#{current_time.min},#{current_time.sec}&amp;quot;
end
</pre>
<p>I put the following code in application.js:</p>
<pre class="brush: jscript;">
var CustomDate = {
  datify: function(current_utc_year,
                   current_utc_month,
                   current_utc_day,
                   current_utc_hour,
                   current_utc_minute,
                   current_utc_second) {
    $('.timestamps').each(function() {
      $(this).html(CustomDate.humane_date($(this).html(),
                                          current_utc_year,
                                          current_utc_month,
                                          current_utc_day,
                                          current_utc_hour,
                                          current_utc_minute,
                                          current_utc_second)).removeClass('timestamps')
    })
  },

  humane_date: function(date_str, current_utc_year, current_utc_month, current_utc_day, current_utc_hour, current_utc_minute, current_utc_second) {
    var time_formats = [
                        [60, 'less than a minute ago'],
                        [90, '1 minute'], // 60*1.5
                        [3600, 'minutes', 60], // 60*60, 60
                        [5400, '1 hour'], // 60*60*1.5
                        [86400, 'hours', 3600], // 60*60*24, 60*60
                        [129600, '1 day'], // 60*60*24*1.5
                        [604800, 'days', 86400], // 60*60*24*7, 60*60*24
                        [907200, '1 week'], // 60*60*24*7*1.5
                        [2628000, 'weeks', 604800], // 60*60*24*(365/12), 60*60*24*7
                        [3942000, '1 month'], // 60*60*24*(365/12)*1.5
                        [31536000, 'months', 2628000], // 60*60*24*365, 60*60*24*(365/12)
                        [47304000, '1 year'], // 60*60*24*365*1.5
                        [3153600000, 'years', 31536000], // 60*60*24*365*100, 60*60*24*365
                        [4730400000, '1 century'], // 60*60*24*365*100*1.5
                      ];

    var time = ('' + date_str).replace(/-/g,&amp;quot;/&amp;quot;).replace(/[TUTC]/g,&amp;quot; &amp;quot;),
        dt = new Date

    dt.setUTCFullYear(current_utc_year, current_utc_month, current_utc_day)
    dt.setUTCHours(current_utc_hour, current_utc_minute, current_utc_second)

    var seconds = ((dt - new Date(time) + (dt.getTimezoneOffset() * 60000)) / 1000),
        token = ' ago',
        prepend = '',
        i = 0,
        format;

    if (seconds &amp;lt; 0) {
      seconds = Math.abs(seconds);
      token = '';
      prepend = 'in ';
    }

    while (format = time_formats[i++]) {
      if (seconds &amp;lt; format[0]) {
        if (format.length == 2) {
          return (i&amp;gt;1?prepend:'') + format[1] + (i &amp;gt; 1 ? token : ''); // Conditional so we don't return Just Now Ago
        }
        else {
            return prepend + Math.round(seconds / format[2]) + ' ' + format[1] + (i &amp;gt; 1 ? token : '');
        }
      }
    }

    // overflow for centuries
    if(seconds &amp;gt; 4730400000) {
      return Math.round(seconds / 4730400000) + ' Centuries' + token;
    }

    return date_str;
  }
}
</pre>
<p>The datify function iterates over all timestamps(elements with class &#8220;timestamps&#8221;) and replaces them with fuzzy timestamps. The humane_date function(yanked from <a href="http://stackoverflow.com/questions/168924/how-to-render-contextual-difference-between-two-timestamps-in-javascript">here</a>) generates the actual fuzzy timestamps.</p>


<p>No related posts.</p>
<p>Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://vinsol.com/blog/2009/09/07/rails-caching-and-javascript-techniques/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>

