RoR facebox for prototype - ruby-on-rails

I've got facebox working using the following tags in my rails app
<%= link_to 'test' some_path, :rel => 'facebox' %>
Now that works perfect if the page is already loaded.
However, I have ajax updates on certain parts of the page which contain new links like the one shown above.
When you click the links from an ajax update facebox doesn't work follows on to the template.
I believe since the page doesn't refresh the source code is the same and :rel => 'facebox' doesn't work.
Does anyone have any advice on how I can get this to work without refreshing the page?
I've tried this in a method in a controller.
render :update do |page|
page << "
facebox.loading();
facebox.reveal('text', null);
new Effect.Appear(facebox.facebox, {duration: .3});
"
end
However, for some reason in chrome and IE the facebox appears for a brief second and then disappears.
Any advice? I've been banging my head off the wall all day.
Thank you

All you need to do, is ensure that you're making a javascript call to facebox somewhere in the view of your AJAX response: arguably the best location would be in the layout file. Just make sure that you include the following:
#app/views/layouts/ajax.html.erb
#...snip...
<% javascript_tag :defer => 'defer' do -%>
jQuery(document).ready(function($) {
$('a[rel*=facebox]').facebox();
})
<% end -%>
or with prototype (untested):
#app/views/layouts/ajax.html.erb
#...snip...
<% javascript_tag :defer => 'defer' do -%>
document.observe("dom:loaded", function() {
$$('a[rel*="facebox"]').facebox();
});
<% end -%>
This will ensure that any new links that appear on the page, as part your AJAX updates, will be handled by facebox.

Related

Render some content on Rails view

