I have pagination + parameters set up over ajax, and working properly.
However, when first loading the page, it takes a while. Is it possible to first load the view, and then load the content over ajax (just like clicking page 2 would for pagination over ajax)?
EDIT/
Is it really stupid to use a parameter conditional? Like in my controller around my query if params[:load] == "ajax" as well as the parts of the view that use this data. And in jquery, when the document is ready (view loaded), call the parameter with a get: $.getScript(window.location.pathname + "?load=ajax");
???
I have done it quite a lot. Load the whole view first, which contains some basic layout, then load the actual important contents using ajax. So in my controller:
class PriceController < ApplicationController
def price
# do something in order to render the page price.html
end
def price_f
# render the partial which contains heavy sorting of datas
render :partial => "price_f"
end
end
in jquery
$(document).ready(function(){
$.ajax({
url : "/price_f.html?page=1"
success: function(data){
$("#price_container").html(data);
}
});
})
Assuming you're using jQuery, you should be able to just do something simple like this after the document is ready. Really, all you're doing is telling your pagination URL that you want Page 1 instead of Page 2, etc.
$(document).ready(function(){
$.get({
url: "/url/for/your/page/data"
});
});
To get rid of the current initial page load (I would have to see your specific code to tell you exactly what to remove/change):
Remove whatever code is in your controller that does the query, loads the data, etc.
Remove the parts of your view that are then using this initial data, maybe just sticking a loading gif in there until it's replaced by your ajax data.
Fire the ajax request -- the page will be loaded while it waits for the controller to sort and deliver the data.
Related
I have this webshop, and on one page you see
products;
with a submitting form for a booking;
your order with its bookings;
with a removing link for a booking;
and an updating form for a booking.
Both the order.bookings and the products make potentially long lists on a html page.
The whole booking works by only a booking_controller.
What the booking_controller does:
Takings in the (new) params of a single booking or the destroy action.
Saves the new order.
Redirects to the store.
Works fine, just using ruby and html.erb.
Only problem, and this really needs to change, is that obviously after each redirect the browser goes to the top of the page. The browser isn't focussed. Or better to say, the browser should remain, but doesn't.
I get that your doing all these things on the server-side, so a page reload, or better to say, data-refresh, is necessary. What I don't want is building this whole thing again on the client-side (JS).
Can't I simply say something like: after data refresh redirect to exact same spot on page. Ignoring all the difficulties an asynchronous request would give, or am I exaggerating and is a little JS easy?
With Rails, using ajax is very easy however if you're not familiar with ajax at all it can be a bit daunting at first. Luckily there are many tutorials on the subject. Basically, add the remote: true option to your form_for statement and rails will automatically understand you want it to make a 'POST' request in JS format. It's important to realize that the incoming HTTP request is in JS format because you'll then need to specify handling that event in the controller. Such as:
def create
#Do whatever saving and processing you need here
respond_to do |format|
format.html { redirect_to some_path_here }
format.js { } #By not adding anything in the brackets here, you're telling rails to fetch a js view file that follows standard rails convention and so it should be named 'create.js.erb'
end
Then in your controller's views folder create the view file create.js.erb. In that file you'll want to refresh whatever part of the page needs updating which usually involves hiding the old div that was there and appending a partial in its place. I usually leave an empty div with an ID on the page (in this case your new_whatever_page.html.erb that I then call in the js.erb file to append a partial to:
In your create.js.erb add:
$("#the-id-of-the-div-in-your-new-view-page").html("<%= escape_javascript(render 'order_table') %> #This basically says, find the div on the current page with a matching id and then append the partial named _order_table.html.erb to it.
Now just make a partial named
_order_table.html.erb
in the same views folder and put whatever content you want to insert or update.
I'm using ajax to update a partial, but i would like to get some data back from the server at the same time.
$('<%=escape_javascript #my_params.to_json%>');
$("#partial").html('<%= escape_javascript(render partial: "view/partial" )%>');
gives me the response with both data and partial rendering in it, but it breaks the Ajax render, so the partial is not rendered.
Using Rails 4, ROR. no errors in the browser or Rails
if i refresh the page i get the result i wanted.
I know this must be easier than i'm making it.
Assuming that you are using js.erb format for rendering ajax page.
Inside the view partial, write the code
run your js code here or assign to global js variable
I'll leave this here for edification, but my friends told me that they would disavow me if i abused a cookie this way. So i switched my implementation, can't afford to lose any friends. They told me to focus on making the turn around time for the ajax call fast. I still needed to know when the object had completed rendering so i simply added a hidden element in the partial and i set its size to zero and wait until the partial rendering changes the height from zero. It was pretty funny to see the interactions with two tabs open to the web page, even though i was planning to use the session ID avoid crosstalk.
Okay, I decided that for my purposes the best way was to put the data in a cookie and just detect when the cookie changed. This allowed me to change the cookie at the end of the send_data command and both get the data for the image position relative to the other image as well as detect when the send_data completed so i could slide the image into place (over the animated wait image).
it looks like this on the server
send_data(image.to_blob { self.format = 'png' },
type: 'image/png',
disposition: 'inline')
cookies[:duck_data] = { :value => $cookie_data.to_json}
and this on the client side
wait_for_paint=->
if $.cookie('duck_data') == 'keep waiting'
setTimeout (->wait_for_paint()), 250
else
my_data= $.parseJSON($.cookie('duck_data'))
do_ajax_response(my_data)
I am trying to implement two pages. The first page being a selection of the items I want to show on the second page.
On my first page, I have done a selection of the items which I want to render.
On click of a button, 1. the ids of these items will be placed in an array and 2. the user will be redirected to a new page through:
window.location.replace("/schedule");
Right now, I want to achieve the following:
Do an ajax call through rails to get each of the array items. i.e. make an ajax calls to the urls of myclass/[id]. The id belonging to the items in the array.
I am not sure how I could get my array items from the current page to the next page or if there is a better way of achieving this. Any advice or suggestion will be greatly appreciated.
Add :remote => true to your form. Then, app will render your action_name.js.erb view instead of action_name.html.erb. In js file you can put code, which will repleace div without redirection, f.e.
$('#div_id').html('<%= escape_javascript render(your_partial_name) %>');
You don't need to do anything special in partial and controller action, its all the same.
I have a page where I want to do an AJAX call and possibly render a partial every 30 seconds or so. Now, I know how to do this with jquery AJAX, doing an AJAX call and passing in the path, but it doesn't seem like the Rails way.
I say this because the result is that the main view does not show you the entire structure of the page. When you render a partial, you at least see the partial's positioning inside the document, if you render a partial via AJAX, you have to read the javascript code to know that it's there.
Is there a more unobtrusive (for lack of a better word) way to do this?
When I need to do something like this, and want the partial block to be positioned, I include a container div that I then render the AJAX call into. That was I can position the partial prior to it actually being rendered.
I am learning Ruby on Rails, and I am very confused on how the controller-model-view relationship works for my application.
What I have now is a table full of comments (posts) users have made. What I want to do is let users click on a comment to see more information in a separate panel (ie, other database fields that weren't initially shown, for example the user_id of the person who posted the comment).
In my _post.html.erb, I have something like:
<div class="post" id="<%= post.post_id %>" onclick = ?? >
<p>post.text</p></div>
What should go in onclick? I need a way for the onclick to call a helper/controller method which can load more information, and then put that in another div on a page (I've tried variations of using the controller and helper to call javascript which inserts html into the site, but that seems messier than it should be). From what I understand, I should create some kind of partial _postdetails.html.erb file that handles the actual displaying of the html, but I have no idea how to specific where that partial would go in the page.
Any help would be appreciated, thanks!
You can achieve what you want either by using Rails helpers or by writing the AJAX calls yourself.
Personally I manually write all my AJAX calls using jQuery.
You can also use Prototype which ships with Rails.
That being said you can do.
In your JS file :
$("div.some-class").click(function()
{
$.ajax(
{
url:"url/to/controller/action",
type:<GET>/<POST>,
data://If you wish to sent any payload
});
});
In your controller :
def some_action
#some computation
render :update do |page|
page["id_of_div_to_be_refreshed"].replace_html :partial => "some_partial"
end
end