chuck w
chuck w

Reputation: 1761

How to pass a div_id to jquery load function

I have a story model that has many posts. I list the stories in an index view without each story's posts. When a user clicks on one of the stories in the index view I want to load that story's posts via calling stories/(story_id)/posts using the ajax .load function, and make sure to put the posts into that story's correct div (created by "<%= div_for(story, "posts_bucket_for") do %>")

The problem is, I don't know how to pass the correct story_id to the .load function or how to make sure that the resulting posts are loaded into the correct posts_bucket_for.

Here's my _story.html.erb file:

<%= div_for(story) do %>
   <%= div_for(story, "heading_for") do %>
        <span class=story_title>
            <%= story.title.titleize %>
        </span>
        <span class=story_post_amount>
            # of posts: <%= story.posts.length %>
        </span>
   <% end %>
<%= div_for(story, "posts_bucket_for") do %>
<% end %>

Here's my PostController#index action

  def index
    @story = Story.find(params[:story_id])
    @posts = @story.posts
    respond_with(@posts, :api_template => :public, :root => :posts)
  end

Any help would be greatly appreciated!!!

Upvotes: 1

Views: 1117

Answers (2)

zequinha-bsb
zequinha-bsb

Reputation: 719

There are many ways of doing what you are trying to achieve and, I bet, many of the contributors here will give you a solution based on their coding experience. Here is mine:

First and foremost, you must decide if you need to keep the story title visible or not once you "upload" the actual story to the point you want.

I have no idea about ruby or ruby-on-rails but have a very good track on "blogging".

Let's say that from your database you listed the stories available as

<div id='story1' onClick='showStory(1); ' >Story 1</div>
<div id='story2' onClick='showStory(2); ' >Story 2</div>
<div id='story3' onClick='showStory(3); ' >Story 3</div>
<div id='story4' onClick='showStory(n); ' >Story n</div>

function showStory(storyNumber) {
    $.get('url-of-the-story-storyNumber', function (data) {
        $('#story'+storyNumber).html(data);
    });
}
or
function showStory(storyNumber) {
     $('#story'+storyNumber).load('url-of-the-story-storyNumber');
}

If you plan on not overwriting the story title line, you just drop another div into the story line:

<div onClick='showStory(1); ' >
 Story 1
 <div id='story1' ></div>
</div>

<div onClick='showStory(2); ' >
 Story 2
 <div id='story2' ></div>
</div>

<div onClick='showStory(3); ' >
 Story 3
 <div id='story3' ></div>
</div>

<div onClick='showStory(n); ' >
 Story n
 <div id='storyn' ></div>
</div>

The easier you make your IDs "manageable" the easier will be to make manuevers with them.

Good luck!

Upvotes: 2

maxenglander
maxenglander

Reputation: 4041

Here is one way to implement a solution (this is for Rails 3).

According to the Rails documentation for div_for, div_for(story, :class => "story") will produce HTML that looks like:

<div id="story_123" class="story"> Your content </div>  

So, with jQuery, you could run something like:

// Attach click event handlers to your story divs
$(function() {
  $("div.story").click(function() {
    // Get the HTML ID of the story div
    html_id = $(this).attr('id');
    // Extract the database id
    story_id = html_id.split("_")[1];
    // Call your handy function to load story posts
    loadStoryPosts(story_id);
  });
});

For your buckets, I would not use another div_for(story). This would result in you having two divs on the page with the same ID. Instead, I would do something like this:

<%= div_for(story, :class => "story") do %>
    <p>The story</p>
    <div class="posts" />
<% end %>

And then, in jQuery

// Make an AJAX request to your Rails server
function loadStoryPosts(story_id) {
  // This is a jQuery AJAX GET request to your stories/:id/posts route
  $.get("stories/" + story_id + "/posts", function(data) {
    html_id = "story_" + story_id;        
    // Insert the result of the request into the appropriate posts bucket
    $("#"+html_id+" .posts").html(data);
  });
}

The remaining task is to have a controller action handle the AJAX request and return the posts to be inserted onto the page.

class StoriesController < ApplicationController
  def posts
    story = Story.find params[:id]
    # Render the story's posts inside a partial (without any layout)
    render :partial => "stories/posts", :locals => { :posts => story.posts }, :layout => false
  end
end

You'll also want to create a partial to render the posts. In my example, this would be views/stories/_posts.html.erb.

This is a lot of new learning material if you haven't dealt with AJAX+Rails before, so here are a couple useful tutorials: here and here.

Upvotes: 0

Related Questions