I am new to Rails, so I'm not sure if this is the correct way to go about doing this. I have a view that contains an AJAX link for a number of checkboxes in the form of
<% #row_headers.each do |row_header| %>
<% row_header_ = row_header.gsub(" ", "-") %>
<%= check_box_tag row_header_, row_header, params.key?(row_header_),
:data => { :remote => true,
:url => url_for(
controller: :web_pages,
action: :administratorswgraph} %> <%= row_header %>
<% end %>
<% end %>
This is being called from the :administratorswgraph view. Later on in the file I have
<% if not #swChart.nil? %>
<div id="swChart"></div>
<%= render_chart(#swChart, 'swChart') %>
<% end %>
Where render_chart is from the GoogleVisualr library. On the controller I have
def administratorswgraph
headers = []
#row_headers.each_with_index do |row_header, i|
if params.key? row_header.gsub(" ", "-")
headers.push i
end
end
if headers.empty?
#swChart = nil
else
#swChart = MakeSiteChart(headers, 580, 480)
end
end
Where the MakeSiteChart function returns a GoogleVisualr object based on the checkboxes. What I want is that for every time the checkbox's state is changed a new chart is made and shown. I can tell from my debugger, that indeed <%= render_chart(#swChart, 'swChart') %> is getting called in the view whenever a checkbox's state is changed, however the display in the browser is never updated. How do I get the display in the browser to show the chart?
Edit
I was able to get control of the ajax event by using the following method
$('#<%= #row_headers[0].gsub(" ", "-") %>').on('ajax:success', function(event, xhr, settings) {
alert("HERE")
});
For testing purposes I'm only hooking up the first checkbox. However, I'm not sure how to parse the arguments, how to get the chart, and how to insert it back into the DOM.
If your controller is RESTful then web_pages#administratorswgraph can answer to html and ajax with separate view (say administratorswgraph.html.erb and administratorswgraph.js.erb).
Place in administratorswgraph.js.erb all your logic responsible for replacing the entire chart... I think its enough to place <%= render_chart(#swChart, 'swChart') %> there, but Im not sure.
assuming that you are using jQuery and so jQuery-UJS, you can hook into the AJAX-Callbacks and replace the chart in your dom with the response that came from the server: https://github.com/rails/jquery-ujs/wiki/ajax
unfortunately, there is no good example for this on guides.rubyonrails.org...
After messing around with this a lot I was able to come up with a satisfactory solution. I used the following JavaScript within the view
<script type="text/javascript" charset="utf-8" id ="myScript">
<% #row_headers.each do |row_header| %>
$('#<%= row_header.gsub(" ", "-") %>').bind('ajax:success', function(event, data, status, xhr) {
var scripts = $(data).filter('script')
var chartScript;
scripts.each(function(index, Element){
if (Element.text.indexOf("swChart") != -1 && Element.id != "myScript") {
chartScript = Element.text;
}
});
jQuery.globalEval(chartScript)
});
<% end %>
</script>
This allowed me to extract the JavaScript that needed to be run after the ajax request came back and I was able to run it.

How to pass a lambda to link_to

I would like to use lambda as a parameter for link_to for the code below: edit.html.erb
<h2>Edit customer info</h2>
<%= render 'form' %>
<%= link_to(#return_to) do %>
Back
step_back()
<% end %>
Here is the def for step_back:
#return link for previous page in page step
def step_back
session[:page_step] -= 1
end
The problem with the code above is that the step_back() is executed as soon as the edit.html.erb is loaded. Actually the step_back should only be executed when the user clicks the Back link. I figure that only lambda can accomplish this.
Any thoughts?
Your options are limited since you're interacting with the session.
You're getting that #return_to from somewhere; it'd probably be easiest to call an action that gets the same data and redirects to it, and does the same session manipulation.
See about writing your step_back() function in javascript and attaching it to an onClick html attribute on an tag instead of using the link_to rails helper
Then also .preventDefault() the event with javascript if you don't want the link to go anywhere, or to '#'
This will allow the code to execute on the click event in the browser and not during asset compilation before the page is served.

Render a partial in rails using jquery

I am trying to setup a navigation bar on my home page that loads a partial into a div element when the user clicks on the links. I have followed the steps in this post and modified them as I thought I needed:
Rails 3 - link_to to call partial using jquery ajax
My code:
views/pages/home.html.erb:
<%= link_to "Files", :action => 'load_upload_partial', :remote => true %>
.
.
.
<div id="main_frame"></div>
pages_controller:
def load_upload_partial
respond_to do | format |
format.js {render :layout => false}
end
end
/views/uploads/load_upload_partial.js.erb:
$("#main_frame").html( "<%= escape_javascript( render( :partial => "/upload/upload_form" ) %>" );
The partial in this example is just a form. When I click on the link I get a blank page with this is the address bar:
http://localhost:3000/load_upload_partial?remote=true
This makes me think that link is not triggering an ajax GET request (if that's the correct terminology). If that is the case is there anything I need to be adding to my application.js file? I followed the railscast #136 on rails and jquery but couldn't figure out which bits of the application.js code applied to my case.
Any thoughts are much appreciated. Thanks. Tom
I now tend to avoid using RJS like you're intending to. I prefer creating js templates with tools like handlebars.
I only use ajax to get raw data and then recreate the partial client side. It's much better for server load and data transfer.
I think you have to change your link_to to:
<%= link_to "Files", {:action => 'load_upload_partial' }, remote => true %>
The problem is related to the method signature of link_to.
ran into this same problem - the hint was in the malformed html produced - take a look at the value of the href attribute of the tag produced by your code. I bet it looks funky. Here's the correct code:
<%= link_to "Files", your_path, action: 'load_upload_partial', remote: true %>
have you tried using .load() instead of .html()?
Also, try using this line instead:
$("#main_frame").html( "<%= escape_javascript( render( :partial => '/upload/upload_form' ) %>" );

How to update a 'div' content after that ActiveRecord values are changed without reload the page?

I am using Ruby on Rails 3 with Prototype/Scriptaculous and I am trying to update a 'div' content after that ActiveRecord values are changed, without reload the page.
In the "edit.html.erb" I have:
...
<div id="test_id">
<%= #account.name.to_s %>
</div>
<%= link_to_function( "Make test" ) do |page|
page.replace_html :test_id, #account.name.to_s
end %>
...
Before clicking on "Make test" I update the '#account.name' value, even via AJAX. Then, clicking on "Make test", the template doesn't changes.
These are steps:
I show the page
I update '#account.name' via AJAX
I click on "Make test"
'div' with 'id="test_id"' doesn't change!
What am I doing wrong?
P.S.: I think that #account is not reloaded in the page, also if his values are changed in the database. If so, what should I do?
I have seen the Railscasts "AJAX with RJS" and I followed an example in that (it is like the my), but it doesn't work for me.
If you have rendered edit.html.erb when the value of #account.name is "George", the HTML will remain the same (with the value "George") until you refresh it. Your call to link_to_function is, on page load, rendering an html link that calls javascript that replaces the inner html of the "test_id" div with 'George'. Unless you replace that HTML, it will always replace the inner html of that div with 'George'.
It's hard to recommend a solution without knowing exactly what you'd like to do...
updated to have more detail:
If you are making an AJAX call that changes the value of the account name on the server to "Fred", and want that change to appear on the page, you should refresh the parts of the page that use that value in that same AJAX call (that same controller action).
Your link_to_function generates HTML like this (if #account.name was 'George' when the page was rendered):
<a onclick="try { Element.update("test_id", "George"); ... >Make test</a>
It is not an ajax call, it is just a link that executes javascript. If you want to make it an ajax call that finds the latest value of the account name and refreshes the test_id div, do something like this:
<%# you need prototype included, but it should probably be in application.rhtml %>
<%= javascript_include_tag "prototype.js" %>
<div id="test_id">
<%= #account.name.to_s %>
</div>
<%= link_to_remote "Make test", :url => { :controller => "account", :action => "change_name" } %>
The 'Make test' link will now perform an AJAX call to the 'change_name' method in the 'account' controller. This method would look something like this:
def change_name
# here you would load the account from the db; I'm cheating
#account = Account.new(:name => "Fred")
render :update do |page|
page.replace_html :test_id, :text => #account.name.to_s
end
end

using ajax in rails with periodically_call_remote

I am attempting to reload a partial on a page periodically but it does not seem to be working. The partial loads correctly when I first load the page but it will not update when I introduce new info to it without reloadig the page. The view looks like:
<div id="menuarea"style="height: 399px; width: 181px">
<%=periodically_call_remote(:url => {:action => :findnew}, :frequency => '20', :update => 'menuarea') %>
<p> Please select a color </p>
<%#partil renders the color table %>
<%= render :partial => "colortable" %>
</div>
and the controller looks like:
def findnew
#bunny= Xparsing::Xmlparse.new
#fuzzybunny= #bunny.hex1
#pinkbunny=#bunny.pantone1
#blackbunny=#bunny.description1
render(:partial => 'colortable')
end
All I am attemptinging to do is reload the partial colortable without reloading the page. I am seeing the render color table in the comand line every 20 seconds but the table is not reloading on the page What do I need to fix?
Are you sure you are not overwriting the Javascript containing periodically_call_remote when you update the <div>?
Don't you want to put that script outside the updating <div>? Or put it into the partial and remove it from where you have it now.
turns out it was an issue with jquery and prototype. I removed jquery and it worked perfectly. Still trying to figure out why

Resources