11

I'm trying to use AngularJS Bootstrap alerts like explained here with the "dismiss-on-timeout" attribute. It has no effect in this example, the alert just appears regularly and doesn't disappear.

<alert type="warning" dismiss-on-timeout="2000">Alert text</alert>

It does however work in the ng-repeat example from the site:

<alert ng-repeat="alert in alerts" type="{{alert.type}}" close="closeAlert($index)" dismiss-on-timeout="2000">{{alert.msg}}</alert>

Is the problem the missing close attribute? If so, how do you write a close function for an alert that's not part of an array?

2
  • Works fine: plnkr.co/edit/0ovNkuePOra371EUzMge?p=preview Commented Aug 15, 2015 at 10:04
  • Yes as I said, there is no problem when using the ng-repeat on an array of alerts. But I am looking for a single alert, and as you can see if you copy the first code bit it does not work there. Commented Aug 15, 2015 at 10:21

5 Answers 5

19

Well it works, it's just dismissOnTimeout directive invokes close method of the alert directive controller. This controller in its turn uses outer scope close method. So you need to implement it with so that directive could call it:

<alert type="danger" close="closeAlert()" ng-if="show" 
       dismiss-on-timeout="2000">Something happened.</alert>

and in controller:

$scope.show = true;

$scope.closeAlert = function(index) {
    $scope.show = false;
};
Sign up to request clarification or add additional context in comments.

6 Comments

Thank you! I suspected it was about the close method, but wasn't sure how to implement it.
What is "close" method ?
It would be great, if any example for usage also available . Thanks!
I gave example in the answer. You just need to implement callback to be called by Angular.
|
5

Actually, you do not need to use the variable ($scope.show = false;) to hide the alert(s). All you need to do is to make sure that the array that holds the alerts can only have one item at a time, unless you want multiple/previous alerts showing on the screen. Just delete the alert after showing it. See below:

Markup

<uib-alert ng-repeat="alert in alerts" dismiss-on-timeout="2000" type="{{alert.type}}" close="closeAlert()">{{alert.msg}}</uib-alert>

Controller

//array to hold the alerts to be displayed on the page
$scope.alerts = [];

/**
 *This function is used to push alerts onto the alerts array.
 */
$scope.addAlert = function(type, message) {

    //add the new alert into the array of alerts to be displayed.
    $scope.alerts.push({type: type, msg: message});
};

/**
 *This function closes the alert
 */
$scope.closeAlert = function(index) {

    //remove the alert from the array to avoid showing previous alerts
    $scope.alerts.splice(0); 
};

So when you want to display an alert:

$scope.addAlert('success', 'My message');

1 Comment

I also applied same as your code but only dismiss timeout base alert did not hide. So, how can i manage ? Please suggest thanks
1

I never could get it to work. Here's a more straightforward approach:

Markup

<div uib-alert 
     data-closeable="true"   <!-- sets the 'x' on the right for closing -->
     close="closeAlert()"    <!-- what the 'x' and the timeout will call -->
     alert alert-{{ alert.level }}"   <!-- sets the color (e.g. 'success' or 'danger')  -->
     ng-show="alert.show">   <!-- only show me when this is truthy -->
     {{ alert.message }}
</div>

Controller

$scope.closeAlert = function() {
    $scope.alert.show = false;
}

$scope.showAlertForFiveSeconds = function(){
    $scope.alert.message = 'Something went wrong!');
    $scope.alert.level = 'danger';  // red
    $timeout(closeAlert, 5000);  // close the alert in 5 seconds
}

Essentially all I'm doing is manually setting a deferred call to close the alert and walking away.

Note that doing this also requires you to inject the Angular $timeout service into the controller up top.

Comments

1

My proposal would be to wrap it in a alertFactory that can be used from everywhere:

App.factory('alertFactory',['$rootScope', 
    function($rootScope) {
    var alertService = {};
    $rootScope.alerts = [];

    // will automatidally close
    // types are success, warning, info, danger
    alertService.addAuto = function(type, msg, delay) {
        var alert = {'type': type, 'msg': msg};
        $rootScope.alerts.push(alert);      
        if (!delay ) {
            delay = 2500; // default delay is 2500ms
        }  
        window.setTimeout(function() {
            var index = $rootScope.alerts.indexOf(alert);
            if (index > -1) {
                $rootScope.alerts.splice(index, 1);
                $rootScope.$apply(); // refresh GUI
            } 
        }, delay);
    }

    return alertService;
}])

Place this, e.g. in your `index.html

<script src="components/angular-ui-bootstrap-bower/ui-bootstrap-tpls.js"></script>
...
<alert ng-repeat="alert in alerts" type="{{alert.type}}" close="closeAlert($index)">{{alert.msg}}</alert>

Call like

App.controller('myCtrl', [ "alertFactory", function(alertFactory) {

    var optionalDelay = 2500;
    alertFactory.addAuto('success', 'my alert text', optionalDelay);
}]);

Comments

0

The solution here is correct, however it is outdated so here is the updated version.

In View: ( Updated in Angular UI Bootstrap )

<uib-alert type="{{alert.type}}" close="closeAlert()" dismiss-on-timeout="2000" ng-if="show">
  {{alert.msg}}
</uib-alert>

In Controller:

$scope.show = true;

   $scope.closeAlert = function() {
     $scope.show = false;
   };

    $scope.alert = {type: 'danger', msg: 'Something gone wrong'};

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.