Rails flash message after AJAX success - ruby-on-rails

I have to ask about something that probably no one uses anymore. I want to display flash[:notice] after successfully AJAX action. I'm aware of this and that one and even this gist but none of them fit my example:
#controller code
def new
#registrant = Registrant.new
respond_to do |format|
format.html
if params[:add_patient_to_caregiver]
format.js { render partial: 'add_patient_to_caregiver' }
end
end
end
#view triggered controller#new action via AJAX
<%= link_to 'Add Patient to Caregiver', patient_to_caregiver_path(add_patient_to_caregiver: true, patient_to_caregiver: registrant.id), method: :get, remote: true %>
I want to have something like format.js { render partial: 'add_patient_to_caregiver', flash[:notice] = 'Patient Added' } to display it in a view. I've come up with a workaround:
_add_patient_to_caregiver.js.erb
$("#add-patient").html("<%= escape_javascript(render :partial => 'registrants/add_patient') %>");
$("#flash-messages").after("<div class='alert alert-success'> Patient Added </div>");
And flash message shows up but there are no close button there. Is there any better way to do so? or how to add close button to that message so that the whole page doesn't reload when it is pressed?

Related

rails 4, nested resource doesn't updates without page refreshing, using Ajax

So, I'm having Events model which has_many Questions. Relation is the same as in Post->Comment. I've tried to implement some Ajax for Questions, but it seems like I'm missing something, because View doesn't updates without refreshing the page. The same problem with delete method.
Here's my question_controller.rb:
def create
#question = #event.questions.create(question_params)
#question.user_id = current_user.id if current_user
if #question.save
respond_to do |format|
format.html { redirect_to event_path(#event) }
format.js # render questions/create.js.erb
end
else
render 'events/show'
end
end
Question _form.haml:
= simple_form_for [#event, #event.questions.new], remote: true do |f|
= f.input :content, label: 'Your question:', id: 'question_content'
= f.submit class: 'submit_btn'
Question partial _question.haml:
%h4
= question.content
This is how it looks in Events show.haml:
%section#question_section
%h1 Questions:
#questions
= render #event.questions
#question-form
%h1 Submit a question:
= render 'questions/form'
And create.js.erb file:
$('#questions').append("<%= j render partial: #question %>");
$('#question_content').val('');
I've tried few different tutorials, but always had the same problem. View updates only after refreshment. Also it is my second post on Stackoverflow so would be grateful for any suggestions if something is wrong with it.
EDIT 1: mostly I've been following this tutorial: https://pragmaticstudio.com/blog/2015/3/18/rails-jquery-ajax
EDIT 2: create.js.erb seems not to respond, tried to test it with alerts or console log, but without any success. After triggering a button in the console having: "Processing by QuestionsController#create as JS" (so it runs a proper file, but file itself doesn't executes any code). Have no idea why that happening.
So the problem was because of HAML. Had to change my format.js line in the controller to:
formta.js { render layout: false }
Here's the thread that helped to solve this: Rails update.js.erb not executing javascript

update different divs using ajax in rails 3.2

I recently started with Rails 3.2 and am stuck while trying to implement some ajax functionality in my app. I followed this railscast completely (http://railscasts.com/episodes/240-search-sort-paginate-with-ajax). Beyond this I want to implement a shortlist button for each product which lets user shortlist products and store them in the session. I also want a small list of shortlisted products to show up on the same page, which needs to be ajax updated.
I am wondering what is the best way to do that. I currently implemented the link_to buttons with remote tag and a helper function to change the link to shortlist/unshortlist. I also, used a conditional div to show the shortlist based on the length of shortlist. However, the issue is that whenever I shortlist, the order of the products table is also reset.
Here are snippets of my code :-
Application_helper.rb
def shortlist_unshortlist_link(product_id )
if (user_session.already_shortlisted? product_id )
link_to 'Unshortlist', { action: 'unshortlist', id: product_id }, remote => 'true'
else
link_to 'Shortlist', { action: 'shortlist', id: product_id }, remote => 'true'
end
end
def shortlist_div
shortlist=user_session.shortlist
if (user_session.shortlist.length > 0)
render :partial => 'pages/shortlist_fields'
end
end
products/index.html.erb
<div id="product">
<% #products.each do |product| %>
<tr>....
<td><%= shortlist_unshortlist_link(product.id.to_s) %></td>
</table>
</div>
<div class="shortlist"><%= shortlist_div() %> </div>
products_controller.rb
def shortlist
user_session.add_to_shortlist(params[:id])
redirect_to products_path
end
def unshortlist
user_session.remove_from_shortlist(params[:id])
redirect_to products_path
end
I think, the issue is because of redirect_to, but I am not getting how to avoid this without hurting the functionality. Am I on a totally wrong path here. Is this a good way to implement this. Any suggestions.
thanks,
Amit
you should use in shortlist method,
respond_to do |format|
format.html {redirect_to products_path }#shortlist.html.erb
format.js #shortlist.js.erb
end
and write your java script to #shortlist.js.erb file.
Do the same with unshortlist.
I agree with Sush, you didn't response to the ajax request from link_to.
In your controller, shortlist method, response to the ajax request
respond_to do |format|
format.html {redirect_to products_path }
format.js
end
By convention in Rails, format.js will execute the js.erb file with the same name as your method.
And in the shortlist.js.erb, you may write something like:
$('#shortlist').html('<%= escape_javascript(render "pages/shortlist_fields")%>');
Besides, you can also call the same js.erb file.
In the unshortlist method, you can do it like that:
respond_to do |format|
format.html {redirect_to products_path }
format.js {render :action=>'shortlist'}
end

rail ajax remote form to update text field upon submission

All I want to do is update a text field on my page with a value when my Rails remote form is submitted.
All the source code be found at github here https://github.com/iamliamnorton/fasdac
The form is on the index page...
Controller code...
def index
#calculator = Calculator.new(params[:calculator])
if #calculator.valid?
respond_to do |format|
format.html { redirect_to calculator_path(:calculator => params[:calculator]), :notice => 'Calculation was successfully completed.' }
format.js
end
else
respond_to do |format|
format.html { redirect_to calculator_path(:calculator => params[:calculator]), :alert => "Calculation was not successfully completed. #{#calculator.errors.full_messages.to_sentence}" }
format.js
end
end
My input form
<%= form_for(#calculator, :url => calculator_path, :remote => true) do |f| %>
...
<% end %>
And the index.js.erb
$("#result").value = "SUCCESS!";
I'm trying to update a input text field with name and id 'result'. I cannot get this working, I've tried many different variants in the index.js.erb but cannot get it working. What am I doing wrong?
It looks like the data is being sent to the controller as I can see in the server console
...
Processing by CalculatorController#index as JS
...
But I can't get the text area to update
index.js.erb
$('#result').val("Success!");

Rails: rendering the js.erb template using the controller

I have a rails app trying to incorporate some AJAX where clicking new opens a modal window and a form. I want to be able to display the validation errors if it fails so in my create action, i thought about re-rendering the new.js.erb file. Is this the right approach?
def create
#place = Place.new(params[:place])
if #place.save
redirect_to places_path, :notice => "Successfully created place"
else
render "new.js.erb"
end
end
The result I get is escaped js text in my browser like:
$("#new_grouping").html("<div class=\"modal-header\">\n <a class=\"close\" data- dismiss=\"modal\">×<\/a>\n <h3>Create a new menu section<\/h3>\n<\/div>\n<form accept-charset=\"UTF-8\" action=\"/places/1-mama-s-pizza/groupings\" class=\"simple_form new_grouping\" id=\"new_grouping\" method=\"post\" novalidate=\"novalidate\">
I've tried putting various options into the render block but no luck. Any tips?
The best practice would be to support both, AJAX and Non-AJAX calls, in case the user has javascript turned off for any reason.
def create
#place = Place.new(params[:place])
respond_to do |format|
if #place.save
format.html { redirect_to places_path, :notice => "Successfully created place" }
format.js # renders create.js.erb, which could be used to redirect via javascript
else
format.html { render :action => 'new' }
format.js { render :action => 'new' }
end
end
end
The render :action => 'new' actually renders the template of the controller action new which results to new.html.erb respectively to new.js.erb depending if it's a non-AJAX or an AJAX call.
In new.js.erb goes your ERB/javascript code:
$("#new_grouping").html("<%= escape_javascript(...) %>">
As i know, rendering partial in controller is a bad idea, because then response can be without content-type and some browsers can't understand this. if it is some file attached to action you should write
render :action => "create"
or if you need just render a singe partial then in your action file write
<%= render :partial => "path/to/partial" %>
as i said, then you won't have problems with content-type in response

Create Model from unrelated View on Rails 3.0

I'm trying to do something fairly simple but I'm not sure the rails way to do it. At its simplest, I have an index page where you can sign up for a mailing list.
I'm trying to set it up so that you can add yourself to the mailing list from the index page without ever seeing the mailing list views. I can submit the data properly using something like:
= form_for #mailing_list, :remote => true do |form|
= if #mailing_list.errors.any?
%ul
= #mailing_list.errors.full_messages.each do |message|
%li
= message
.field
= form.label :email, 'Your email'
= form.text_field :email
= form.submit "Add to Mailing List"
With the controller:
def create
#mailing_list = MailingList.new(params[:mailing_list])
if #mailing_list.save
redirect_to(:root, :notice => 'Mailing list was successfully created.')
else
? How do I return the errors ?
end
end
But I am unable to get the errors back (ie. Email not valid, etc.). Is there a better way to do what I'm attempting? I would just like to be able to call and respond to actions of the MailingList controller from the index page view...
I believe that you are wanting a form that will add someone to a Mailing list without leaving that page.
Better? Hmmm.. Well, I'll tell you what I do and you can decide what you like.
I would use respond_to in the controller to differentiate between the standard html call and the remote js call. Then, I would handle the page changes in the view. I like keeping the display in the views.
Controller:
def create
#mailing_list = MailingList.new(params[:mailing_list])
if #mailing_list.save
respond_to do |format|
format.html { redirect_to(:root, :notice => 'Mailing list was successfully created.') }
format.js { render }
end
else
respond_to do |format|
format.html { render }
format.js { render :errors }
end
end
end
create.js.erb
$('#errors').html('').hide();
$('form').html('Mailing list was successfully created.'); // needs a better element
errors.js.erb
$('#errors').html('<%= escape_javascript(#mailing_list.errors.full_messages.collect { |msg| content_tag :li, msg }.join().html_safe) %>').show();
You can do something with the errors object on #mailing_list, e.g.
flash.now[:error] = #mailing_list.errors.full_messages

Resources