Auto refresh <div> without reload entire page - ruby-on-rails

I'm trying to update the content of "mydiv" without refreshing the entire index page.
#mydata is given by mycontroller. I need to recalculate it every n seconds and pass it to "mydiv"
With "link_to" it works!
index.html.erb
<%=
link_to('refresh', '/mycontroller/index', :remote => true)
%>
<div id="mydiv">
<%=
#mydata
%>
</div>
index.js.erb
$('#mydiv').html('<%= escape_javascript(#mydata) %>')
Now I need to refresh the content of "mydiv" automatically every n seconds (so without click on the link). I have tried solutions from:
First Link
Second Link
but no luck.
In my application.js I have writed this:
function executeQuery() {
$.ajax({
//url: '/index',
success: function(data) {
$('#mydiv').html(data)
}
});
setTimeout(executeQuery, 500);
}
$(document).ready(function() {
setTimeout(executeQuery, 500);
});
For who is facing my same problem, I solved it by replacing
$('#mydiv').html(data)
with
$('#mydiv').load('/mycontroller/index #mydiv')

Use setInterval() instead of using setTimeout().
Ref: https://www.w3schools.com/jsref/met_win_setinterval.asp
function executeQuery() {
$.ajax({
type: 'GET',
url: 'example.com/url/', // Provide your response URL here.
success: function(data) {
$('#mydiv').html(data);
}
});
}
setInterval(executeQuery(), (n * 1000)); // Replace 'n' with how many seconds you want.
This code will run the executeQuery() method in every 'n' seconds interval. So that your requirement is accomplished.

Set layout to false in the action and just pass on the relevent content, not the entire page
def action1
<your code here>
end
def action2
<your code here>
render :layout => false
end
Your view for action2 should have content pertaining only to #mydiv.
A better solution would be to use a single action and change render options based on type of request. (Ajax or non ajax)

Related

Using same form as local and remote both in rails for filtering purposes

Scenario:
I have a form that does some filtering. For the sake of simplicity, let's assume I have a form that has three input options:
<%= form_tag(some_path,method: :get) do %>
#..checkboxes for option 1
#..radiobuttons for option 2
#..checkboxes for option 3
<%= submit_tag "submit" %>
<% end %>
<p>You have a total of: COUNT results.</p>
Required Output:
What I want is the functionality when a user clicks on any checkbox or radio button, (essentially a change in any input field), by ajax request should be generated to a path that returns a COUNT of total results, and I will update the COUNT inside p tag with that returned count number.
And when the user clicks on submit button, the default GET request should be generated.
I added this script for ajax request, and it is working perfectly fine.
<script>
$(".option").change(function(){
var type = $("input[name='type[]']:checked").map(function () {
return this.value;
}).get();
$.ajax({
url: "/gre",
type: "put",
dataType: "json",
data: {custom: 'true',type: type},
success: function (response) {
var count = response["count"];
$('#count').html('Your session will have a total of '+ count + ' questions.');
}
});
});

Partial view not getting updated on click of button ruby rails

From file soul.html.erb , partial view called at the time of page load
<%= render 'contact_options_soul_d' %>
In file contact_options_soul_d.html.erb partial view looks like this -
<div id="contact-option">
<div id= 'un-authenticated' data-access-api-result = <%= #valid_ticket %> %></div>
</div>
On click of a button a Rest call happens in controller and partial view is called from partial_create.js.erb
def partial_create
respond_to do |format|
format.js
end
return
end
File partial_create.js.erb
$('#contact-option').html('<%= escape_javascript(render :partial => 'rhythm/contact_options_soul_d') %>')
My Question is - partial view is called , breakpoint hits and new value of #valid_ticket also gets updated, but view is not getting updated as webpage still looks same even after updation.(View remains same when checked in browser inspect)
Please help!!!
This is not an answer to exactly the way you're doing it, but you could always render it in the controller and return that on "respond_to", then on Ajax success use the returned value to substitute the html:
def partial_create
html = (render_to_string partial: 'rhythm/contact_options_soul_d', locals: { if_you_need: variables_in_partial })
respond_to do |format|
format.json { render json: { new_html: html, success: true } }
end
return
end
then on your JS code (this with jQuery):
function soul_searching(parameters) {
$.ajax({
url: "YOUR/POST/ROUTE",
type: "POST",
dataType: "json",
data: {
any_parameters: 'you_need_to_pass_to_controller'
},
success: function(data) {
$('#contact-option').html(data['new_html']);
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
//DO SOMETHING
}
});
}
You need to prepend partials with an underscore. For example:
_contact_options_soul_d.html.erb
Note: You only need to do this to the file name. You can still call the partial with
<%= render partial: 'contact_options_soul_d.html.erb' %>
Also make sure you're referencing the path if the partial is in a separate folder.

View rails record details in bootstrap modal on row click

