Reputation: 2155
I have the following angular directive. It uses a range slider to scroll a horizontal div of items. It works if applied to only one row. But if applied to multiple...nothing happens. The transclusion works, but function never runs and no errors are given. What can I do to this to make it be more angular universal and work on multiple elements? Here is repro:CodePen
app.directive('bob', function () {
return {
restrict: 'A',
transclude: true,
template:
`<div style="background-color: #333"><input type="range" value="0" id="scroll-rangeb"><div id="photo-containerb" style="display: flex; overflow-x: scroll; flex-direction: row; align-items: center; height: 90%;" ng-transclude></div></div>`,
link: function (scope, element, attrs) {
var scroll = document.getElementById("scroll-rangeb");
scroll.oninput = function () {
var panel = document.getElementById("photo-containerb");
var total = panel.scrollWidth - panel.offsetWidth;
var percentage = total * (this.value / 100);
panel.scrollLeft = percentage;
}
}
};
});
Upvotes: 0
Views: 867
Reputation: 9800
#scroll-rangeb
is a unique element (in theory), if you override the oninput
on every directive it clearly will not work, it'll remain only the first one found. Anyways, you mustn't use multiple components with the same id at all. Try to find it from the element parameter given on the link function instead, using classes or somthing else.
For example, I could get it solved by using element[0].getElementsByClassName('scroll-rangeb')
:
angular.module('app', [])
.directive('bob', function() {
return {
restrict: 'A',
transclude: true,
template: `
<div style="background-color: #333">
<input type="range" value="0" class="scroll-rangeb">
<div
class="photo-containerb"
style="display: flex; overflow-x: scroll; flex-direction: row; align-items: center; height: 90%;"
ng-transclude>
</div>
</div>`,
link: function(scope, $element, attrs) {
var
element = $element[0],
scroll = element.getElementsByClassName("scroll-rangeb")[0],
panel = element.getElementsByClassName("photo-containerb")[0];
scroll.oninput = function() {
var total = panel.scrollWidth - panel.offsetWidth;
var percentage = total * (this.value / 100);
panel.scrollLeft = percentage;
}
}
};
});
img {
border-radius: 50%;
}
.box {
display: block;
width: 50px;
height: 50px;
min-width: 50px;
margin: 10px;
}
<div ng-app="app">
<div bob>
<img class="box" ng-repeat="img in [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18]" src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==">
</div>
<div bob>
<img class="box" ng-repeat="img in [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18]" src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==">
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.0/angular.js"></script>
Upvotes: 1