In my view I have a link_to for downloading an excel file:
<%= link_to 'Download Excel', url_for( :controller => "my_controller", :action => "file", :format => 'xlsx', :params => params ) %>
The controller uses axlsx to render the file like:
format.xlsx {
render xlsx: 'file', filename: 'filename', disposition: 'inline'
}
Now it can take a bit of time to generate and return that file, so I'd like to give the user an indication that the site's working.
I have a hidden div in the view code:
<div id="loader"><img src="/assets/loading.gif" ></div>
When someone clicks on the link, I can show the div with this jQuery:
$('#excel_export').click(function() {
$("#loader").show();
});
My question is: how can I .hide() that div when the file download starts? Maybe an ajax callback of some sort?
I don't know if this may help you. I found this code helpful to show spinner while an ajax request is performed.
$(document)
.ajaxStart(function() {
$("#loader").show();
})
.ajaxStop(function() {
$('#loader').hide();
});
You can get more samples from the following link.
You can use setTimeout() function by checking general time taken for download to start
Like this
$('#excel_export').click(function() {
$("#loader").show();
setTimeout($("#loader").hide();, 1000);
});
So it will be automatically close after 1000ms
Related
I'm completely new to ruby on rails. Please help me out with the below use case.
By default flash messages are configured to timeout and fade in few seconds in application.html.erb
<div id="message" class="modal alert alert-error fade clear" data-alert="alert">
<%= flash[:notice] %>
</div>
Javascript code to set the timeout for the flash:
var showFlashMsg = function(){
<%if flash[:notice].nil?%>
return false;
<%else%>
return true;
<%end%>}
if(showFlashMsg()){
window.setTimeout(function () {
showMsg();
}, 100);
window.setTimeout(function () {
closeMsg();
}, 500);
}
showMsg() and closeMsg() holds #message.show() and #message.hide() functions.
But i'm trying to override that above mentioned behavior by making specific flash alert messages user dismissable (ie., adding the close button to the flash alert.) - in case the flash message is triggered when i submit the particular form.
So in this case, i need to override the default behavior set for the flash by adding the close button and removing the closeMsg() timeout for those flash. Except the flash messages which are displaying the form submission response, all the other flash messages triggered by same controller and the same action should follow above mentioned behavior of fading out within few seconds.
Please give me some suggestions on how to customize the flash messages only for the particular form submission response using javascript and rails?
Thanks in advance !!!
I'd rewrite the first bit of code as:
var showFlashMsg = <%= !flash[:notice].nil? %>
Then assuming you know what string you're looking out for in your notice:
<% special_string = "This is the special flash notice" %>
var showFlashMsg = <%= !flash[:notice].nil? %>
var setTimeout = <%= flash[:notice] && flash[:notice] != special_string %>
if(showFlashMsg){
window.setTimeout(function () {
showMsg();
}, 100)
}
if (setTimeout){
window.setTimeout(function () {
closeMsg();
}, 500);
}
This will set showFlashMsg to true if flash[:notice] is not nil, and setTimeout to true if it's not nil, and also doesn't equal the special string.
Here is my blog_post_inner.js :\
$(document).ready(function () {
// when the load more link is clicked
$('a.load-more').click(function (e) {
// prevent the default click action
e.preventDefault();
// hide load more link
$('.load-more').hide();
// show loading gif
$('.loading-gif').show();
// get the last id and save it in a variable 'last-id'
var last_id = $('.record').last().attr('data-id');
// make an ajax call passing along our last user id
$.ajax({
// make a get request to the server
type: "GET",
// get the url from the href attribute of our link
url: $(this).attr('href'),
// send the last id to our rails app
data: {
id: last_id
},
// the response will be a script
dataType: "script",
// upon success
success: function () {
// hide the loading gif
$('.loading-gif').hide();
// show our load more link
$('.load-more').show();
}
});
});
});
Inside blog_post_inner my main ajax is defined.
I am calling it here inside blog_post_inner.html.erb:
<div class="load-more-container">
<!-- hide our loading gif image so that we show it when making ajax call via jquery -->
<%= image_tag "ajax-loader.gif", style: "display:none;", class: "loading-gif" %>
<%= link_to_next_page articles,"Load More" ,class: "load-more" %>
</div>
But the main problem is my ajax is not loading the page in the same webpage istead its reloading/refreshing/redirecting to second page.
What to do?
I have tried changing link_to_next_page to link_to but it's giving an error:
undefined method `to_model' for #
Did you mean? to_xml
Please help my ajax is not working i have tried so many different methods but none of them prove to be useful.
I followed this article to implement this:
http://josephndungu.com/tutorials/rails-load-more-results-using-jquery-ajax
I'm working on a webapp using Ruby on Rails as framework. For all the partial renders, we used link_to with remote true as explained in this answer. However, I would like to bind the all those links to something equivalent to ajax:beforeSend and ajax:complete in order to implement a loader anytime a page is called in jQuery. So far I tried the following but it is not working :
$('a').on('ajax:beforeSend', function() {
alert("BEFORE");
});
$('a').bind('ajax:complete', function() {
alert("AFTER");
});
So if you have any other ideas it would be really appreciated if you could let me know. Thanks in advance.
EDIT: Here's an example of how I have been using link_to :
<%= link_to({action: "show_card", controller: "pages", id: activ.id, method: :get, :remote => true}, class: "nav-link p-0") %>
What is not working ajax or loader if your ajax is working then for loader it should be like this
<div id="mySpinner" style="displany:none;">
<img src="loader.gif">
</div>
$(function () {
$(document).ajaxStart(function() {
//$("#mySpinner").show();
alert("BEFORE");
}).ajaxStop(function() {
//$("#mySpinner").hide();
alert("AFTER");
});
});
How about to show loader on element onclick event and hide it on ajax:success?
$('a').on('click', function() {
alert("BEFORE");
});
$('a').ob('ajax:success', function() {
alert("AFTER");
});
Make sure to also cover ajax:error
You might also try to subscribe to ajax:send instead of ajax:beforeSend. Because ajax:beforeSend is a local event and can be subscribed to only within the Ajax request object as docs say
I found out what it was, when I render new staff partially, I need to rebind it to the event, and apparently even using
$( window ).load(function() {
$('a').on('ajax:beforeSend', function() {
alert("BEFORE");
});
$('a').bind('ajax:complete', function() {
alert("AFTER");
});
});
In the application.js file did not work, so basically to bind it initially I had to put a script tag at the bottom of my page which binds everything once it already rendered everything. Furthermore, anytime I do any remote partial rendering, I also need to rebind everything in the .js.erb file, that way it actually works. I'm there has to be a better way because this seems an awful solution; it is however, a solution for now.
Actually I have got a more number of records in my index page with respective "hide"link on each record. Then problem is when I click the respective link it hides the record but moves to the top of the page, how do I stop this?
_rak361.html.erb
<%= link_to "Hide", hide_rak361_path(rak361), method: :put, class: 'stopper', style: "color:#ccc;" %>
ample.js
$( document ).ready(function() {
$(".stopper").click(function(event) {
event.preventDefault();
});
});
rak361s_controller.rb
def hide
#rak361 = Rak361.find(params[:id])
#rak361.hide
flash[:notice] = 'Rak361 was successfully hidden.'
redirect_to rak361s_url
end
I have tried but it is not working for me.
Any suggestions are most welcome.
Thank you in advance.
Thats because its a full page reload, first thing you need to to do is to use path helpers instead of mentioning controller and action in link_to, and the second thing is you should use remote: true option to ajaxify the request. Here's an example
= link_to "Hide", example_hide_path(id), method: :put, remote: true, class: 'stopper', style: "color:#ccc;"
Either you can use remote: true, or you can send an ajax request using jQuery's $.ajax().
Hope that helps!
I'm writing a Rails app which includes ajax functionality using jQuery. I hope you guys could help me out here.
For example, in my /public/javascripts/application.js :
/* application.js */
...
$('.item-edit').editable('/item/update', {
name : $(this).attr('name'),
id : $(this).attr('id'),
cancel : 'Cancel',
submit : 'OK',
indicator : 'Saving...',
tooltip : 'Click to edit...',
method : 'put',
submitdata : {attribute : "name"}
});
With the jEditable plugin, this code binds the registered elements for inline-editing.
So lets say I have a partial in app/views/shared/_item_info.html.erb
<!-- _item_info.html.erb -->
...
<li class="item-edit" id="<%= item.id %>"><%= item.name %> </li>
...
On first load, when any 'item-edit' elements are clicked, the user will be presented with an inline textbox with an 'Ok' button. When 'Ok' is clicked, a 'PUT' request is submitted causing that text to be saved. After that text has been saved in the DB, we will then render the new text by calling the partial:
This is what my update.js.erb looks like:
/* update.js.erb */
...
$("#items").html("<%= escape_javascript(render('shared/item_info')) %>")
$('.item-edit').editable('/item/update', {
name : $(this).attr('name'),
id : $(this).attr('id'),
cancel : 'Cancel',
submit : 'OK',
indicator : 'Saving...',
tooltip : 'Click to edit...',
method : 'put',
submitdata : {attribute : "name"}
});
...
You may have noticed that I have to re-register my elements to enable inline-editing, if not, clicking on the elements will do nothing. My problem is that I am re-registering other events in other requests such as in create.js.erb as well which causes massive code duplication.
Is there any solutions to this problem? Is there a way where I could put all my common event re-registering codes in one .js file and include it inside a create.js.erb, update.js.erb...so that all my events will be re-registered without me having to copy/paste code?
Sorry for being long-winded. Would appreciate any help I could get.
jQuery provides an awesome method to do this called .live (docs: http://api.jquery.com/live/ )
However since your using a plugin and calling .editable to do the binding, you would have to modify the source of jEditable to use .live appropriately, which may (or may not) be more work than its worth.
There actually seems to be some other very similar questions:
jeditable live()
Making JEditable work on new elements (.live)
but neither have a perfect solution, but worth checking out
I came up with a solution that's not pretty but it helps eliminate code duplication right now.
I just added this in my partial:
<!-- _item_info.html.erb -->
...
<li class="item-edit" id="<%= item.id %>"><%= item.name %> </li>
...
<% javascript_tag do -%>
$('.item-edit').editable('/item/update', {
name : $(this).attr('name'),
id : $(this).attr('id'),
cancel : 'Cancel',
submit : 'OK',
indicator : 'Saving...',
tooltip : 'Click to edit...',
method : 'put',
submitdata : {attribute : "name"}
});
...
I no longer have to do any re-registration in my .js.erb files.