7

I've been searching the web and racking my brain but can't seem to find a solution to this. I need to make a popover inside of an ng-repeat, where the popover will also have an ng-repeat inside of it.

Here is the JSFiddle I have so far but the ng-repeat with "phone.friends" does not work:

http://jsfiddle.net/grzesir/Lq8ve/4/

HTML:

<div ng-app="AngularApp">
<div class="container" ng-controller="MainController">
    <div ng-repeat="phone in phones">

        {{phone.name}} 
        <a href="javascript: void(0);" class='repeatpopover' data-popover="true" data-html=true data-content="<div ng-repeat='friend in phone.friends'>{{friend.name}}</div>">hover here</a>

    </div>
</div>

Javascript:

var angularApp = angular.module('AngularApp', []);

angularApp.controller('MainController', function ($scope) {
    $scope.phones = [{
        'name': 'Nexus S',
            'snippet': 'Fast just got faster with Nexus S.',
            'friends': [{
            'name': 'John'
        }, {
            'name': 'Mike'
        }]
    }, {
        'name': 'Motorola XOOM™ with Wi-Fi',
            'snippet': 'The Next, Next Generation tablet.',
            'friends': [{
            'name': 'John 2'
        }, {
            'name': 'Mike 2'
        }]
    }, {
        'name': 'MOTOROLA XOOM™',
            'snippet': 'The Next, Next Generation tablet.',
            'friends': [{
            'name': 'Chris'
        }, {
            'name': 'Noah'
        }]
    }];
});

$(function () {
    $(".repeatpopover").popover({
        trigger: "hover"
    });
});
Rob
  • 7,028
  • 15
  • 63
  • 95
  • 1
    I don't have an answer for you, but until you get one this may get you going: http://stackoverflow.com/questions/21490194/how-to-add-angularjs-ui-bootstrap-tooltips-dynamically-to-existing-markup – Samsquanch Jun 11 '14 at 18:55

2 Answers2

4

I've updated your fiddle for solution using a filter.

Add:

angularApp.filter('friendsHTML', function() {
  return function(input) {
      var html = '';
      for (idx in input) {
          html += '<div>' + input[idx].name + '</div>';
      }
      return html;
  };
});

And then in your template for the data-content parameter just do data-content="{{ phone.friends | friendsHTML }}". This could probably be made more general/reusable somehow though.

This may be worth looking into as well. Hope that helps!

jeffff
  • 1,309
  • 1
  • 7
  • 23
  • This works, but I feel like there could be a better solution (aka could be confusing for other devs on the project). Do you think using something like ng-include might work as well? Note: I'm not very good with ng-include so I'm looking into this now. – Rob Jun 11 '14 at 19:22
  • I agree it could definitely look confusing... Possibly less confusing is a directive for the whole thing, but I think either way be content of the attribute would need to be precompiled. Definitely interested to see any workarounds. – jeffff Jun 11 '14 at 19:30
3

In case anyone is interested, here is a JS Fiddle with it working:

http://jsfiddle.net/grzesir/TZ72k/2/

Javascript:

var angularApp = angular.module("bootstrap", []);

angularApp.controller('MainController', function ($scope) {
    $scope.phones = [{
        'name': 'Nexus S',
            'snippet': 'Fast just got faster with Nexus S.',
            'friends': [{
            'name': 'John'
        }, {
            'name': 'Mike'
        }]
    }, {
        'name': 'Motorola XOOM™ with Wi-Fi',
            'snippet': 'The Next, Next Generation tablet.',
            'friends': [{
            'name': 'John 2'
        }, {
            'name': 'Mike 2'
        }]
    }, {
        'name': 'MOTOROLA XOOM™',
            'snippet': 'The Next, Next Generation tablet.',
            'friends': [{
            'name': 'Chris'
        }, {
            'name': 'Noah'
        }]
    }];
});

angularApp.directive('popOver', function ($compile, $templateCache) {
        var getTemplate = function () {
            $templateCache.put('templateId.html', 'This is the content of the template');
            console.log($templateCache.get("popover_template.html"));
            return $templateCache.get("popover_template.html");
        }
        return {
            restrict: "A",
            transclude: true,
            template: "<span ng-transclude></span>",
            link: function (scope, element, attrs) {
                var popOverContent;
                if (scope.friends) {
                    var html = getTemplate();
                    popOverContent = $compile(html)(scope);                    
                    var options = {
                        content: popOverContent,
                        placement: "bottom",
                        html: true,
                        title: scope.title
                    };
                    $(element).popover(options);
                }
            },
            scope: {
                friends: '=',
                title: '@'
            }
        };
    });

HTML:

<div ng-app="bootstrap" id="example" ng-init="items = ['car', 'truck', 'plane', 'bike']">
    <div ng-controller="MainController">
        <div ng-repeat="phone in phones">
            <a href="#" pop-over friends="phone.friends", title="Mode of transport">Show Pop over</a>
        </div>
    </div>
    <script type="text/ng-template" id="popover_template.html">
        <ul class='unstyled'><li ng-repeat='friend in friends'>{{friend.name}}</li></ul>
    </script>
</div>
Rob
  • 7,028
  • 15
  • 63
  • 95