How to use Ajax in ruby on rails? - ruby

After reading several articles about Ajax in ROR, I am still confused about how to use Ajax!
There is a main/index.html and main_controller in my project. I want to fulfill the function described as below:
Once the link in the index.html is clicked, the RSS content will show up in the index. I have fulfill the function by jumping to another webpage. But I don't know how to use Ajax...
index
<h1>Listing Jobs</h1>
<table>
<tr>
<th>Source</th>
<th></th>
</tr>
<% #jobs.each do |job| %>
<tr>
<td><%= job.source %></td>
<td>
<%= link_to 'Show', #:controller=>'main', :action=>'show',
:id=>job.id,:remote=>true, "data-type"=>:json, :class=>'updateJob'%>
</td>
</tr>
<% end %>
</table>
<script type="text/javascript" charset="utf-8">
$(function(){
# $('#'+job.id).bind("click",function(){
# $('#showJob').append('Hi')
# })
$('#'+job.id).bind("ajax:success",function(data, status, xhr){
("<h1>hello</h1>").appendTo("#showJob")
})
})
</script>
show.html
<div id="showJob">
</div>
<table>
<tr>
<th>Source</th>
<th>Link</th>
</tr>
<% #feed.items.each do |item| %>
<tr>
<th><%= item.title %></th>
<th><%= item.link %></th>
</tr>
<% end %>
</table>
main_controller
require 'rss'
require 'rss/1.0'
require 'rss/2.0'
require 'open-uri'
class MainController < ApplicationController
#get /jobs
def index
#jobs=Job.all
respond_to do |format|
format.html # index.html.erb
format.json {render:json=>#jobs}
end
end
def welcome
#num_sources =Job.count
end
def show
job=Job.find(params[:id])
url=job.url
open(url) do |rss|
#feed = RSS::Parser.parse(rss)
end
respond_to do |format|
# format.html do
# render :partial=>'main/show'
# end
format.json {render :json=>#feed}
end
end
end

Instead of binding to the click event, add bindings for the ajax events that you want to handle. Typically, this would include the ajax:success event:
$(function(){
$('#'+job.id).on("ajax:success", function(data, status, xhr){
// do something with 'data' json object
});
});
A complete list of events can be found here.
To have the controller use the 'json' format when rendering, change your link to look like this:
<%= link_to 'Show', { :controller=>'main', :action=>'show', :id=>job.id },
:data => {:remote=>true, :type=>:json}, :class=>'updateJob'%>
Note that the hash that makes up the url (controller, action, id) needs to be passed in a separate hash from the other attributes to work properly. You can make this even simpler if you have your job set up as a resource in your routes.rb file:
<%= link_to 'Show', job, :data => {:remote=>true, :type=>:json}, :class=>'updateJob'%>

Related

Value is not submitting in using Rails ajax form

I want to store value in db using Rails ajax form but it is not storing anything.Please let me to know where i did the mistake and help me to resolve this issue.
I am explaining my code below.
users/index.html.ebr:
<script type="text/javascript">
$('form').submit(function() {
var valuesToSubmit = $(this).serialize();
console.log('hello')
$.ajax({
type: "POST",
url: $(this).attr('create'), //sumbits it to the given url of the form
data: valuesToSubmit,
dataType: "JSON" // you want a difference between normal and ajax-calls, and json is standard
}).success(function(json){
console.log("success", json);
});
return false; // prevents normal behaviour
});
</script>
<p><%= flash[:notice] %></p>
<%= form_for :user do |f| %>
<p>
Name : <%= f.text_field :name,placeholder:"Enter your name" %>
</p>
<p>
Email : <%= f.email_field :email,placeholder:"Enter your email" %>
</p>
<p>
Content : <%= f.text_field :content,placeholder:"Enter your content" %>
</p>
<p>
<%= f.text_field :submit,:onchange => "this.form.submit();" %>
</p>
<% end %>
<div id="sdf-puri" style="display:none" >
</div>
controller/users_controller.rb
class UsersController < ApplicationController
def index
#user=User.new
respond_to do |format|
format.html
format.js
end
end
def create
#user=User.new(params[:user])
if #user.save
flash[:notice]="user created"
end
end
end
create.js.erb
$("#sdf-puri").css("display", "block");
$("#sdf-puri").html("<%= escape_javascript (render 'table' ) %>");
$("#sdf-puri").slideDown(350);
create.html.erb
<%= render 'table' %>
_table.html.erb
<table>
<tr>
<th>Name :</th>
<th>Email :</th>
<th>Content :</th>
</tr>
<% #user.each do |user| %>
<tr>
<td><%= user.name %></td>
<td><%= user.email %></td>
<td><%= user.content %></td>
</tr>
<% end %>
</table>
After submit value should display in same index page.Please help me.
Rails has a built in Ajax system, on your form you need to add remote: true
form_for(#user, remote: true) do |f|
This tells rails to submit the form using Ajax under the hood... You don't need all of the script above the form
Your controller already correctly has the line:
responds_to js
So all you would do is have a create.js file in your views/user folder that handled your return Ajax stuff such as appending or fading etc
you need to add remote: true in form tag

Linking a link from ERB to the control file

I'm trying to make a sort part to my ruby erb list, so far it makes the list then i want a way to sort the list when the click "sort by date". I have no idea where to start?
I'm sure whether to use the href tag or what to use.
<table class="user_display">
<tr>
<th>Name</th>
<th>Date</th>
<th>Friends</th>
</tr>
<% #mentions.each do |name| %>
<tr>
<td><%=h name %></td>
<td><%=h date %></td>
<td><%=h friends %></td>
</tr>
<% end %>
</table>
this isn't the real code but it follows the same ideas with some names changed.
so How do I have a button or link that when they click it reorders the array?
i feel like i should pass something along the lines of
<input class="order" type="button" name="date" value="<%=h params[:orderdate] %>"/>
is this the right idea, if so how do I link to controller file? which has
get '/list' do
#mentions = array_of_names
erb :list
end
any ideas?
Try to add this to the view:
<%= link_to 'Order by date', sort_mentions_path(:order_type => 'date'), :class => 'btn' %>
<%= link_to 'Order by name', sort_mentions_path(:order_type => 'name'), :class => 'btn' %>
In the controller could be something like this:
def sort
if( params[:order_type] == 'name')
#mentions = Mention.order('name')
elsif ( params[:order_type] == 'date')
#mentions = Mention.order('date')
else
#mentions = Mention.all
end
respond_to do |format|
format.html { }
format.json { render json: #mentions }
end
end (Remember to add sort.html.erb with the list view)
And the route:
resources :mentions do
collection do
get 'sort'
end
end
This will put in #mentions the array ordered by date if you have the Object 'Mention':
#mentions = Mention.order(:date)
You don't need to pass any parameter from the view, you can manage the order in the controller

Database values are not showing inside the table while using Ajax in Rails 3

I want to display the database values inside the table using Ajax in Rails.bou i got the following error.
Error:
Template is missing
Missing template users/search, application/search with {:locale=>[:en], :formats=>[:html], :handlers=>[:erb, :builder, :coffee]}. Searched in: * "c:/Site/demo2/app/views"
I also added the search.html.erb i removed the error but got the blank page.
Please check my below codes.
views/users/index.html.erb
<%= form_for :user ,:url => {:action => "search" }, remote: true do |f| %>
<div class="input-group bmargindiv1 col-md-12"> <span class="input-group-addon text-left">Receipt No. Scan :</span>
<%= f.text_field :receipt,:class => "form-control",placeholder:"user number",:onchange => "this.form.submit();" %>
</div>
<% end %>
<div id="search-output-table">
<%= render partial: "search_output_table", locales: {user: #user} %>
</div>
controller/users_controller.rb
class UsersController < ApplicationController
def index
#user=User.new
end
def search
#user = User.find_by_receipt(params[:user][:receipt])
end
end
views/users/_search.js.erb
$("#search-output-table").html("<%= escape_javascript( render(partial: "search_output_table") ) %>");
views/users/_search_output_table.html.erb
<table>
<tr>
<th>User Name</th>
<th>User Email</th>
<th>User Number</th>
</tr>
<tr>
<td><%= #user.name %></td>
<td><%= #user.email %></td>
<td><%= #user.receipt %></td>
</tr>
</table>
I also want remove onchange event and as soon as the value will fill inside text field the action will execute without reload the page as well as the table value will display(initially the table should remain disable/hide).Please help me to resolve this error and add this new scenario.
Well, on request to UsersController#search Rails will by default render app/views/users/search.html.erb, which I assume is empty.
You probably just need to rename views/users/_search.js.erb to views/users/search.js.erb and add following to the controller
def search
#user = User.find_by_receipt(params[:user][:receipt])
respond_to do |format|
format.js
end
end
Also make sure you're passing in #user to the search_output_table template. Like this
render partial: 'search_output_table', locals: {user: #user}
And in 'search_output_table' you should use just user instead of #user.

Rails 3 Ajax Cannot get newly created record to append at bottom of existing table

On my index page I return a table of query results using Ajax. I having successfully created a new record using Ajax too. My problem is trying to get that new record immediately appended to the table of query results. I have seen Railscast 136 and cannot get it to work, maybe because I'm using Ruby 1.8.7.
Here is my index method, from the lookup controller that returns the initial results
def index
#lookuprows = Lookup.return_lookup_rows(:pubyear, :codetype)
respond_to do |format|
format.html
format.js
end
end
Here is the index.js.erb ( I did get this from Railscast 136, except Ryan had "<%= j render(#lookuprows) %>". I could not get this to work. I kept on getting a missing partial error. The only way I could get it to work is by making a _lkupshow.html.erb partial).
$("#lkupresultarea").html("<%= j render("lkupshow") %>
I have the ajax select working, here is some of the code from lkupshow partial that displays the records
<table class="lkupdata">
<tbody class="lkuptbody">
<% #lookuprows.each do |lkup| %>
<tr>
<td><input value="<%= lkup.codevalue %>" /></td>
<td><input value="<%= lkup.parameters %>" /></td>
<td><input value="<%= lkup.remark %>" /></td>
</tr>
<% end %>
</tbody>
</table>
In the same partial, I have a form above it
<div class="lkupnewdiv">
<%= form_tag(lkupcreate_path, :remote => "true") do %>
<table>
<tr>
<td><%= text_field(:lookup, :codevalue) %></td>
<td><%= text_field(:lookup, :parameters) %></td>
<td><%= text_field(:lookup, :remark) %></td>
</tr>
<tr><td><%= submit_tag("Submit", :id=> "lkupsubmit") %></td></tr>
</table>
<% end %>
</div>
Here is the create method from the Lookup controller, the save works
def create
#lookup = Lookup.new
#lookup.codevalue = params[:lookup][:codevalue]
#lookup.parameters = params[:lookup][:parameters]
#lookup.remark = params[:lookup][:remark]
#lookup.save
respond_to do |format|
format.html
format.js
end
end
And finally, here is the create.js.erb, i get the same "missing partial" error here too.
$(".lkupnewdiv").hide();
$(".lkupdata > tbody:last").append('<%= j render(#lookup) %>');
So when I add my new record it does save, but there's nothing to indicate that from the form in the browser. Could I maybe change my create method to this?
def create
#lookup = Lookup.new
#lookup.codevalue = params[:lookup][:codevalue]
#lookup.parameters = params[:lookup][:parameters]
#lookup.remark = params[:lookup][:remark]
#lookup.save
# Call the whole query again? pubyear is one of the variables, just didnt feel like
# typing them all in
#lookuprows = Lookup.return_lookup_rows(:pubyear, :codetype)
respond_to do |format|
format.html
# Shouldnt the #lookuprows be accessible with the path below?
format.js { redirect_to lkupshow_path }
end
end
Since I cannot get past the "missing partial" error from the create.js.erb, I am looking for other solutions. Any help would be appreciated. Thanks!

XML Parsing Error: no element found when using rjs in rails

I implemented destroy functionality using rjs template in rails. i got an error "XML Parsing Error: no element found" when destroy one record from database. is this right my coding?
I used the following versions ruby and rails:
Ruby version: 1.8.7
Rails Version: 2.3.8
Controller file:
def destroy
begin
#task = Task.find(params[:id])
#task.destroy
respond_to do |format|
#format.html { redirect_to(tasks_url) }
format.js
format.xml { head :ok }
end
rescue Exception => e
puts e
end
end
partial template file _task.html.erb:
<tr id="<%= dom_id(task) %>">
<td><%= task.name %></td>
<td><%= task.note %></td>
<td><%= task.priority %></td>
<td><%= link_to 'Show', task %></td>
<td><%= link_to 'Edit', edit_task_path(task) %></td>
<td>
<%= link_to 'Destroy', task, :confirm => 'Are you sure?', :method =>:delete,:remote => :true %>
index.rhtml file:
<div id='newform'>
<% form_for([#task, Task.new]) do |f| %>
<div>
<%= f.label 'Add a new task: ' %>
<%= f.text_field :name %>
</div>
<div>
<%= f.submit %>
</div>
<% end %>
</div>
<table id="alltasks">
<tr id="tablehead">
<th>Name</th>
<th>Note</th>
<th>Priority</th>
<th></th>
<th></th>
<th></th>
</tr>
<%= render #tasks %>
<!-- expanded: render :partial => "task", :collection => #tasks -->
</table>
<br />
<%= link_to 'New Task', new_task_path %>
destroy.js.rjs file:
page.alert('Hi')
The problem is that the xml format is getting requested from your destroy action, not the js format, and something is trying to parse the empty xml response produced by the format.xml { head :ok } line in the controller. It used to be that you could get away with the empty xml response, but it also looks like you're using unobtrusive javascript, and something somewhere in ujs tries to parse it.
One potential solution is to make a destroy.xml.builder view that produces a simple response, and change your controller action to read format.xml { render :layout => false } or something similar. You can also do some fun things with changing the data type your link is requesting, but I'd recommend avoiding that unless you really want to do something with your js response in destroy.js.rjs.

Resources