0

I am trying to implement a custom directive <ticker> which will allow the text in the element to scroll on mouseover like a news ticker if the text width exceeds the space available in the element.

The directive works with normal text like this:

<ticker>A Very Very Long Test Statement</ticker>

but not with a binded variable like this:

<ticker>{{item}}</ticker>

I think it is because I try to strip out the html text in the directive. you can see in this PLUNKER

Here is my full directive:

angular.module('app.directives.ticker', [])
  .directive('ticker', function($interval){
    return { 
      restrict: 'E',
      scope: {},
      link: function(scope, element, attrs){

        var counter = 0;
        var active = false;
        var needed = false;
        var firstIteration = true;
        var originalText = element.html();
        var elementWidth = element.width();
        var textWidth = getTextWidth(element);

        if(textWidth > elementWidth){
          needed = true;
          $interval(startTicker, 25);
        }
        function startTicker(){
          if(firstIteration === true){
            element.html("");
            element.append("<span id='firstTickerItem' class='tickerItem'>" + originalText + "</span>");
            element.append("<span id='secondTickerItem'class='tickerItem'>" + originalText + "</span>");
            firstIteration = false;
          }
          if(counter > textWidth + 19){
            $('#firstTickerItem').remove();
            $('#secondTickerItem').attr("id","firstTickerItem");
            element.append("<span id='secondTickerItem'class='tickerItem'>" + originalText + "</span>");
            counter = 0;
          }
          if(active && needed){
            var leftMostMargin = parseInt($('#firstTickerItem').css('margin-left').replace("px", ""));
            $('#firstTickerItem').css({'margin-left': leftMostMargin - 1 + "px"});
            counter += 1;
          }

        }
        element.mouseenter(function(){
          active = true;
          firstIteration = true;
        });
        element.mouseleave(function(){
          active = false;
          element.html("");

          element.html(originalText);
          counter = 0;
        });
      }
    };
  });

How can I make this work?

Nate May
  • 3,814
  • 7
  • 33
  • 86
  • This is no way to work with angular. There is nothing in this directive that needs you to append your own html. Most of this can be done using built in directives in your template. When you do this appending yourself you need to use `$compile` – charlietfl Mar 05 '16 at 20:39
  • @charlietfl what should my logic be then? This is only my 4th directive, so if I'm thinking about this in a non-angular way, then can you give me a resource that I can read to understand what is the right way? – Nate May Mar 05 '16 at 20:51
  • Valuable reading http://stackoverflow.com/questions/14994391/thinking-in-angularjs-if-i-have-a-jquery-background – charlietfl Mar 05 '16 at 20:54
  • Need to learn to think of the data models first...and let your data models drive the view. Look at things like `ng-if` or `ng-class` for example to remove/ modify your elements – charlietfl Mar 05 '16 at 20:54
  • You may want to check into [ng-transclude](https://docs.angularjs.org/api/ng/directive/ngTransclude) and the [Transclusion](https://docs.angularjs.org/api/ng/service/$compile#transclusion) section of $compile. Transclusion is how you copy the content of a directive while maintaining it's original scope (and thus bindings). – kicken Mar 06 '16 at 08:10

0 Answers0