show flow player with using AJAX - ruby-on-rails

I am using flow player in my site to view the videos , Now on the index view i have all the videos . but to show that video i have made remote_link to open it on the same page
I got the video on the page too , but it is not displaying , i can even save the video by clicking it , but i cant see the player at all my code is
controller
#video = Upload.find_by_id(params[:id])
render :update do |page|
page[:"div_video_#{#video.id}"].innerHTML = render :partial => "display_video"
page[:"div_video_#{#video.id}"].show
end
Waht i want is to dispaly the video by ajax call from controller , please help me?

The problem is that the flowplayer function has already been initialized on the page, and so won't affect any new html you put into it, you'll need to recall the flowplayer function after the page has been updated, something like this:
#video = Upload.find_by_id(params[:id])
render :update do |page|
page[:"div_video_#{#video.id}"].innerHTML = render :partial => "display_video"
page.flowplayer("player", "path/to/the/flowplayer-3.1.5.swf")
page[:"div_video_#{#video.id}"].show
end

Related

How to pass object to partial using controller?

I've been trying to pass my Product object to my rendered partial but no matter what I try it doesn't work. The home page has a quick view button that pops a modal (the partial) and I want to pass the correct product to it.
Route
get 'shop-product-ajax-page', to: "pages#shop_product_ajax_page"
Home Page (shortened to only the link for brevity)
<% #products.each do |product| %>
<%= link_to "Quick View", shop_product_ajax_page_path, :data => {:lightbox => 'ajax'} %>
<% end %>
Controller Action
def shop_product_ajax_page
render :partial => 'pages/shop_product_ajax_page', :layout => false
end
Right now, the button works and displays the HTML in the modal. I want to be able to populate the correct product information for whatever Quick View product is selected.
The problem is that the link is making a completely separate AJAX request, it's hitting the server separately, so the Ruby context you expect (variables etc) isn't available in that new request.
Two choices:
Don't make an AJAX request but render the lightbox as part of the page. You could hide it using display: none or similar, then use Javascript to display it when the link is clicked.
Make the request the way you currently are, but pass in the same parameters that your current controller action is using to get #products and in shop_product_ajax_page do the same thing to hit the database and get the products.
The second choice might be easier without messing with JS. It would be something like:
def shop_product_ajax_page
#products = get_products_from_params(params)
render :partial => 'pages/shop_product_ajax_page', :layout => false
end
private
def get_products_from_params(params)
Product.find(params["product_ids"]) # or whatever you're currently doing
end

Declare a variable in Link so Controller loads separate layout in Rails

I have a link that calls this:
<%=link_to 'Free Trial', '/sign_up', :rel => "#signup", :class => "sign_up_button"%>
Which renders mysite.com/sign_up - This loads a partial in a Jquery light box. However What I would love to do is have a controller statement where if the link above is clicked it renders the page with no layout. But if the user navigates to mysite.com/sign_up from the address bar, they see the same page but with a layout.
I am thinking in my controller something like this:
def sign_up
if :variable == true
render :layout => false
else
render :layout => 'layouts/sign_up'
end
end
then in my link declaring a variable it can pass to the controller? something like
:variable => 'true'
I am thinking about this in the right way? How would the above work?
The main reason for this is so that if mysite.com/login is loaded on its own (without Jquery) then it will still look good!
Thanks
You have two ways :
You can do as you are thinking, and set your partial flag via POST. Replace /signup with /signup?partial=1 and in your controller if params[:partial]
Or you can render conditionnaly looking at request.xhr? (but ajax headers must be setted correctly by your js framework)

Partial not updated on first click

