ajax link not working though jquery is loaded - ruby-on-rails

I have a link to in my view
= link_to "Remove from Handy List", {controller: "handy_lists", action: "destroy_via_ajax", tradie_id: "1"}, method: :get, remote: true, class: "pull-right"
In my routes I have
get "handy_lists/destroy_via_ajax/:tradie_id", to: "handy_lists#destroy_via_ajax"
The action for now simply displays
def destroy_via_ajax
puts "it deletes"
end
Whenever I click the button the server isn't responding. I've checked and javascript and jquery are loaded so I know it can't be that. I don't know what I'm missing. What's wrong with the link and how can I fix it?

There are several things which could be wrong:
Is your remote link working?
This would be the first thing to test. I would use the development console in either Chrome or Mozilla & click on the "network" tab, to see if the link is actually requesting some sort of ajax link.
Likelihood is that it is, but I don't think you've set up your system correctly
Your controller setup could be incorrect
You're calling the action "destroy with ajax"... why not just use the respond_to function in the normal destroy action?
You could try this:
def destroy
respond_to do |format|
format.js
end
end
This will allow you to create destroy.js.erb in your views/controller folder, where you can then call something like:
alert('Deleted Successfully!');
This should work, but I am open to chat if you need more help!

Related

Rails + ajax, my "edit.js.erb" is not being run

I'm trying to setup ajax within rails, but I am having trouble getting my "edit.js.erb" to be ran
My edit.html.haml
= f.check_box :foo, {checked: eligibility_data.foo, class: "foo", remote: true}
controller
def edit
#survey = Foo.find_by_id(params[:id])
respond_to do |format|
format.html
format.js
end
end
edit.js.erb
alert("Testing");
How can I get edit.js.erb to run? Once it's working I want to append html to my view, will I be able to place that html right into my js.erb, or will I have to make a partial of some sort?
You can't append remote: true to a checkbox and expect it to fire off.
It needs to either be attached to the parent form tag of said checkbox, or you need to write some js that watches that checkbox.
If you go the watcher route, the JS will send an ajax call when the box gets clicked on.
Here is a link on how to do AJAX with jQuery (which is built into rails)

Add a "Thank you for your order" page that is not directly visitable

When the user purchases an item we want to display a thank you page.
Then again we want this page not to be directly visitable.
In other words, if the page was to be /orders/thankyou, the user could directly navigate to it which would be rather ugly and fail aas it would have nothing to show.
how can we show this page only when in context and forbid direct navigation to it?
You can create a partial form and append it to the DOM after the purchase event is fired. In the partial view, be sure to add a redirect action if it was accessed without the purchase event firing.
For just displaying short text (and not also e.g. the order data) you could just use a flash notice. For example:
redirect_to #page, notice: "Thank you for your order!"
Ajax
Sounds like you'll be best using ajax:
#app/views/cart/index.html.erb
<%= form_tag cart_order_path, remote: true do |f| %>
... (cart form)
<%= f.submit %>
<% end %>
This (obviously very simple) form will send a "remote" (Ajax) form submission to your controller. The reason why this is important is because you will then handle the response directly in that page you just sent the request from:
#app/assets/javascripts/application.js
$(document).on("ajax:success", "#your_form_id", function(status, data, xhr) {
$("your_page_div").html(data);
});
The trick here will be to render your thank you view without a layout -
#app/controllers/cart_controller.rb
class CartController < ApplicationController
respond_to :js, only: :create
def create
... business logic here
render "thank_you", layout: false
end
end
This will render the view you want without any of the supporting "layout" HTML - giving you the chance to append that to your current view. This means that if you wanted to show the "Thank You" view without letting the user browse to it directly - that's what you'll do
How It Works
Ajax (Asynchronous Javascript and XML) is a javascript technology which basically allows you to send "pseudo requests" to your Rails backend:
Basically the same as a standard HTTP request, except handled with Javascript, Ajax gives you the ability to create the appearance of "no refresh" functionality in your app. It does this by sending requests on your behalf, through Javascript.
Ajax is typically used for small pieces of functionality on web interfaces - whereby you'll have the ability to send simple requests to the server, gaining a comparable response that you can then work into the DOM.
This is the functionality I have been proposing - whereby you'll be able to send a request to your controller (albeit using the Rails UJS engine), to which you'll then receive a response. This response can then be worked into your page, thus providing you with the ability to show the "Thank You" page without the user refreshing.
You can use any solution from the following:
Using ActionDispatch::Flash:
flash[:notice] = "Thank you for your order!"
redirect_to #page
or
redirect_to #page, notice: "Thank you for your order!"
Using alert, in show.js.haml file (assuming you use action show in orders_controller.rb):
alert("Thank you for your order!");
and then add respond_to :js, only: :show, and format.js in action show for orders_controller.rb

