August 01 2014

AngularJS directives for social sharing buttons - Facebook Like, Google+, Twitter and Pinterest

A few simple AngularJS directives that wrap the social sharing buttons: Facebook Like, Google Plus, Twitter Tweet and Pinterest Pin It.

The social buttons work after route changes by automatically updating to the current URL as you navigate through your AngularJS app.

For an updated version for Angular 2+ check out Angular 2+ Social Sharing Buttons for Facebook, Google Plus, Twitter, LinkedIn and Pinterest

Here they are in action: (See on Plunker at http://plnkr.co/edit/TQoIJ2?p=preview)

Update History:


AngularJS Social Button Installation

  • Install using Bower: bower install angulike
  • Or download the code from GitHub and include the angulike.js file in your page, it's available on GitHub at https://github.com/cornflourblue/angulike
  • Or copy the AngularJS Directive sections below and add to your application

Add the 'angulike' module as a dependency of your AngularJS application:

angular.module('myApp', ['angulike']);

 

AngularJS Social Button Usage


AngularJS Facebook Like

Create an empty div with the fb-like attribute:

<div fb-like></div>

To use a custom URL for the facebook like button:

<div fb-like="myModel.Url"></div>

 

AngularJS Google+ Share

Create an empty div with the google-plus attribute:

<div google-plus></div>

To use a custom URL for the google plus button:

<div google-plus="myModel.Url"></div>

 

AngularJS Twitter Tweet

Create an empty div with the tweet attribute, the value of the attribute contains the name of the model object for the tweet text:

<div tweet="myModel.Name"></div>

To use a custom URL for the tweet button:

<div tweet="myModel.Name" tweet-url="myModel.Url"></div>

 

AngularJS Pinterest PinIt

Create an empty div with the pin-it and pin-it-image attributes, the pin-it attribute contains the name of the model object for the description and the pin-it-image attribute contains the name of the model object for the image url:

<div pin-it="myModel.Name" pin-it-image="myModel.ImageUrl"></div>

To use a custom URL for the pinterest button:

<div pin-it="myModel.Name" pin-it-image="myModel.ImageUrl" pin-it-url="myModel.Url"></div>

 

AngularJS Controller to set the $scope variables used by the social share directives

Set the scope variables used by the directives in your controller:

angular.module('myApp')
  .controller('myController', [
      '$scope', function ($scope) {
          $scope.myModel = {
              Url: 'http://jasonwatmore.com/post/2014/08/01/AngularJS-directives-for-social-sharing-buttons-Facebook-Like-GooglePlus-Twitter-and-Pinterest.aspx',
              Name: "AngularJS directives for social sharing buttons - Facebook, Google+, Twitter and Pinterest | Jason Watmore's Blog", 
              ImageUrl: 'http://www.jasonwatmore.com/pics/jason.jpg'
          };
      }
  ]);

 

Set your Facebook App Id in your AngularJS App Run Method

angular.module('myApp', ['angulike'])
  .run([
      '$rootScope', function ($rootScope) {
          $rootScope.facebookAppId = '[FacebookAppId]'; // set your facebook app id here
      }
  ]);

 

 

Breakdown of the AngularJS Social Sharing Buttons Code

Below is a breakdown of how the angular social sharing buttons are implemented, for those interested in the nuts and bolts.

I'm setting each element html for each button in the directive link function rather than using a template so the directive waits for all the data and APIs to be loaded before displaying anything.

 

AngularJS Facebook Like Button Directive

angular.module('angulike')
    .directive('fbLike', [
        '$window', '$rootScope', function ($window, $rootScope) {
            return {
                restrict: 'A',
                scope: {
                    fbLike: '=?'
                },
                link: function (scope, element, attrs) {
                    if (!$window.FB) {
                        // Load Facebook SDK if not already loaded
                        $.getScript('//connect.facebook.net/en_US/sdk.js', function () {
                            $window.FB.init({
                                appId: $rootScope.facebookAppId,
                                xfbml: true,
                                version: 'v2.0'
                            });
                            renderLikeButton();
                        });
                    } else {
                        renderLikeButton();
                    }

                    var watchAdded = false;
                    function renderLikeButton() {
                        if (!!attrs.fbLike && !scope.fbLike && !watchAdded) {
                            // wait for data if it hasn't loaded yet
                            watchAdded = true;
                            var unbindWatch = scope.$watch('fbLike', function (newValue, oldValue) {
                                if (newValue) {
                                    renderLikeButton();
									  
                                    // only need to run once
                                    unbindWatch();
                                }
                                  
                            });
                            return;
                        } else {
                            element.html('<div class="fb-like"' + (!!scope.fbLike ? ' data-href="' + scope.fbLike + '"' : '') + ' data-layout="button_count" data-action="like" data-show-faces="true" data-share="true"></div>');
                            $window.FB.XFBML.parse(element.parent()[0]);
                        }
                    }
                }
            };
        }
    ]);

 

AngularJS Google Plus Button Directive

angular.module('angulike')
    .directive('googlePlus', [
        '$window', function ($window) {
            return {
                restrict: 'A',
                scope: {
                    googlePlus: '=?'
                },
                link: function (scope, element, attrs) {
                    if (!$window.gapi) {
                        // Load Google SDK if not already loaded
                        $.getScript('//apis.google.com/js/platform.js', function () {
                            renderPlusButton();
                        });
                    } else {
                        renderPlusButton();
                    }

                    var watchAdded = false;
                    function renderPlusButton() {
                        if (!!attrs.googlePlus && !scope.googlePlus && !watchAdded) {
                            // wait for data if it hasn't loaded yet
                            watchAdded = true;
                            var unbindWatch = scope.$watch('googlePlus', function (newValue, oldValue) {
                                if (newValue) {
                                    renderPlusButton();

                                    // only need to run once
                                    unbindWatch();
                                }

                            });
                            return;
                        } else {
                            element.html('<div class="g-plusone"' + (!!scope.googlePlus ? ' data-href="' + scope.googlePlus + '"' : '') + ' data-size="medium"></div>');
                            $window.gapi.plusone.go(element.parent()[0]);
                        }
                    }
                }
            };
        }
    ]);

 

AngularJS Twitter Tweet Button Directive

angular.module('angulike')
    .directive('tweet', [
        '$window', '$location',
        function ($window, $location) {
            return {
                restrict: 'A',
                scope: {
                    tweet: '=',
                    tweetUrl: '='
                },
                link: function (scope, element, attrs) {
                    if (!$window.twttr) {
                        // Load Twitter SDK if not already loaded
                        $.getScript('//platform.twitter.com/widgets.js', function () {
                            renderTweetButton();
                        });
                    } else {
                        renderTweetButton();
                    }

					var watchAdded = false;
                    function renderTweetButton() {
                        if (!scope.tweet && !watchAdded) {
                            // wait for data if it hasn't loaded yet
							watchAdded = true;
                            var unbindWatch = scope.$watch('tweet', function (newValue, oldValue) {
							    if (newValue) {
                                    renderTweetButton();
								  
								    // only need to run once
								    unbindWatch();
								}
                            });
                            return;
                        } else {
                            element.html('<a href="https://twitter.com/share" class="twitter-share-button" data-text="' + scope.tweet + '" data-url="' + (scope.tweetUrl || $location.absUrl()) + '">Tweet</a>');
                            $window.twttr.widgets.load(element.parent()[0]);
                        }
                    }
                }
            };
        }
    ]);

 

AngularJS Pinterest PinIt Button Directive

angular.module('angulike')
    .directive('pinIt', [
        '$window', '$location',
        function ($window, $location) {
            return {
                restrict: 'A',
                scope: {
                    pinIt: '=',
                    pinItImage: '=',
                    pinItUrl: '='
                },
                link: function (scope, element, attrs) {
                    if (!$window.parsePins) {
                        // Load Pinterest SDK if not already loaded
                        (function (d) {
                            var f = d.getElementsByTagName('SCRIPT')[0], p = d.createElement('SCRIPT');
                            p.type = 'text/javascript';
                            p.async = true;
                            p.src = '//assets.pinterest.com/js/pinit.js';
                            p['data-pin-build'] = 'parsePins';
                            p.onload = function () {
                                if (!!$window.parsePins) {
                                    renderPinItButton();
                                } else {
                                    setTimeout(p.onload, 100);
                                }
                            };
                            f.parentNode.insertBefore(p, f);
                        }($window.document));
                    } else {
                        renderPinItButton();
                    }

					var watchAdded = false;
                    function renderPinItButton() {
                        if (!scope.pinIt && !watchAdded) {
                            // wait for data if it hasn't loaded yet
							watchAdded = true;
                            var unbindWatch = scope.$watch('pinIt', function (newValue, oldValue) {
							    if (newValue) {
								    renderPinItButton();
									  
									// only need to run once
									unbindWatch();
								}
                            });
                            return;
                        } else {
                            element.html('<a href="//www.pinterest.com/pin/create/button/?url=' + (scope.pinItUrl || $location.absUrl()) + '&media=' + scope.pinItImage + '&description=' + scope.pinIt + '" data-pin-do="buttonPin" data-pin-config="beside"></a>');
                            $window.parsePins(element.parent()[0]);
                        }
                    }
                }
            };
        }
    ]);

 

Web Development and AngularJS Consultant Sydney

Feel free to drop me a line if you're looking for web development or AngularJS development or consulting services in Sydney Australia, I also provide remote contracting services for clients outside Sydney.


Sponsored by