5

I am making a cart application in Angular using Angular Bootstrap.

When hovering over the cart icon a tooltip should appear. The tooltip's content should change based on if the item is already in the cart or not.

So, here is the html:

<h3><i class="fa fa-shopping-basket" ng-click="add2Cart(item.Name)" tooltip-placement="right" uib-tooltip-html="itemtooltiptext(item.Name)" aria-hidden="true"></i></h3>

Basically, in order to check if the item is already in the cart, I want the tooltip text to resolve from a function. My understanding from the documentation is this is supported as long as the HTML is trusted.

It says,

uib-tooltip-html $ - Takes an expression that evaluates to an HTML string. Note that this HTML is not compiled. If compilation is required, please use the uib-tooltip-template attribute option instead. The user is responsible for ensuring the content is safe to put into the DOM!

So my itemtooltiptext() function is...

  $scope.itemtooltiptext = function(name) {
  if (localStorage.getItem("cart") === null) {
    return $sce.trustAsHtml("Add " + name + " to Cart!");
  } else {
    var cart = JSON.parse(localStorage.getItem("cart"));
    for (var i = 0; i < cart.length; i++) {
      if (cart[i] == name) {
        console.log("already in cart");
        return $sce.trustAsHtml(name + "already in Cart!");
      }
    }
    return $sce.trustAsHtml("Add " + name + " to Cart!");
  }
}   

This results in an

Infinite $digest Loop Error

As detailed here: https://stackoverflow.com/a/19370032

But the problem is I need it to come from a function with the various conditions? So should I be using a template? I don't understand how that would work any better because I still need dynamic text served from the template... so what is the solution?

Thank you.

1
  • can you make up a plunk? Commented Feb 6, 2017 at 10:00

2 Answers 2

3

This is not how you use uib-tooltip-html, apparently it causes an infinite digest loop, fortunately the demo plunk shows you how to do it.

You need to get/calculate your html, bind to some scope variable and bind it into uib-tooltip-html

js

$scope.itemtooltiptext = function() {
    $scope.htmlTooltip = $sce.trustAsHtml('I\'ve been made <b>bold</b>!');
};
$scope.itemtooltiptext();

html

<button uib-tooltip-html="htmlTooltip" class="btn btn-default">Tooltip</button>

If you still want to bind a function to your tooltip, you can do like so

<button uib-tooltip="{{itemtooltiptext()}}" class="btn btn-default">Tooltip</button>

Note that this approache will have the function invoked every digest cycle.

Sign up to request clarification or add additional context in comments.

2 Comments

FYI your plunk is blank!
fixed it, it's basically the unaltered ui-bootstrap demo plunk for the tooltip
0

I ran into this infinite digest cycle issue where I needed a dynamic tooltip... it caused angular to recalculate it every time as a new value (even though it was the same). I created a function to cache the computed value like so:

$ctrl.myObj = {
    Title: 'my title',
    A: 'first part of dynamic toolip',
    B: 'second part of dynamic tooltip',
    C: 'some other value',
    getTooltip: function () {
        // cache the tooltip
        var obj = this;
        var tooltip = '<strong>A: </strong>' + obj.A + '<br><strong>B: </strong>' + obj.B;
        var $tooltip = {
            raw: tooltip,
            trusted: $sce.trustAsHtml(tooltip)
        };
        if (!obj.$tooltip) obj.$tooltip = $tooltip;
        else if (obj.$tooltip.raw !== tooltip) obj.$tooltip = $tooltip;
        return obj.$tooltip;
    }
};

Then in the html, I accessed it like this:

<input type="text" ng-model="$ctrl.myObj.C"
    uib-tooltip-html="$ctrl.myObj.getTooltip().trusted">

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.