I have been stuck on this problem for quite some time now and looked through several posts as well, however I cannot achieve exactly what I want for my Rails application. Essentially, I want to be able to click on a table row on my page and have a modal pop up which displays all the information for that specific record. Here are the scenarios which I have thought of/attempted partially:
Set the data-link attribute in table row with some JS as follows
HTML:
<tr data-link="<%= kid_path %>">
...
</tr>
JS:
$("tr[data-link]").dblclick(function() {
window.location = $(this).data("link")
})
This worked fine to open the show path page generated by the scaffold, but I was not able to modify it to work with a modal and have the same data for the kid in the modal.
Use data-id and JavaScript to load onto the modal
HTML:
<tr data-id="<%= kid.id %>">
...
</tr>
JS:
$(function () {
$('#showModal').modal({
keyboard: true,
backdrop: "static",
show: false,
}).on('show', function () {
});
$(".table-striped").find('tr[data-id]').on('click', function () {
debugger;
$('#showDetails').html($('<p>' + 'Kid ID: ' + $(this).data('id') + '<%= Kid.find(30).first_name %>' + '</p>'));
$('#showModal').modal('show');
});
});
In this approach I am able to load the modal on row click and am able to access the Kid ID, however I cannot move further to access other attributes of the record. For example, I want to set #Kid = kid.find(id) using JS where id would be the extracted ID from the row. And then, I want to be able to write the generic modal template which displays other elements (ex. kid.first_name, kid.last_name, etc).
I am totally stuck and cannot find any approach that helps to accomplish my goal. Any help is appreciated, thank you.
You need to ajax call record attributes because the line Kid.find(30).first_name doesn't exist at the time page loaded.
Try this:
KidsController
def show
kid = Kid.find(params[:id])
respond_to do |format|
format.html { // Usually show.html.erb }
format.json do
# Return kid as json object
result = {
first_name: kid.first_name,
last_name: kid.last_name
}
# If you want to return the whole kid record attributes in json: result = kid.attributes.to_json
render json: result
end
end
end
Try /kid/[:id].json to verify that you are not getting UnknownFormat error.
JS
$(".table-striped").find('tr[data-id]').on('click', function () {
var kid_id = $(this).data('id');
$.getJSON("/kid/" + kid_id, function(data) {
// Render the modal body here
// first_name = data.first_name, last_name = data.last_name etc
$('#showDetails').html($('<p>'+ data.first_name + '</p>'));
$('#showModal').modal('show');
});
})
If you have setup correct route for Kid model then these are what you needed.
UPDATED: I made a typo in the result hash. FIXED

Update progress bar in rails using jQuery

I'm a complete novice in JavaScript/jQuery and I believe it's a very simple question; however I'm not being able to accomplish it.
I have an asynchronous task being performed (by sidekiq) and it's progress is available by a method from the model (percentage_complete) that retrieves its progress from Redis.
I want to display a progress bar in model's show view, and I want it to update every x seconds using AJAX.
The progress bar is being displayed like this on the show.html.erb file:
<div class="progress">
<div class="bar" style="width: <%= #model.percentage_complete %>%;"></div>
</div>
How can I set a jQuery script to update this attribute asynchronously?
EDIT
I also have a a :status attribute which is set do "done" when the task is complete. I would like to stop updating when that happens.
By reading my question it appears that I haven't tried nothing and just want someone to write the code for me. Let me add some comments:
I know I should use setInterval to update the attribute every "x" seconds
I know I should use $('.progress .bar').width(<%= #model.percentage_complete %>%) to set the new percentage
However, since I'm not familiar to jQuery and JavaScript, specially in Rails, I'm not sure if this script should be loaded in a view, or if it should be a view itself.
I solved it by creating an action to retrieve the status
# GET /status/1.json
def status
#batch = Batch.find(params[:id])
respond_to do |format|
format.json
end
end
and using the following JavaScript:
<script type="text/javascript">
function progress(){
var progress = setInterval(function() {
var $bar = $('.bar');
var $pct = $('#pct');
$.get("<%= #batch.id %>/status.json", function(data){
if (data.status == "done") {
location.reload();
} else {
$bar.width(data.progress+"%");
$pct.text(data.progress+"%");
}
});
}, 800);
}
$(document).ready(function() {
$.get("<%= #batch.id %>/status.json", function(data) {
if (data.status == "processing") {
progress();
}
});
});
</script>

Cannot render JavaScript from Rails controller

I want to display a modal window with an error message, when the user has entered something invalid in a form, but render another action if everything is OK. However, when I try to display the modal window with
render :js => "jQuery.facebox(#{...})"
only the actual JavaScript called is displayed:
try {
jQuery.facebox(...)
} catch (e) { alert('RJS error:\n\n' + e.toString());
alert('jQuery.facebox(\"<div class=\'error\'>Error</div>\")');
throw e;
}
Have you tried putting the code in a partial? So instead of
render :js => "jQuery.facebox(#{...})"
try
render :partial => "my_facebox_popup"
Then inside of your _my_facebox_popup.html.erb partial put your code:
<script type = "text/javascript">
...
</script>
debug any errors you get with firebug.
Try this
render :update do|page|
page << "jQuery.facebox(#{...})"
end
Maybe you should specify in the jQuery call the dataType of the response you're waiting for.
E.g.:
$.ajax({
url: "/controller/action/id",
success: function(){
$(this).addClass("done");
},
dataType: 'script'
});

Resources