Never been to CodeSnippets before?

Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world (or not, you can keep them private!)

Ajax link_to_remote replace with spinner on click

This combination of CSS and prototype allows you to swap out the text with a spinner element, then back when loading is complete.

CSS

div.loading {
	background: url(/images/dots-white.gif) no-repeat 8px 6px;
	text-indent: -999px;
}


RHTML
<div id="lc" class="">
<%= link_to_remote 'toggle action', {
	:url => toggle_showall_new_recipe_path, 
	:method => :get,
	:before => "Element.addClassName('lc', 'loading')",
	:complete => "Element.removeClassName('lc', 'loading')"}, 
	:class => 'loading xhr', 
	:id => 'xhr-link' %>
</div>


Upon link click, the loading class will be added, moving the text off the window, effectively hiding it, while showing the background (not background-image). When XHR call is complete, simply remove the class and you're back to normal display properties.

Multiple updates to calling page in AJAX call

Uses Rails' .rjs template to form multiple update calls, server side, that will update the calling page with the included javascript.

Example:

def original_control_handler
 [misc methods and other things]
 [done normally in this controller]
 render :update do |page|
  page.replace_html 'calling_element_id', :partial => 'updated_template'
  page.helper 'helper_id', :helper_options => 'go here'
 end
end


Without rjs templates, you would have to write complex javascript by hand to update multiple elements on the calling page after returning from an XMLHTTPREQUEST (XHR) request. This allows you to avoid that, and do it all server side.

You can also place the update calls into an actual view templates instead of in the controller. Just put the contents of the update block into app/views/[controller]/original_control_handler

To replace simple tag contents, just provide a string of what to replace it with
 ...
 page.replace_html 'element_to_update', "this string goes in element"


Or replace the entire tag itself.
 page.replace 'element2_to_update', 
  (link_to_remote "link_text", {:url => dest, :method => :get, :id => 'element2_to_update')



Building :with querystring values in AJAX remote_function call

To build the string with multiple values, you must end it with an '=' char.

example:
To get this
?chapter=9&sort_by=created_at&sort_dir=desc


You need this
:with => "'chapter='+ encodeURIComponent(value)+'&sort_by=#{@sort_by}&sort_dir=#{@sort_dir}&='", :update => 'list_items'


Explained at: http://codefluency.com/2006/6/2/rails-views-using-the-with-option

AJAX link submit of form

Submit a form using a link, which itself shows different text depending on whether a database item exists or not.

Place this in .rhtml file (or layout file for site-wide coverage)
<%= javascript_include_tag "prototype" %>


Creates a link that fires a javascript method.
Method is created by remote_function.
Form.Serialize processes the entire form contents into a string so that receiving page is none the wiser.
Giving link an id ('follow_anchor') and asking remote_function to update the same id, allows us to dynamically change the innerHTML of the link. On the target side, have the method (create in this case) render text that will be used as the new innerHTML of this link.
<%= link_to_function @toggle_text, remote_function(:url => watch_lists_path, :method => :post, :with => "Form.serialize('watch_form')", :update => 'follow_anchor'), :id => 'follow_anchor' %>


  def create
    @watch_list = WatchList.new(params[:watch_list])

    if @watch_list.toggle
      render(:text => @watch_list.toggle_text)
    else
      render(:text => 'We couldn''t add this book to your Watch List. Please contact us for help.')
    end
  end




Load javascript function from returned ajax HTML

Problem - calling a function in <script> tags from dynamic ajax results does not get executed by the browser

Resolution - make a pixel image and call the function with the onload event in the image

<img src="some_image.jpg" onload="someFunction();">

Radio button with observer field

This is a clip of a radio button that updates a field with ajax on changes.

<%= radio_button_tag "payment_method_token", pm.token, (@payment_method_token == pm.token ? true : false), {:onchange => remote_function( 	:with => "'payment_method_token='+this.value", :url => {:action => 'load_payment_method' } )}%>
</TD>
<TD nowrap><B><%=pm.name%></B></TD>
<TD><%=pm.description%></TD>
</TR>
<%}%>
<% observe_field('payment_method_token', :frequency => 0.5,
                         :with => "payment_method_token",
                         :url => { :action => 'load_payment_method' }) 
%>

ajax_request? method to XHR detection

A oneline helper I put in all of my apps. Looks for HTTP headers that signal you're being called via an XmlHttpRequest. I use it for instant degradable AJAX by rendering a template if it's as usual but just rendering a partial if they just want that part!

  def ajax_request?
    request.env['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest' || params[:ajax]  # params[:ajax] for safe-keeping, FIXME if it works w/ all browsers
  end

Link to Remote Tag

Tag for creating ajax callback links

<%= link_to_remote( "click here",
                         :update => "specific_div_block",
                         :url =>{ :action => :action_name }) %>

CSS live edit with AJAX and rails !!!

(part of zena)

Using the helper <%= css_edit('style.css') %> shows two buttons to start/stop the css live update

Usage (on your local machine) :
0. open the web page where you inserted <%= css_edit('style.css') %> (replace style.css with your own stylesheets name)
1. click start on the web page
2. open your great editor
3. edit 'style.css'
4. save the file
5 MAGIC ! the web page is updated

# CONTROLLER (version but could be anything else)
  def css_preview
    file = params[:css].gsub('..','')
    path = File.join(RAILS_ROOT, 'public', 'stylesheets', file)
    if File.exists?(path)
      if session[:css] && session[:css] == File.stat(path).mtime
        render :nothing=>true
      else
        session[:css] = File.stat(path).mtime
        @css = File.read(path)
      end
    else
      render :nothing=>true
    end
  end

# HELPER :
  def css_edit(css_file = 'zen.css')
    str = <<ENDTXT
    <div id='css_edit'>
      <div id='css' onClick='cssUpdate()'></div>
      <script type="text/javascript">
      var c=0
      var t
      function timedCount()
      {
        if (c == '#'){
          c = '_'
        } else {
          c = '#'
        }
        document.getElementById('css_counter').innerHTML=c
        new Ajax.Request('/version/css_preview', {asynchronous:true, evalScripts:true, parameters:'css=#{css_file}'});
        t=setTimeout("timedCount()",2000)
      }

      function stopCount()
      {
        clearTimeout(t)
      }

      </script>
      <form>
        <input type="button" value="Start CSS" onClick="timedCount()">
        <input type="button" value="Stop  CSS" onClick="stopCount()">
        <span id='css_counter'></span>
      </form>
    </div>
    
ENDTXT
  end

# RJS template 'css_preview.rjs'
page.replace_html    "css", "<style>#{@css}</style>"

Displaying ActiveRecord validation errors from AJAX requests

I haven’t been able to find anything built into Rails to present errors from model validation when a request is sent via AJAX.

So I came up with this handly little hack, which I’ve put in my application.rb file.

def render_javascript_alert_for_errors_on(object)
  errors = object.errors.full_messages
  alert_text = errors.collect { |error| '-' + error }.join("\n")
  render :update do |page|
    page.alert alert_text
  end
end


This takes the object and displays a nicely-formatted version of all the errors on that object, taking advantage of inline RJS to render the javascript to create an alert().

It works perfectly, but it still feels a little “hacky” to me. Any better ideas?