Mark Wilbur
Mark Wilbur

Reputation: 2925

Update and save a variable to the database in Rails3 , jQuery and AJAX (without a form)

I'm working on a site where I've got a page where a user can choose a cover image for a video, from a set of screenshots. I've got the images all displaying in a grid, and I've added jQuery so that whichever video was last clicked by the user is "selected" and has a frame around it.

What I need help with is writing this to the database. All I'm looking for is a way to save this selection.

This is what I have now. In the videos controller:

  def cover_selected
    @video.cover_url = params[:selected_cover]
    @video.save
  end

And this is in the videos/show.html.erb:

<%= stylesheet_link_tag 'application.css' %> 
<% provide(:movie_url, @h264_encoding.url) %>
<div class="container">
<% if @original_video.status == "success" %>
  <div id="strobemediaplayback">Movie goes here!</div>
  <br/><h2>Select a cover image</h2>
  <% @h264_encoding.screenshots.each_with_index do |screenshot,i| %>
    <% if i%3 == 0 %> 
        <div class="row">
    <% end %>
    <div class="span3" style="margin-bottom:20px"><img class="screenshot" id="<%= i %>" src="<%=  screenshot %>" />
    </div>
    <% if i%3 == 2 %>
        </div>
    <% end %>
  <% end %>
<% end %>
</div>

<script>
  $(document).ready(function(){
    $('div.row img').click(function(e) {
      e.preventDefault();
      $('div.row img.selected').removeClass('selected');
      $(this).addClass('selected');
      $.ajax({
       url: '/videos/cover_selected/',
       data: { selectedCover: this.id },
      });     
    });
  });
</script>

And my video schema includes:

  create_table "videos", :force => true do |t|
    t.string    "title"
    t.timestamp "created_at",       :null => false
    t.timestamp "updated_at",       :null => false
    # ... and so on
    t.string    "cover_url"
  end

How do I update the cover_url attribute of @video?

Upvotes: 1

Views: 1350

Answers (2)

Mark Wilbur
Mark Wilbur

Reputation: 2925

You need 3 pieces working in unison to do this--

1) an action in your controller 2) the appropriate jQuery in your show.html.erb, and 3) a route so that rails can sent the incoming data to the right action.

The action in the controller was close, this will work:

  def cover_selected
    @video = Video.find(params[:video_id])
    @video.update_attribute(:cover_url, params[:selected_cover])
    respond_to do |format|
      format.all { render :nothing => true, :status => 200 }
    end
  end

The jQuery code was okay, but it can be updated to also show what cover was selected when you got to the page:

  $(document).ready(function(){
    var video_id = <%= @video.id %>;
    $('div.row img[id=<%= @video.cover_url || 0 %>]').addClass('selected');
    $('div.row img').click(function(e) {
      e.preventDefault();
      $('div.row img.selected').removeClass('selected');
      $(this).addClass('selected');
      $.ajax({
       url: '/videos/cover_selected/',
       data: { 'selected_cover': this.id,
               'video_id': video_id },
      });     
    });
  });

And finally, in Rails 3, you need to add a route so that Rails knows what to do with the request!

  get 'videos/cover_selected'

Make sure you put that above the line with resources :videos so that Rails doesn't look for a video with id=cover_selected.

Upvotes: 1

Terry
Terry

Reputation: 14219

You need to use an asynchronous call to the server (AJAX).

$('div.row img').click(function(e) { 
    e.preventDefault();  // FYI - only need this for <a href="" /> elements

    $.ajax({
       url: '/mysite/saveSelectedCover/',
       data: { selectedCover: this.id },
       ...
    });     
});

Everything you need to know about jQuery's AJAX function can be found in their docs. http://api.jquery.com/jQuery.ajax/

Upvotes: 0

Related Questions