0

I have developed a directive, but it is always applying functionality on the last element in the page, here is my code:

HTML:

<div ng-controller="MyCtrl">
  <input type="text" email-commy comma-separated-data="model1" class="form-control"/>
  <input type="text" email-commy comma-separated-data="model2" class="form-control"/>
</div>

JS:

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

function MyCtrl($scope) {
    $scope.model1 = "abc@gmail.com";
    $scope.model2 = "abc2@gmail.com";
}

app.directive("emailCommy", function(){
  return {
    scope: {
      commaSeparatedData: '='
    },    
    restrict: "A",  
    multiple: true,
    link: function (scope, elem, attrs, ngModel) {

      function handler(dataString){

        function buildEmailList() {

          var lis = data.map(function (em, index) {
            return "<li>" + em + "<span class='remove-element' data-index='" + index + "'>&times;</span>" + "</li>";
          }).join("");

          var input = $("<input/>", {"class": "form-control shadow-element", "placeholder": "Enter..."});
          lis += "<li class='input-field'>" + input.wrap("<p/>").parent().html() + "</li>";

          return "<ul class='list-inline'>" + lis + "</ul>";
        }

        function renderer() {
          $wrapper.empty().append(buildEmailList());          
          elem.addClass("hide").before($wrapper);
          listener();
        }

        function listener() {
          angular.element(".shadow-element").off("keypress").on("keypress", function (evt) {
            var $this = $(this),
                charCode = evt.which || evt.keyCode;

            //add input in case of (comma, enter, and semi-colon) pressed
            if ($this.val() && (charCode === 44 || charCode === 13 || charCode === 59)) {
              data.push($this.val().toLowerCase());                                    
              renderer();

              updateModel();
              $this.val("");
            }
          });

          angular.element(".remove-element").off("click").on("click", function () {
            var $this = $(this),
                index = $this.data("index");

            data.splice(index, 1);
            updateModel();
            renderer();
          });
        }

        function updateModel(){
          var updatedVal = data.join(",");
          $(elem).val(updatedVal);
        }

        if(dataString) {
          var data = dataString.split(",").map(function (em) {
            return em.toLowerCase().trim();
          });

          var $wrapper = $("<div/>", {"class": "email-container"});

          renderer();
        }
      }

      handler(scope.commaSeparatedData);

      //scope.$watch(attrs.commaSeparatedData, handler);
    }
  };
});

Here is fiddle: http://jsfiddle.net/RmDuw/928/

Directive only working on last element. If i add data in first directive it adds to below one.

Please help, and suggest me how to fix. Thanks

maverickosama92
  • 2,685
  • 2
  • 21
  • 35
  • 1
    I think your problem can be related to the selectors you use, such as ```angular.element(".shadow-element")```: this does not select the one of the current directive but all the ones in the page so handling of the events can be wrong. – Dario Sep 09 '16 at 16:59
  • @Dario: any suggestions? – maverickosama92 Sep 09 '16 at 20:38

1 Answers1

0

Just change your code in order to select the input of current directive like this:

function listener() {
   $wrapper.find('input').on(...

and for remove element:

$wrapper.find('span')..

See the fiddle

Dario
  • 6,152
  • 9
  • 39
  • 50