Ruby render partial on form submit on same page - ruby

I am trying to render a partial that I made on top of the current page after a form submit. This should happen in the controller's create method, but I can't seem to figure out if this can be done in Ruby, or if I should just render it using Javascript.
Here is what I have tried so far:
Created a partial in the same folder as the new.html.erb (called _lightbox.html.erb)
The controller render changed to this:
def create
#user = User.new(params[:user])
respond_to do |format|
if #user.save
BackgroundJob.perform_async(#user.id)
format.html { render :partial=>"lightbox", :layout=>false}
format.json { render json: #user, status: :created, location: #user }
else
format.html { render action: "new" }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
I have read up on render, however using the :partial key it simply renders the partial on a new page. I should probably just change the form to use :remote and add the lightbox-esque content with an ajax success, however I was curious as to if this can be done with Ruby on Rails with its rendering functionality.

The code you've displayed here isn't really the problem. It's all in the view.
You need to prevent the default action from form submission, which is to post to the form URL. If the browser posts to that URL, it will render the response. Once you've prevented the default action, you'll then need to submit the form yourself using javascript and set up a callback to deal with the response. That callback should put the html in the place you want it in the page. If any parts of this are unclear, I can expand upon them.

Related

Rails 4 Render Different Depednding on Location of Form Submission

My application allows a user to upload some artwork to a specified campaign through the campaigns 'show' view. This allows me to capture the #campaign.id during the upload for association purposes.
Currently, if an error occurs (validation), it renders action: 'edit'.
I know if I update the render action: 'edit' => to render action: 'show', the basic level task works, but it also messes with the render action when editing the record itself.
If there a way for me to check if the 'update' is being processed through the 'show' view in order for me to render the show action instead of edit?
def update
respond_to do |format|
if #campaign.update(campaign_params)
format.html { redirect_to #campaign, notice: 'Campaign was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #campaign.errors, status: :unprocessable_entity }
end
end
end
Campaign Show View
<button class="btn btn-white" data-toggle="modal" data-target="#new_creative">
<i class="fa fa-plus-square-o"></i> Add New Creative
</button>
<%= render 'remoteforms/add_creative_to_campaign' %>

Rails remote delete and update view through Ajax

In the past, whenever I wanted to update a part of my view through Ajax, I've done the following:
create a partial out of the part I want to update and give it a unique ID, say #tracks
create a special action in the controller for that Ajax call, say remove_track that updates all the values, etc. and add format.js
create a new JS file with the same name as the action so Rails calls it automatically remove_track.js.erb which contains something like: $('#tracks').html("<%=j render 'cds/show_tracks' %>");
set remote: true in the link that calls this action.
All this is fine, but now I am trying to delete and update a common index view using the regular destroy method for flexibility, meaning I can call this method either through Ajax or normally. I figured it's such a common thing to do that there has to be a better way than all of the above.
I can get the destroy method to call my destroy.js.erb file by simply putting this into the controller:
format.js { layout: false }
and of course setting remote: true on the link.
what I cannot do is get the view to refresh. The table I want to refresh is encased in a div with a unique ID, but since it's not a partial, it refuses to refresh the content. Maybe I'm missing something.
Am I doomed to have to create a partial and refresh it with the method above or is there a more magical way of doing it (other than using Turbolinks)?
Thanks.
PS
Also, I just noticed this has the added disadvantage that I cannot pass the rest of the params to the destroy method since it only passes the object ID to destroy using the regular CRUD routes. If I try to use platform(action: destroy) or platform(method: delete) I get an error:
No route matches {:action=>"destroy", :controller=>"platforms"}
Which means I have to create a new route if I want to pass those parameters...
Yet another disadvantage to all this is that I'm repeading all the logic for searches and sorting that I have in the index method again in the destroy method. I am certain this is definitely not the way to do it.
Thanks to this page I found the proper way to do it. So simple and effective.
http://carmennorahgraydean.blogspot.com.es/2012/10/rails-328-ajax-super-basic-example.html
Update your destroy line in index.html.erb:
<%= link_to 'Destroy', pony, method: :delete, data: { confirm:
'Are you sure?' }, :remote => true, :class => 'delete_pony' %>
Create a file, destroy.js.erb, put it next to your other .erb files
(under app/views/ponies). It should look like this:
$('.delete_pony').bind('ajax:success', function() {
$(this).closest('tr').fadeOut();
});
Add format.js { render :layout => false } to your controller:
respond_to do |format|
format.html { redirect_to ponies_url }
format.json { head :no_content }
format.js { render :layout => false }
end
Hope this helps someone else.

rails insert ajax via jquery

Good day!
I'm trying to implement ajax in my rails test app.
my controller code app/controllers/admin/data
class Admin::DataController < ApplicationController
...
def ajax
if params[:ajax] == 'list'
#responce = Admin::Datum.all
else
#responce ={error: true}
end
respond_to do |format|
# format.html { redirect_to #user }
# format.js
format.json { render json: #responce }
end
end
end
index.js.erb
alert('1');
$.post('/admin/data/ajax',{ajax:'list'},function(responce){
alert('2');
console.log(responce);
}
);
could you help me in determining the url that i've to use in ajax to access ajax method?
or any other help is very welcome!
Update 1
Updated initial code to represent more complex problem
I added to routes.rb
match 'admin/data/ajax' => 'Admin::Data#ajax'
could be any url, it's what you write in your jquery.
And it works!

Best practice for Rails controller that paginates one mime format but not another

My rails project is paginating the HTML format but not the the others. Can someone suggest a more elegant approach to dealing with the difference in getting the #contacts collection? Perhaps the pagination version should be a different method that only supports HTML?
def index
if request.format.to_sym == :html
#contacts = Contact.paginate(page: params[:page]).search(params[:search])
else
#contacts = Contact.search(params[:search])
end
respond_to do |format|
format.html { render html: #contacts }
format.mobile { render mobile: #contacts }
format.json { render json: #contacts }
format.xml { render xml: #contacts.to_xml }
end
end
My solution was to add paginate as a RESTful resource in routes.rb which automagically gives me the route helper method: paginate_contacts_path
resources :contacts do
collection do
get 'paginate'
end
end
and to have a separate paginate method in ContactsController
def index
#contacts = Contact.search(params[:search])
respond_to do |format|
format.html { render html: #contacts }
format.mobile { render mobile: #contacts }
format.json { render json: #contacts }
format.xml { render xml: #contacts.to_xml }
end
end
def paginate
#contacts = Contact.paginate(page: params[:page]).search(params[:search])
respond_to do |format|
format.html
end
end
Strongly prefer a separate method because this creates inconstancies and makes the piece less testable. Also you would, in for example documentation, need to create exceptions.
Another way is to handle this with some parameter. Now it suddenly (when you only change views) returns different data. That might look like an error for an unknown developer and might raise issues.
So don't do it magically, clear parameter or separate method.

Rails 3.1 ajax:success handling

So Im playing with CoffeeScript, Rails 3.1 all the good stuff. I have a resource with all the usual routes index, show, create, edit, update, destroy.
The index view has a form that uses :remote => true like so:
<%= form_for #todo, :remote => true do |f| %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
In the controller for create I have the following:
def create
#todo = Todo.new(params[:todo])
respond_to do |format|
if #todo.save
format.html { redirect_to #todo, notice: 'Todo was successfully created.' }
format.json { render json: #todo, status: :created, location: #todo }
format.js {render json: #todo }
else
format.html { render action: "new" }
format.json { render json: #todo.errors, status: :unprocessable_entity }
end
end
end
Im trying to not use .js.erb views as I would rather handle the JSON returned and do all the fancy appends to the todo list and so on. (It just feels cleaner to me).
In my todos.js.coffee I have used the following:
$(document).ready ->
$("#new_todo")
.bind "ajax:success", (event, data) ->
alert("Ajax SUCCESS!!!")
(Yeah just tyting to open an alert box does not work) I tried loads but just cannot trigger this event. The request does complete successfully and the new todo is added.
Any help with this would be appreciated. Thanks
Started to pour over the rails.js and wondered if any of the ajax: callbacks were being raise.
Turned out they were well the beforeSend and error... hang on... error? How could this be? The creation of the new todo happens successfully, the response is the JSON I expect. But on stepping through the callback code I notice an Invalid label error.
Quick google later brings me to this post http://blog.seqmedia.com/?p=484
Turns out the JSON is being returned as a string, Firbug got that and parsed it correctly so I could check the response. However rails.js and js in general didnt know how to handle the string and threw the above error (rather silently I may say).
The solution was in the respond_to
format.js {render json: #todo, content_type: 'text/json' }
A bit thanks to Trevor Burnham (like the book BTW) for his help and Amy from sequence media whose blog post ultimately gave me the solution.
What is #new_todo? Does an element with that ID exist? Verify that $('#new_todo').length > 0 in your code, and that it's the right element to bind your event handler to.
What is ajax:success? The jQuery API defines an ajaxSuccess event (see the Ajax Events docs), but I've never seen the version with the colon before.

Resources