I want to invoke an Ajax call in Rails. I've seen a good way of doing so with the :remote option. I've got this working example:
<%= button_to('Get Transfers', {:action => 'get_transfers', :section_id => params[:section_id]}, :method => :get, :remote => true) %>
However, I don't want the user to invoke the call by pressing a button or clicking a link, but rather invoke it on a Javascript event (hovering over an element).
Is there a way to use :remote => true, but invoke it automatically when hovering over an element? If yes, how?
Option 1
To make the button respond to click and hover over some other div you can try doing the following:
In your view you give the button a unique id and add some class to an element that should be act as a trigger:
<%= button_to('Get Transfers', {action: 'get_transfers', section_id: params[:section_id]}, method: :get, remote: true}, {id: 'remote_hover_button'}) %>
<div class="some_trigger">Hover me!</div>
In your js you want to bind to that trigger element and trigger the click event on the button:
$(document).ready(function(){
$('.some_trigger').hover(function(){
$('#remote_hover_button').trigger('click');
});
});
Option 2
Write the ajax manually by creating a div that you hover and provide it with an url to call:
<div class="some_trigger" data-url="<%= url_for(action: 'get_transfers', section_id: params[:section_id]) %>">Hover me!</div>
Bind to the div and do an ajax call:
$(document).ready(function(){
$('.some_trigger').hover(function(){
$.ajax($(this).data('url'));
});
});
This will actually just trigger the action and not perform anything with the response.
You can bind to the result with something like this:
$(document).ready(function(){
$('.some_trigger').hover(function(){
$.ajax($(this).data('url'))
.done(function() { alert("success"); })
.fail(function() { alert("error"); })
.always(function() { alert("complete"); });
});
});
For more information on ajax function look at the documentation.
Related
I have a partial _table_row this partial holds my html for the output of #admin_products.all
In this partial I have a soft delete button which initiates a twitter bootstrap popover, this popover has the hard delete button for the record from the database.
To get the button into the popover currently I've included the HTML content in the partial _table_row this as you can imagine repeats the HTML by the number of records in my database.
What I'm trying to achieve is to keep the HTML for the popover in index.html.erb and to dynamically add the destroy button into the popover with the correct ID. This is where I'm having difficulty.
I've tried to use
$('.deleteButton').popover({
html: true,
content: $('#popoverDestroy').html() + <%= link_to 'Delete', admin_product, method: :delete, class: 'btn btn-danger destroyButton', remote: true %>,
placement: 'left'
});
But as you can understand it will fail as it doesn't know what admin_product is, how would you associate it correctly?
Add the HTML that you want as a data attribute on the soft delete button, then pull it out again in javascript:
In the partial:
<button class='deleteButton' data-delete-button='<%= link_to 'Delete', admin_product, method: :delete, class: 'btn btn-danger destroyButton', remote: true %>'></button>
Then in JavaScript:
$('.deleteButton').each(function() {
var softButton = $(this);
softButton.popover({
html: true,
content: $('#popoverDestroy').html() + softButton.data('delete-button'),
placement: 'left'
});
});
Instead of breaking best practice and placing your javascript inline you could actually have the "soft" link actually have the correct URL.
You could do this by having your "soft" link actually point to the delete url and having an event listener which cancels out the click and opens the popover.
$(document).on('click', '.deleteButton', function(){
var link = $(this);
var content = $('#popoverDestroy').clone()
.append(link.clone().removeClass('.deleteButton'))
link.popover({
html: true,
content: content.html()
});
return false;
});
This is more inline with the idea of progressive enhancement since you take a normal HTML link element and add behavior.
You can pass the product id as an html attribute. In you _table_row.html.erb:
<a class='deleteButton' data-productId='<%= admin_product.id %>'>Soft Delete</a>
And then in your javascript, you can access the clicked button with the this reference if you pass a function to content (reference):
$('.deleteButton').popover({
html: true,
content: function(){
return $('#popoverDestroy').html() + "<a href='/your-url/'" + this.data('productId') + "data-remote='true' data-method='delete'>Destroy</a>"
},
placement: 'left'
});
I am trying to hide this button in ruby once it is clicked so it doesn't show up again and the user thinks their request has not went through. I just want this clickable once then removed from page not just disabled
<% if #ride_request clicks %>
<%= link_to "Book Ride", :controller => "/request", :action => "book", :id => #ride.id %>
Consider using disable_with, which IIRC works with both link_to and submit buttons:
http://api.rubyonrails.org/classes/ActionView/Helpers/UrlHelper.html#method-i-link_to
You can this javascript (jQuery) inside your controller specific .js file
$(document).ready(function() {
$('#replace_id').click(function (){
$(this).hide();
});
});
All you need to do now is add the id of the object and substitute it with replace_id.
you could try jQuery's element.hide() http://api.jquery.com/hide/#hide
or you could toggle css' display:none for that button
or you could try jQuery's element.remove() http://www.w3schools.com/jquery/html_remove.asp
Your question is actually about JS, rather than Rails.
You have to remember Rails is a server-side framework, which means it takes a request from the front-end, and then processes a response for you. This means that any UX stuff on the front-end needs to be handled with JS
To do that, you'd be best using the $("element").remove(); function of Javascript:
DEMO
$(document).on("click", "element", function(){
$(this).fadeOut(150, function() {
$(this).remove();
});
});
This will fade the button out, and then remove it from the DOM
I want to show modal window on click of link but also want to do ajax request to get the object which needs to be shown on modal window.
I am getting response with the content which needs to be shown on modal window but it is not popping up as modal window probably the script is not getting executed.
Code
Main Page
<%= link_to "New Topic", "#", :class => 'btn primary float-right bootstrap-popover' %>
<div id="modal_form_container"></div>
Javascript Code
$('a.bootstrap-popover').live('click', function(){
$(this).unbind('click');
$.ajax({
url: "/topics/new",
type: "GET",
dataType: "html",
complete: function() {
$('loading').hide();
},
success: function(data) {
},
error:function() {
}
}); // End of Ajax
new.js.erb
$('#modal_form_container').html("<%= escape_javascript( render :partial => 'new_form')%>");
$('#modal_form').modal('show');
This new_form page contains content to be shown on modal window
Can anybody help?
Is it because the loading element is not being hidden?
$('loading').hide();
Should this not be something like:
$('#loading').hide();
I think you have to write something like following code after your ajax request gets success.
$('#PopupBoxId').modal('show'); // Show the pop-up (modal)
$('#disable_layer').modal('show'); // Show the black overlay
We have to manually show the pop-up after the ajax request handling.. As per my small experience in bootstrap.
:)
Hope it works for you.
Have you looked into the Bootstrap Modal Manager? You can use it like so:
$("a.open-with-ajax-loader").live('click', function(e){
e.preventDefault();
$('body').modalmanager('loading');
$('#id-of-modal-div').modal({
remote: '/url/to/load'
});
});
You can see this in action on the live demo page for the Bootstrap Modal Manager ( scroll down a bit, look for the AJAX demo ).
I'm experiencing some strange behavior with .bind() and .unbind() in JQuery, even though my situation is seemingly identical to an example given on the JQuery site. In this case, the bind/unbind is applied to a JQuery tab (one of many). When the tab is clicked, it loads a controller action through ajax.
# show.html.erb:
$(document).ready( function(){
var projectNav = function(){
$("#tabs-project .loadingDiv").show();
$.ajax({ url: "<%= url_for(params.except(:action).merge(:action => 'show_project')) %>", dataType: 'script' })
};
$("#projectMenuButton").bind('click', projectNav);
});
# show_project.js.erb
$("#tabs-project .loadingDiv").remove();
$("#tabs-project").append('<%= escape_javascript(render :partial => "profiles/project")%>')
$("#projectMenuButton").unbind('click', projectNav);
The .unbind() part isn't working like that - clicking the menu button again reloads the partial again.
When I change the existing unbind to $("#projectMenuButton").unbind('click');, it unbinds everything including the tab's principal function (to switch the view to the right div).
You have a scope problem... projectNav is only defined within the scope of the $(document).ready, so it is undefined when passed into unbind. A solution:
# show.html.erb:
var projectNav = function(){
$("#tabs-project .loadingDiv").show();
$.ajax({ url: "<%= url_for(params.except(:action).merge(:action => 'show_project')) %>", dataType: 'script' })
};
$(document).ready( function(){
$("#projectMenuButton").bind('click', projectNav);
});
# show_project.js.erb
$("#tabs-project .loadingDiv").remove();
$("#tabs-project").append('<%= escape_javascript(render :partial => "profiles/project")%>')
$("#projectMenuButton").unbind('click', projectNav);
How do I create a link of this type:
<a href="#" onclick="document.getElementById('search').value=this.value">
using method link_to in Rails?
I couldn't figure it out from Rails docs.
You can use link_to_function (removed in Rails 4.1):
link_to_function 'My link with obtrusive JavaScript', 'alert("Oh no!")'
Or, if you absolutely need to use link_to:
link_to 'Another link with obtrusive JavaScript', '#',
:onclick => 'alert("Please no!")'
However, putting JavaScript right into your generated HTML is obtrusive, and is bad practice.
Instead, your Rails code should simply be something like this:
link_to 'Link with unobtrusive JavaScript',
'/actual/url/in/case/javascript/is/broken',
:id => 'my-link'
And assuming you're using the Prototype JS framework, JS like this in your application.js:
$('my-link').observe('click', function (event) {
alert('Hooray!');
event.stop(); // Prevent link from following through to its given href
});
Or if you're using jQuery:
$('#my-link').click(function (event) {
alert('Hooray!');
event.preventDefault(); // Prevent link from following its href
});
By using this third technique, you guarantee that the link will follow through to some other page—not just fail silently—if JavaScript is unavailable for the user. Remember, JS could be unavailable because the user has a poor internet connection (e.g., mobile device, public wifi), the user or user's sysadmin disabled it, or an unexpected JS error occurred (i.e., developer error).
To follow up on Ron's answer if using JQuery and putting it in application.js or the head section you need to wrap it in a ready() section...
$(document).ready(function() {
$('#my-link').click(function(event){
alert('Hooray!');
event.preventDefault(); // Prevent link from following its href
});
});
just use
=link_to "link", "javascript:function()"
another solution is catching onClick event and for aggregate data to js function you can
.hmtl.erb
<%= link_to "Action", 'javascript:;', class: 'my-class', data: { 'array' => %w(foo bar) } %>
.js
// handle my-class click
$('a.my-class').on('click', function () {
var link = $(this);
var array = link.data('array');
});