I am having problems with a remotely executed action and a partial that doesn't update the first time I click the link.
Inside the view (a partial named books) I am creating a link:
link_to "⊗", read_book_path(book), :remote => true
The read_book_path is defined in routes.rb
There is also a conditional that displays a different text when that book is read.
Inside my controller, I have defined a new action:
def read
#books = Book.all
#book = Book.find(params[:id])
#book.read = !#book.read
#book.save
respond_to do |format|
format.html { redirect_to(books_url) }
format.js {render :layout => false, :locals => { :book => #book } }
end
end
This means I need a file read.js.erb, this file's content is:
$("#books").empty().html("<%= escape_javascript( render(:partial => "books") ) %>");
When I click the link, I can see in the terminal window that the database field is updated but the partial is not. Clicking the same link again updates the partial.
Changing the link to :remote => false also works but the page reloads (as expected).
I have tried to debug it with Safari and the Developer tools and I can see the server's response when clicking the link for the first time.
Something is wrong there, the HTML generated by <%= escape_javascript( render(:partial => "books") ) %> contains the wrong HTML with the old content of the partial. Only the second or third click shows the updated HTML.
I have integrated jquery-ujs - is that the reason the partial doesn't update the first time or am I missing something else?
This really gave me a headache, can you help me?
Edit:
If that helps: I created a listener in application.js to ajax:before and ajax:complete. The first one shows a little spinner, the second one hides it.
When I click the link, the spinner shows but it doesn't hide.
It looks like you have an ordering problem that's causing the trouble. You're capturing a complete set of books into the #books variable and then modifying a separate copy of a single book. This change will not be propagated back.
# Load and modify the one book by flipping the flag
#book = Book.find(params[:id])
#book.read = !#book.read
#book.save
# Load all books
#books = Book.all
As a note this is an extremely inefficient way of doing things, so I hope you're not working on a large amount of data. You might find it's easier to do this by simply toggling the one field with a simple UPDATE query:
Book.update_all({ :read => true }, { :id => params[:id] })
I'm not sure why you're calling $(...).empty().html(...) instead of simply $(...).html(...) since the html() method should replace the HTML wholesale with no need to clear it in advance.
One thing that might help is using .js.rjs where the equivalent would be:
page[:books].replace_html(:partial => 'books')
With simple JavaScript, RJS allows you to eliminate a lot of the drudgery. You can use JS in RJS as well for cases where there is no equivalent:
page << '$("#books").empty()'
page[:books].replace_html(:partial => 'books')
To make this more Rails friendly, you could call your partial _book which would make the local variables redundant. Each partial has a default variable with a name matching the template name:
render(:partial => 'book', :collection => #books)

how can I cache a partial retrieved through link_to_remote in rails?

I use link_to_remote to pull the dynamic contents of a partial onto the page. It's basically a long row from a database of "todo's" for the day.
So as the person goes through and checks them off, I want to show the updated list with a line through those that are finished.
Currently, I end up needing to click on the link_to_remote again after an item is ticked off, but would like it to redirect back to the "cached" page of to-do's but with the one item lined through.
How do I do that?
Here is the main view:
<% #campaigns.each do |campaign| %>
<!--link_to_remote(name, options = {}, html_options = nil)-->
<tr><td> <%= link_to_remote(campaign.name, :update => "campaign_todo",
:url => {:action => "campaign_todo",
:id => campaign.id
}
) %> </td></tr>
<% end %>
</table>
<div id="campaign_todo">
</div>
I'd like when the New/Create actions are done to go back to the page that redirected it there.
When someone wants to "do" a task, it takes them to the new action. here is the controller:
def create
#contact_call = ContactCall.new(params[:contact_call])
if #contact_call.save
flash[:notice] = "Successfully created contact call."
redirect_to contact_path(#contact_call.contact_id)
else
render :action => 'new'
end
end
I switched to redirect_to :back, which takes me back to the main view shown above...but WITHOUT the PARTIAL. It means I need to reload the partial all over again, which is a time-consuming database call.
1) Is it possible to go back to a view that has a partial called through AJAX and still have those results show up?
2) Can that result, however, be marked via CSS to indicate that it has been "checked off"?
I would render the to-do list item response from javascript ERB files. So when you make the link_to_remote call, instead of redirecting back to the page, instead render javascript.
You'd have the form in /app/views/contact_call/_form.html.erb
/app/views/contact_call/create.js.rjs
page.replace :contact_form, :partial => "contact_call/form", :locals => { :user => #user }
page.visual_effect :highlight, :contact_form
Your controller would then render the javascript, which would in turn replace html on your page with the latest version (and highlight it). And your page would load the partial with strike-through on completed items.
you have to create an ajax call when you mark one item as 'done', in this action you'll need to
update your list item to add the 'line-through' to text-decoration
create a method like 'after_save', to expire your cache
you can read about the CSS 'line-through' here:
http://www.icelab.eu/en/blog/css-4/xhtml-and-css-strike-alternatives-86.htm
and the documentation for expire_page and expire_action is here:
http://api.rubyonrails.org/classes/ActionController/Caching/Sweeping.html
I think you may be able to use action caching on your index action, or whatever the name of the action is that renders your main page.
You can also do page caching and fragment caching, which would work with partials. For more information on Rails caching strategies, see the rails guide:
http://guides.rails.info/caching_with_rails.html

Rails Rendering Action in Different Controller

So I have a controller called Music with one action which is index. On the music/index.html page I list out a bunch of Songs (via a Song model) and at the bottom I have a for to create a new Song.
Song has validations which I have tested and work just fine. When the new Song saves in controller Songs action create I redirect_to => 'music_index_path' so the person can see the new song in the list. However when the Song does not save (does not pass validations) then I cannot use redirect_to since the form error_messages do not carry over. I need to use render but cannot say render :controller => 'music', :action => 'index.
My goal is to be able to show the error messages for the Song form ON the music/index.html page.
How should I go about this. I am open to other ideas (like changing up controllers) as well.
Thanks!
It sounds to me like Music should be a part of Song, or the other way around. You can always use routes to disguise it as one or the other to the user.
song/index sounds to me like it should display all songs, which is all music does anyway.
My first thought is that we need to rethink this process. Assuming you're using RESTful controllers, it's unclear to me why you would need a Music controller and a Song controller... how are those resources different? The next relevant question would be, why is it not sufficient to show errors via Song#create ? I mean, they couldn't get it right when it was just a form, is the distraction of additional content likely to help? :)
With that said, here is a possible solution. (Given that you didn't paste your code, I'm making a lot of assumptions here.)
<hack>
first, extract the form parts from songs/new to songs/_form, then from the music/index view, render :partial => songs/_form, and in the songs controller, render :action => '../music/index' (this is called a hackity-hack.) Because it's a hack, you will almost certainly need to go into music#index and add #song = Song.new
</hack>
If you start running on edge, the ability to pass a flash through a redirect was just added...but that doesn't really get you there.
The simplest solution though, is that you need to render index, but set up all of the variables that are needed for that page. If you factor that out into a separate module or method, you can call it from both the index action and the save failure.
def index
setup_for_index
end
def create
#song = Song.new(params[:song])
#song.save
#...
#on failure
setup_for_index
render :controller => "music", :action => "index"
end
def setup_for_index
#songs = Song.all
#etc
end
The other thing you could do is use form_remote_for and have the song form just update the div on failure. Then use an RJS template return type reload the whole song list on success.
While I want to reiterate what others have stated about your resource architecture deserving a second look, you can certainly render views for other resources using the :template option:
render template: 'music/index'
Why not a simple if request.post? conditional in the index action's view rather than redirecting to another page?
You can also try using flash[:song_save_error] to pass the error conditions back to your Music controller.
http://api.rubyonrails.org/classes/ActionController/Flash.html
You could try render :file => ...

Resources