Simulate redirect_to with remote option

I have the following scheme:
lessons_controller -> show.html.erb, which contains *form_tag* with remote: true -> test_controller -> show.js -> _test.html.erb
So I receive the content of _test.html.erb when submit the form_tag on lesson/show page.
But I want to skip the lesson/show page in some cases.
So I want to go to the lesson/show page and receive the content of _test.html.erb without submitting anything, under the ground. Something like redirect_to in lessons_controller with remote option to simulate the form_tag submitting.
Is it possible?
Not sure your purpose, if you only want to show the form directly, it's as simple as putting following in js assets
$ ->
$(form#show_lesson).submit()
If you want to control it in controller level. You can do the following.
# Lessons controller
def show
#lesson = Lesson.find params[:id]
template = params[:show_directly].present? ? 'show' : 'show_with_test'
render template
end
# views/show.html.erb
render partial: 'show_form'
# views/show_with_test.erb
render partial: 'test', locals: {lesson: #lesson}
Use
Browse lessons/1 will show original form
Browse lessons/1?show_directly=1 will show all directly.
I think you can just invoke javascript submit when lessons#show is loaded, and use the callback data from _test.html.erb.
I don't think it's possible and good way to make a redirect request with a 'script' type.

Adding AJAX 'add to favorite' to this controller?

This is blowing my mind, and there is so much going on that I just need to ask here for help.
Right now, I have a listing of resources. Inside each resource, it allows someone to 'add it as a favorite' by clicking a link. I have it working with normal redirection, but as for integrating ajax so they can favorite without the page refreshing, I am completely lost...
Right now I have it as a "put" action it seems for CRUD 'update'
FavoritesController (update is the only action in this controller)
def update
#favorite = Favorite.find_or_initialize_by_resource_id_and_user_id(params[:id], current_user.id)
if #favorite.persisted?
#favorite.destroy
else
if #favorite.valid?
#favorite.save
end
end
redirect_to root_url
end
My view:
<%= link_to "", favorites_path(:id => resource.id), :class => "star#{star_post?(resource)}", :method => "put" %>
My routes:
resource :favorites, :only => [:update]
My JS:
$('.res-list .star').click(function(){
$.put('/favorites/?id=' + $(this).attr('data-id'));
return false;
});
There's a couple of ways to do this. You can use link_to_function through which you can pass a javascript method (you can even pass a custom one if you've defined it in the view or in application.js). In this method, you can set up your AJAX call to hit your update action.
View (using jQuery's put macro):
<%= link_to_function "AJAX Link", "$.put('/favorites/#{resource.id}');" %>
Another way to do this is to give your link an addition HTML selector. Again, you would need to write a bit of js to hit your update action. I tend to like this way because I like to use buttons and what not instead of <a href="#"> tags. (Though honestly I ended up just creating a button_to_function method that calls content_tag(:button) instead of content_tag(:a))
I would recommend starting off with this Railscast on basic JQuery and Ajax processing. It's a bit dated, but is pretty solid still and will give you the basics to get you started.
http://railscasts.com/episodes/136-jquery
It will give you an idea of how to attach the ajax call to the element on your page, handle request processing and craft a basic javascript view partial that will update the form for the user.
Good luck!

rails, how to reference action mailer in jquery

i wanted to perform an action mailer method after an ajax method completes. im building a twitter app essentially, and wanted an email notification to be sent after someone clicks 'follow', which is done asynchronously.
i gave the follow button an id
<%= f.submit "Follow", :class => "btn btn-large btn-primary",
:id => "follow_button"%>
and then used jquery
$("#follow_button").bind('ajax:success', function() {
});
however, im really sure how i can reference my UserMailer in jquery. ultimately im trying to perform this line after my ajax is complete
UserMailer.is_now_following(#user, current_user).deliver
thanks!
hmmm i tried adding that line of code in my create function (to create the relationship of the follow) but it lags my ajax quite a lot. the ajax is to render the 'unfollow' button after the 'follow' is clicked btw.
def create
#user = User.find(params[:relationship][:followed_id])
current_user.follow!(#user)
respond_to do |format|
format.html {redirect_to #user}
format.js
end
#UserMailer.is_now_following(#user, current_user).deliver
end
i commented it out. is this what you meant for adding it after my ajax call is successful?
also, how do you put a job on queue? thanks!
The better solution is doing that only in your server not in your client side.
If you do like you want you need doing 2 requests. 1 to follow people and 1 to launch mail. If you user stop this application between this 2 requests, no email is send.
The better solution is to launch your Mailer directly in your follow action. In your controller, you know if the request is a success or not. If the request is a success launch the email.
If you want more reactivity and avoid doing this job directly in your action, you can push the mailer action to a job queue.

Resources