Given that I have the routes.
root :to => 'pessoas#index'
post '/pessoas' => 'pessoas#create'
And my view app/view/pessoas/index.haml has the following view code. (Submit here will post to pessoas#create)
= form_tag "/pessoas", :method => :post, :remote => true, :id => "participe" do
...
= button_tag "Sign up", :class => "envia"
And my create.js.erb view is.
$('#user-feedback').html('<%= #message %>');
And the controller code simply saves the model.
def create
#pessoa = Pessoa.new(params[:cliente])
if #pessoa.save
#message = "Success"
else
#message = "Failure"
end
respond_to do |format|
format.js
end
end
Then I go to the root path /
And I fill the form and click on submit.
Then the element p#user-feedback haven't been changed. Why?
I notice in app's log: that the request was done right and the jquery also but it render at /pessoas response but not at current view (index).
What can I do? Or should I just forget about this and make this with $.ajax way?
I want a way to provide feedback to the users.
Related
I have dropdown list using select_tag and I have button near it.
I have following requirements:
1) on click of submit button it should go to books#show action
2) Then in show action I retrieve the selected book from dropdown list
3) The show method should show details of book that I would retrieve from database
i.e,the same page should update with this book details.
However,I am unable to perform none of this.
In my view:
<%= form_tag books_path do |f|%>
<%= label_tag "select book" %>
<%= select_tag "selectbook", options_from_collection_for_select(#bid,"book_id","book_id"), :prompt => "Select book",:class => 'cmbbook' %>
<%= submit_tag "view ...", :disable_with => "Please wait." ,:action => "show"%>
<%end%>
In my controller
if(params[:selectbook])
#books = Book.where("book_id = ?",params[:selectbook])
else
#books = Book.all
end
#bid= Books.select("book_id").uniq;
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => #books }
format.json { render json: #books }
end
The submit method calling action create instead of show and I also wish the page autoupdate with new book data.
First of all, you should specify controller and action for the form, like this
form_tag( {:controller => 'your_controller', :action => "show"} )
For autoupdating page you should read rails doc
I have found what to do:
I have to write a method in javascript that calls getJson() method to appropriate controller and action and again update view using javascript.Thus,using ajax javascript problem is solved.However,I wish I can do same with pure ruby code.
I've some difficulty in determining any way to update my objects as a group. I have an Alert model which has some alerts for the user. I'd like to provide a way to update them in bulk, as I've noticed that I often want to. I just don't know Rails well enough to know what 'the Rails way' would be.
My controller:
class AlertsController < ApplicationController
def index
#alerts = Alert.all(show: true)
end
def destroy
alert = Alert.get(params[:id])
## I lied, I'm not really deleting things, just hiding them from showing
alert.update(show: false) if alert
respond_to do |format|
format.js { render :nothing => true }
end
end
I've been using this code in my *.html.haml view to create the delete link for each individual alert:
- #alerts.each do |alert|
%span{ :class => 'description' }=alert.description
= link_to "Destroy", alert, :confirm => "Are you sure", :method => :delete, :remote => :true
What I want to have is a link on my index page Delete All which I could use to hide(update) all of the alerts. I've been attempting this with a destroy_all method for my controller, but I felt like it wasn't quite the right approach, as I didn't know how to link to something like that. Thank you for pointing me in the right direction.
Here is the destroy_all method I'd hacked together, for reference.
def destroy_all
#alerts.each do |alert|
alert.update(show: false) if alert
respond_to do |format|
format.js {render :nothing => true}
end
end
end
I don't know how you have routed to this controller but I would probably do something like this:
#routes.rb
resources :alerts do
delete :remove_all, :on => :collection
end
This will create a route looking like /alerts/remove_all which can only be called through the DELETE protocol. By specifying :collection it tells the routing the this route is not a sub route to one specific Alert so no :id is included.
Then the controller action could probably look something like this:
def remove_all
Alert.update_all({ show: false }, { show: true })
respond_to do |format|
format.js {render :nothing => true}
end
end
The update_all function will make sure that there is only one database update instead of one for each alert that is to be removed. The first argument is a hash containing the updates and the second argument is a hash with the conditions for which records are to be updated.
And from the view you should be able to link to the action like this:
= link_to "Remove All", remove_all_alerts_path, :confirm => "Are you sure", :method => :delete, :remote => :true
remove_all_alerts_path is a path helper that is automatically generated when you use the above syntax in routes.rb
I'm working on rails 3 with link_to remote option.
This is my code structure.
View/punch/report.html.erb :
<%= link_to 'Punch report', punchreport_punch_index_path, :remote => true%>
<div id="punchform"> </div>
View/punch/punchreport.js.erb :
$("#punchform").html("<%= escape_javascript(render(:partial => "reportform"))%>");
and created a form inside
View/punch/_reportform.html.erb
and controller :
controller/punch_controller.rb
def report
end
def punchreport
respond_to do |format|
format.html { render report_punch_index_path }
format.js
end
end
note : punchreport_punch_index_path : /punch/punchreport
report_punch_index_path : /punch/report
I don get the ajax request working. instead of that, it redirects the page.
Any help
Thanks in advance
Sounds like your :remote => true is not being handled by an unobstrusive javascript event handler...
Do you have something called jquery-rails in your project? it should set a handler on "data-remote" attribute. Can you find it and post back what you have there?
I am using Ruby on Rails 3 and I would like to change its conventional behavior on posting a form in order to post from a signup action to the create action instead that from the new action. That is, I would like to use the signup action instead of the (conventional) new action in my User controller and trigger the create action to save my model data that contains nested resources.
In my /config/routes.rb file I have:
resources :users do
collection do
get 'signup'
end
resource :profile
end
In my /app/controllers/users_controller.rb I have
class UsersController < ApplicationController
def signup
#signup_user = User.new(params[:user])
#signup_user.build_profile # NOTE: Nested resource
...
end
def create
...
#signup_user.save
respond_to do |format|
format.html { render :action => :signup } # signup.html.erb
end
end
end
In my /app/views/users/signup.html.erb file I have
<%= form_for #signup_user do |f| %>
...
<% end %>
My problem is that if I submit the above form, I will be redirected to the index action of the user controller and not to the create action I expect. It seams that the form posts only to the index action.
How can I solve the problem?
I tryed to use the following
<%= form_for( :user, #signup_user, :url => { :controller => "users", :action => "create" }, :html => { :method => :post } do |f| %>
but I have still the problem: I am redirected to the index action.
SOLUTION
The problem did seam to be in the routers.rb. The correct code was
resources :users do
collection do
get 'signup'
post 'create'
end
resource :profile
end
Using rails3 and prototype (rails.js)
I have a simple list of products with edit and delete links as images.
When deleting a product, the list is not updated. Refreshing the page shows that the product has indeed been deleted.
/app/views/products/list.rhtml
<div id="product_list">
<%= render :partial => 'list' %>
</div>
/app/views/products/_list.rhtml
<%= link_to image_tag("delete.png"), { :controller => 'products', :action => 'destroy', :id => product }, :method => :delete, :confirm => "Are you sure?", :remote => true %>
/app/controllers/products.rb
def destroy
Product.find(params[:id]).destroy
#products = Product.all
end
/app/views/products/destroy.rjs (not sure what to do with that...)
$(document).ready(function() {
$("#product_list").html("<%= escape_javascript( render(:partial => "list") ) %>");
});
So the remote link seems to work fine.
I'm not sure how to use the ajax callback to update #product_list
I tried to put the following in the head of the page:
$(document).ready(function(){
$('#product_list').bind("ajax:success", function(evt, data, status, xhr){
alert('hello');
})
});
But it's not executed (that's probably not a valid code for prototype) and I wouldn't know anyway what code to put inside so that my list gets updated after destroying a product
Any help (other than "use jQuery") is greatly appreciated!
EDIT: Here is the server log for the delete action (after I moved the javascript above to destroy.js.erb)
Started POST "/products/destroy/3" for 127.0.0.1 at .....
Processing by ProductsController#destroy as JS
Parameters: {"_"=>"", "id"=>"3"}
[1m[36mProduct Load (0.0ms)[0m [1mSELECT `products`.* FROM `products` WHERE (`products`.`id` = 3) LIMIT 1[0m
[1m[35mSQL (0.0ms)[0m BEGIN
[1m[36mSQL (0.0ms)[0m [1mDELETE FROM `products` WHERE (`products`.`id` = 3)[0m
[1m[35mSQL (78.1ms)[0m COMMIT
[1m[36mProduct Load (0.0ms)[0m [1mSELECT `products`.* FROM `products`[0m
Rendered products/destroy.js.erb within layouts/standard (31.2ms)
Completed 200 OK in 312ms (Views: 62.5ms | ActiveRecord: 78.1ms)
Processing by ProductsController#destroy as JS so the remote link works
[36mProduct Load (0.0ms)[0m [1mSELECT products. FROM products* The #products = Product.all is executed
Rendered products/destroy.js.erb within layouts/standard the javascript fie is rendered
So now I guess it's a problem with the javascript code:
$(document).ready(function() {
$("#product_list").html("<%= escape_javascript( render(:partial => "list") ) %>");
});
Is that kind of code supported by prototype? I don't use jQuery...
Found the answer on my own:
/app/controllers/products.rb
def destroy
Product.find(params[:id]).destroy
#products = Product.all
respond_to do |format|
format.js { render :layout=>false }
end
end
/app/views/products/destroy.js.erb
$("product_list").update("<%= escape_javascript(render(:partial => "list")) %>");
Why is there NO tutorial, code example or anything clear about the ajax thingy in rails3?
I had to use code parts from 5 different blogs, forums and casts, and mix them all together until I find the right combination... sigh
on repecmps lines,
just insert :content_type to represent part of content downloaded, like this:
format.js { render :layout=>false, :content_type => 'application/javascript' }
with complete part of repecmps responses:
def destroy
Product.find(params[:id]).destroy
#products = Product.all
respond_to do |format|
format.js { render :layout=>false, :content_type => 'application/javascript' }
end
end
/app/views/products/destroy.js.erb:
$("product_list").html("<%= escape_javascript(render(:partial => "list")) %>");
and, I found this to night.
I think your destroy action is doing too much, as it is destroying the product and list all the products. You could do something like:
/app/controllers/products.rb
class ProductsController < ApplicationController
respond_to :html, :js
def destroy
#product_id = params[:id]
Product.find(#product_id).destroy
respond_with do |format|
format.html { redirect_to posts_path }
end
end
end
/app/views/products/destroy.js.erb
$("#product_<%= #product_id %>").remove()
As long as your product element in the index uses something like dom_id, here's an example:
<ul id="products">
<% #products.each do |product|
<li id=<%= dom_id product %>>...</li>
<% end %>
</ul>
This way your destroy action will only destroy the intended product, and if the client has no JS it fallback the HTML request which will redirect to the products index which will be updated accordingly.
Hum... I'm going to try to help you.
Are you sure after clicking on the delete link, the request is handled as JS ?
Check on the log.
Is you file "app/views/products/destroy.rjs" is rendered ?
Rjs doesn't exist anymore in rails3. The new name is UJS.
Try to rename the file to destroy.js.{haml or erb}
Is it better ?