Jeff Cope
Jeff Cope

Reputation: 791

How to build link into bootstrap alert with angular

My application has a multi-line alert where each line represents information for a unique condition. Some of the lines need to include a link that scrolls to the appropriate section of the page.

The example below displays a button (anchor doesn't work either) in the alert message. When you click the button it should display a javascript alert via AlertMessage_Click.

HTML:

<div>
  <div ng-controller="MyCtrl" class="alert alert-warning" id="AlertTest" ng-show="ShowAlertMessage()">
  </div>
</div>

controller:

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

function MyCtrl($scope) {

  $scope.AlertMessage_Click = function() {
    alert('test');
  }

  $scope.ShowAlertMessage = function() {
    var alertMessage = "";
    //alertMessage = "<a id='TestLink' href='#' ng-click='AlertMessage_Click($event)'>Click Here...</a>";    
    alertMessage = "<button id='TestLink' ng-click='AlertMessage_Click()'>Click Here...</button>";

    var AlertTest = document.getElementById('AlertTest');
    AlertTest.innerHTML = alertMessage;
    return (alertMessage != "");
  }

}

JSFiddle

Why doesn't AlertMessage_Click fire?

Upvotes: 0

Views: 307

Answers (2)

Jeff Cope
Jeff Cope

Reputation: 791

I took Luxor001's advice and instead of trying to make it work within the controller I created a custom directive with its own controller.

The controller populates an array of items and the custom directive takes those values and adds to the alert element. Where appropriate it binds the click event and displays the ID of the element clicked.

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

myApp.directive('customAlert', function () {

    var AlertController = ['$scope', function ($scope) {

        //setup condition variables. These will be populated
        //from a web api
        $scope.Condition1 = true;
        $scope.Condition2 = false;
        $scope.Condition3 = true;

        //create array of our messages
        $scope.AlertMessages = [];

        //process conditional variables and add new array elements if appropriate
        if ($scope.Condition1) {
            $scope.AlertMessages.push({
                Message: 'Condition 1 is true',
                ID: 'Condition1',
                IsLink: true
            });
        }


        if ($scope.Condition2) {
            $scope.AlertMessages.push({
                Message: 'Condition 2 is true',
                ID: 'Condition2',
                IsLink: true
            });
        }

        if ($scope.Condition3) {
            $scope.AlertMessages.push({
                Message: 'Condition 3 is true',
                ID: 'Condition3',
                IsLink: false
            });
        }

    }];


    return {
        //set controller property to our AlertController custom controller
        controller: AlertController,
        link: function ($scope, element, attrs) {

            //loop through our alert messages
            for (i = 0; i < $scope.AlertMessages.length; i++) {

                var NewElement = '';

                //if we are processing anything but the first item, add a line break
                if (i != 0)
                { NewElement = NewElement + "<br>"; }

                //add the new element. If this is supposed to be a link item it
                //should add an anchor and set the click event. 
                if ($scope.AlertMessages[i].IsLink) {
                    NewElement = NewElement + "<a id='"
                        + $scope.AlertMessages[i].ID
                        + "'>"
                        + $scope.AlertMessages[i].Message
                        + "</a>";
                }
                    //otherwise add as a static label
                else {
                    NewElement = NewElement + "<label id='"
                        + $scope.AlertMessages[i].ID
                        + "'>"
                        + $scope.AlertMessages[i].Message
                        + "</label>";
                }

                NewElement = angular.element(NewElement);

                //click will show the element id. this will
                //eventually be used to navigate to other sections of the page
                //based on what was clicked. Only assigned if setup as a link.
                if ($scope.AlertMessages[i].IsLink) {
                    NewElement.on('click',
                   function (Item) {
                       alert(Item.target.id);

                   });
                }
                //append the new element to our alert div
                element.append(NewElement);

            }

        }
    };
});

Here is the updated JSFiddle.

Upvotes: 0

illeb
illeb

Reputation: 2947

First: you are not thinking in angularjs (don't manipulate DOM inside the controller! Use a directive instead).

Second: your ng-click event it's not fired because it's not compiled by angularjs. Try to change this line:

AlertTest.innerHTML = alertMessage;

in this one:

AlertTest.innerHTML = $compile(alertMessage)($scope);

This way, you'll end up having a proper, compiled and hopefully working HTML.

P.S. don't forget to include $compile in your dependencies:

function MyCtrl($scope, $compile) {

Upvotes: 1

Related Questions