Showing posts with label ajax. Show all posts
Showing posts with label ajax. Show all posts

Wednesday, June 20, 2012

Ajax request via javascript

Hello Rubies,
      Have you tried AJAX request via javascript? Lets see the eg.

<script type="text/javascript">

  // Ajax without update parameter:
  function ajax_request(id){
    window._token = '<%= form_authenticity_token %>';
    var url = '/controller/action';
    var pars = 'id=' + id + '&authenticity_token=' + window._token;
    var myAjax = new Ajax.Request(url, {method: 'post', parameters: pars, onFailure: showFailure(), onSuccess: showSuccess() });
  }

  // Ajax with update parameter:
  function ajax_update_request(id){
    window._token = '<%= form_authenticity_token %>';
    var url = '/controller/action';
    var pars = 'id=' + id + '&authenticity_token=' + window._token;
    var myAjax = new Ajax.Updater('update_div_id', url, {method: 'get', parameters: pars, onFailure: showFailure(), onSuccess: showSuccess()});
  }

  function showSuccess(){
  }

  function showFailure(){
  }

</script>

Sunday, November 20, 2011

Allow ajax upload

Hello Rubies,
          Do you know how to upload the file through ajax? Last time i was juggling for ajax upload. There is some patch which i have used to allow ajax upload with rails 2.3.x. Follow below instruction to implement it.

Lets, consider the scenario. Where we have content page which has file(.pdf) upload and content area portion.

new.rhtml

<%= form_remote_tag(:url => {:controller => 'contents', :action => 'create'}, :html => { :multipart => true })%>     
    <p id='error_msgs'> </p>
    <p> Content: <%= text_area 'content', 'body' %> </p>
    <p> PDF: <%= file_column_field 'content', 'pdf_path' %> </p>
     <p> <%= submit_tag('Create') %> </p>
</form>
This form allow us to create content along with pdf upload through ajax.

Now want to add some basic validation for file?

class Content < ActiveRecord::Base
   validates_file_format_of :pdf_path , :in => ["pdf"]
   file_column(:pdf_path, :root_path => "#{RAILS_ROOT}/PDFs", :fix_file_extensions => nil)
end

Above we added the validation for file which must be in .pdf format only and store in our application's PDFs directory. You have to assume that your using file column here otherwise you can use normal file_field as well.

In controller of contents we have method called 'create' which need to enhance.

class ContentsController < ApplicationController
   
  def create
     @content = Content.new(params[:content])   
     responds_to_parent do
        if @content.save     
           render :update do |page|
              flash[:notice] = "content created successfully"
              page.redirect_to contents_url
           end
        else
           render :update do |page|
             page.replace_html "error_msgs", "#{error_messages_for :content}"
           end
        end
     end 
  end

end

Here you observed something ?.. we have used the responds_to_parent instead of respond_to block.

Now you guys are wondering about method 'responds_to_parent'. correct?
rails_responds_to_parent  is the method of gem 'rails_responds_to_parent t'. Now install that via
gem install rails_responds_to_parent

For the ajax support we have to add the patch called 'remote_upload' in lib folder of rails application

lib/remote_upload.rb

module ActionView
  module Helpers
    module PrototypeHelper
      alias_method :form_remote_tag_old, :form_remote_tag
      def form_remote_tag(options = {})
         if options[:html] && options[:html][:multipart]     
           uid = "a#{Time.now.to_f.hash}"                               
          <<-STR   
            <iframe name="#{uid}" id="#{uid}" src="about:blank" style="position:absolute;left:-100px;width:0px;height:0px;border:0px"></iframe>
            <form method="post" action="#{url_for options[:url].update({:iframe_remote => true})}" enctype="multipart/form-data" target="#{uid}" #{%(onsubmit="#{options[:loading]}") if options[:loading]}>
           STR
         else
            form_remote_tag_old(options)
         end
      end                            
    end
  end
end

This code will override the prototype's form_remote_tag method and allow iframe support.

Now, we have to include below lines in config/environment.rb to allow access of remote_upload and responds_to_parent

require 'remote_upload.rb'
require 'rails_responds_to_parent'

See our work completed. Now we will freely upload the file through ajax. Find interesting?
If you have any suggestion or query then post the comment.

to get the gem source of rails_responds_to_parent

Wednesday, September 21, 2011

Ajax to allow file download

Hello Guys,
          Yesterday i was trying to download the attachment during ajax request. So i find out the some simple way which might help you people.

Below is the controller code snippet:

