Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I get Twitter / Facebook / Google+ buttons to show up after loading page via ajax?

I have a rails 3.1 application where I want to allow users to share items via Twitter, Google+ and Facebook (HTML5 version of the like button). I have it working great on the show page for the item (i.e. - just showing that one item), but I'm having issues on a container page that loads the items in a list via Ajax. I want to have separate share buttons next to each item in the container.

The first time the page loads, the share buttons show up fine next to each item. It's only when I reload the container via ajax that my issue arises. The Twitter, Google+ and Facebook buttons do not show up. Here's how I have this set up:

application.html.haml

-# This is right before the body tag closes
= render 'site/share_js'

_share_js.html.erb (code from each provider)

<div id="fb-root"></div>
<script>(function(d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return;
js = d.createElement(s); js.id = id;
js.src = "//connect.facebook.net/en_US/all.js#xfbml=1&appId=MY_APP_ID";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));</script>


<%# Twitter %>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>

<%# Google+ %>
<script type="text/javascript" src="https://apis.google.com/js/plusone.js"></script>

_share_buttons.html.erb (URL of the item to share is passed in)

<div class="share-buttons">

<%# Twitter %>
<a  href="https://twitter.com/share" 
class="twitter-share-button" 
data-lang="en"
data-count="horizontal"
data-text="<%= share_text %>"
data-url="<%= bly_url %>">
Tweet
</a>

<%# Google+ %>
<g:plusone size="medium" href="<%= full_url %>"></g:plusone>

<%# Facebook %>
<div    class="fb-like" 
    data-href="<%= full_url %>" 
    data-send="true" 
    data-layout="button_count" 
    data-width="75"
    data-image="<%= image_path_here %>" 
    data-show-faces="false"></div>

</div>

If I use the share_buttons partial on the item's show page or the first time the container loads, it works great:

_my_item.html.haml

-# other code here that displays the item...
= render :partial => 'site/share_buttons', :locals => share_info_hash

But, as I alluded to above, it doesn't work as well after the ajax action:

my_ajax_action.js.erb (called via format.js in the controller)

$("#item-container").html("<%= escape_javascript(render :partial => "my_item", :collection => @item_list)%>");

The items all display correctly in the container, but the share buttons aren't displaying. I'm guessing that the issue is that provider specific javascript needs to run after executing the ajax action. I've tried placing the provider javascript inside the my_ajax_action.js.erb file after the html is refreshed, but this doesn't seem to do the trick. Does anyone have any ideas on how I could get this to work? Any assistance is much appreciated!

like image 897
George S Avatar asked Feb 22 '23 02:02

George S


1 Answers

The buttons that you are trying to render use a search and replace technique. This works without any special intervention when the elements that become the buttons already exist on the page when onload occurs.

In your case, though, the elements that become the buttons are inserted after the replace script has executed. Since the order is different than the scripts expect, you'll need to trigger the rendering yourself after you add the new buttons to your page.

Here are some links to docs that explain how to do this for each service:

Google +1 button: https://developers.google.com/+/plugins/+1button/#example-explicit-load

Facebook Like button: http://developers.facebook.com/docs/reference/javascript/FB.XFBML.parse/

Tweet button: Well I can't find this one in the docs, but based on some forum activity this looks like the code you're looking for:

twttr.widgets.load();

(see relevant forum post here: https://dev.twitter.com/discussions/890 )

like image 97
mimming Avatar answered Apr 08 '23 03:04

mimming