Reputation: 791
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 != "");
}
}
Why doesn't AlertMessage_Click fire?
Upvotes: 0
Views: 307
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
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