Good way to dynamically open / close a popover (or tooltip) using angular, based on expression?

danludwig picture danludwig · Jan 5, 2014 · Viewed 84.8k times · Source

I have a form that is wired into angular, using it for validation. I am able to display error messages using ng-show directives like so:

<span ng-show="t3.f.needsAttention(f.fieldName)" ng-cloak>
    <span ng-show="f.fieldName.$error.required && !f.fieldName.$viewValue">
        This field is required.
    </span>
</span>

.. where f is the form, and t3 comes from a custom directive on the form which detects whether a submission was attempted, and contains functions for checking the validity of fields.

What I am trying to accomplish is to display validation message(s) inside a popover instead. Either bootstrap's native popover, or the popover from UI Bootstrap, I have both loaded. I may also consider AngularStrap if it is easier to do it using that lib.

What I'm struggling with right now is the nature of popovers in general -- they autodisplay based on user events like click, mouseenter, blur, etc. What I want to do is show & hide the popover(s) based on the same functions in the ng-show attributes above. So that when the expression returns false hide it, and when it returns true, show it.

I know bootstrap has the .popover('show') for this, but I'm not supposed to tell angular anything about the dom, so I'm not sure how I would get access to $(element).popover() if doing this in a custom form controller function. Am I missing something?

Update

The solution mentioned in the duplicate vote still only shows the popover on mouseenter. I want to force it to display, as if doing $('#popover_id').popover('show').

Answer

Kim Ras picture Kim Ras · Apr 30, 2014

You can also build your own extended triggers. This will apply to both Tooltip and Popover.

First extend the Tooltip triggers as follows:

// define additional triggers on Tooltip and Popover
app.config(['$tooltipProvider', function($tooltipProvider){
    $tooltipProvider.setTriggers({
        'show': 'hide'
    });
}]);

Then define the trigger on the HTML tag like this:

<div id="RegisterHelp" popover-trigger="show" popover-placement="left" popover="{{ 'Login or register here'}}">

And now you can call hide and show from JavaScript, this is a show in 3 seconds.

$("#RegisterHelp").trigger('show');
//Close the info again
$timeout(function () {
    $("#RegisterHelp").trigger('hide');
}, 3000);