def download
   file_path = "#{RAILS_ROOT}/test.txt"
   respond_to do |format|
      format.js{
        render :update do |page|
          page.redirect_to :action =>'ajax_download' ,:file => file_path        
        end
      } 
   end
end

def ajax_download
    send_file params[:file]
end

In view i have link for download as:

<%= link_to_remote "Download", :url => {:controller => "test", :action => "download"}%>

Here my parent request is download and than it internally invoke ajax_download action to download attachment.

Friday, September 2, 2011

Ajax based pagination

Hello Guys,
          There are different plugin and gem available for pagination. I would like to prefer will_paginate gem for pagination in rails.

First of all we have to add mislav-will_paginate gem via
sudo gem install mislav-will_paginate
 
or specify in your environment.rb

config.gem "mislav-will_paginate", :lib => "will_paginate", :source => "http://gems.github.com"

in your pagination.js add the javascript code to support ajax based pagination

document.observe("dom:loaded", function() {
  var container = $(document.body)

  if (container) {
    # uncomment below code to load spinner
    //var img = new Image
    //img.src = '/images/spinner.jpeg'  
    function createSpinner() {
      //return new Element('img', { src: img.src, 'class': 'spinner' })
    }

    container.observe('click', function(e) {
      var el = e.element()
      if (el.match('.pagination.ajax a')) {
          el.up('.pagination.ajax').insert(createSpinner())
//      if (el.match('.pagination a')) {
//        el.up('.pagination').insert(createSpinner())
        new Ajax.Request(el.href, { method: 'get' })
        e.stop()
      }
    })
  }
})

Now you have to include pagination.js in your view through
<%= javascript_include_tag 'pagination' %>

Lets we implement pagination on index method of users controller.

users_controller.rb

def index
  @users = User.all.paginate(:per_page => 20,:page => params[:page])
  respond_to do |format|
    format.html
    format.js {
      render :update do |page|       
        page.replace_html 'user_list', :partial => 'user_list', :locals => {:users => @users}
      end
    }
    end
end

Now move towards the views. here we have 3 views which listed below.

i) index.html.erb
   <h1> Listing Users </h1>
   <table>
     <tr>
       <th> Name </th>
       <th> Surname </th>
     </tr>
     <tbody id='user_list'>
        <%= render :partial =>'user_list', :locals => {:users => @users} %>
     </tbody>
   </table>

ii) _user_list.html.erb

  <% users.each do |user| %>
    <tr>
      <td> <%= user.name %> </td>
      <td> <%= user.surname %> </td>
    </tr>
  <% end %>
  <tr>
   <td colspan="2"> 
      <%= will_paginate users, :class => 'pagination ajax', :id=>"flickr_pagination"%>
   </td>
  </tr>

iii) index.js.erb
      $("#user_list").html("<%= escape_javascript(render :partial => "user_list") %>");

This is the file which actually play with ajax during pagination.

Now add pagination.css in style sheet for better formatting

#flickr_pagination {
  text-align: center;
  padding: 0.3em 0.3em 0.3em 0.3em;
  clear:both;
  margin:5px 0px 5px 0px;
  }
#flickr_pagination * {
  font: 10pt Arial,Helvetica,Geneva,sans-serif;
  } 
#flickr_pagination a, #flickr_pagination span {
  padding: 0.2em 0.5em; 
  }
#flickr_pagination span.disabled {
  color: #AAA
AAA;
  }
#flickr_pagination span.current {
  font-weight: bold;
  color: #898989; 
  }
#flickr_pagination a {
  border: 1px solid #DDDDDD;
  color: #0072BC;
  text-decoration: none; 
  }
#flickr_pagination a:hover, #flickr_pagination a:focus {
  border-color: #DDDDDD;
  background: #898989;
  color: #FFFFFF; 
  }
#flickr_pagination .page_info {
  color: #aaaaaa;
  padding: 0.8em 0em 0em 0em; 
  }
#flickr_pagination .prev_page, #flickr_pagination .next_page {
  border-width: 1px; 
  }
#flickr_pagination .prev_page {
  margin: 0em 1em 0em 0em; 
  }
#flickr_pagination .next_page {
  margin: 0em 0em 0em 1em; 
  }

you have to include pagination.css in your view through
<%= stylesheet_link_tag 'pagination' %>

Finally we done with ajax pagination. If you want different styles for pagination then just replace the style sheet. http://woork.blogspot.com/2008/03/perfect-pagination-style-using-css.html

Hope this post will help you to implement ajax pagination in rails.