Reputation: 67
I am trying to allow the user to click on a word in a particular div and that word will be highlighted. I am very new and know that what I have made is not close to working, but I have watched lots of videos and read lots of articles and am stuck. Even if I don't get an answer of exactly what to do, any direction for my next step would be incredibly helpful.
I think I need a directive that would take the div, divide up the text and add a span around each word. This div needs a click event that highlights the word. I have gone through lots of iterations and I am getting blocked at every point.
I have plenty of other angular built in directives working on the page, so I know that I have the app in general set up correctly, and I am including the directive in the app module.
<div my-prepare-text ng-bind-html="item.text | unsafe"></div>
angular.module('MyDirectives', [])
.directive('myPrepareText', function() {
return {
restrict: 'A',
link: function(scope, element) {
var words = element.text().split(' ');
var text = words.join("</span> <span my-highlight ng-click='highlight()'>");
element.html("<p><span my-highlight ng-click='highlight()'>" + text + "</span></p>");
};
};
})
Upvotes: 2
Views: 3332
Reputation: 14375
You can create a directive that gets the words as an attribute and then uses ng-repeat to create the spans.
I made an basic example to show this behavior.
angular.module('MyDirectives', [])
.directive('myPrepareText', function() {
return {
restrict: 'A',
template: '<div><span ng-repeat="word in words" class="single-word" ng-click="highlight($event)">{{word}}</span></div>',
link: function($scope, $element) {
$scope.words = $element.attr('words').split(' ');
$scope.highlight = function(event) {
angular.element(event.target).toggleClass('highlight');
};
}
};
});
.highlight {
background-color: yellow;
}
.single-word::after {
content: ' ';
background-color: #fff;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<!DOCTYPE html>
<html>
<head>
</head>
<body ng-app="MyDirectives">
<div words="so many words to highlight" my-prepare-text></div>
</body>
</html>
Upvotes: 4
Reputation: 447
I think that your approach fails because angular won't compile what you insert as html in a directive via element.html(...)
.
Here's 2 solutions:
Use a template in the directive, instead of inserting html string. In the template, use ng-repeat
to iterate over the array you split in the link function and let ng-repeat
generate your <span>
s.
Use the $compile
service. I have found an easy example of how to use $compile
here.
Keep in mind that angular always has to go through the 2 phases compile and link to make it's "directive magic" happen. It won't know that you have inserted a new directive via element.html(...)
that it has to somehow process, unless you tell it so. This is good because otherwise the digest process would be unbearably slow, as angular would have to recursively check what happens to each DOM-element in every digest cycle.
I hope this got you closer to understand what angular is doing under the hood.
Upvotes: 2