1

I have a modal being loaded into a directive and it has a button with a few of attributes.

app.directive('dataFactoryModal', ['$compile', '$timeout', function($compile, $timeout) {
    return {
        scope: { .... }
        link: function (scope, element, attrs) {
            var html = '
               <input ng-model = "recipients" name = "email" type = "text" placeholder = "Enter email(s)" >\
               ....
               // Modal button section
               <button type = "button" class = "btn btn-primary" data-factory = "{{dataFactoryCodes}}" data-recipients = "">Submit</button>\
               ....
            ';
            ....
        }
    }
}

Now I need to insert all typed emails from the input (with ng-model of 'Recipients') inside the "data-list" attribute of the button.

Something like below:

<button type = "button" class = "btn btn-primary" data-factory = "123;109;129" data-recipients = "meme@email.com;yayaya@email.com">Submit</button>

On the input recipients, you can type multiple email addresses but should be separated only with comma.

Of course, ng-model is there to the rescue. So...

<button type = "button" class = "btn btn-primary" data-factory = "{{dataFactoryCodes}}" data-recipients = "{{recipients}}">Submit</button>

But the tricky part is to replace all commas with semi-colons.

So far I added the ff on the directive. But no success to make it work.

  1. Direct replace filter

     scope.replaceCommas = function(value) {
        if (value!==undefined) {
           return value.replace(',', ';');
        }
     }
    

    and then call the function inside the attribute like:

     data-list = {{replaceCommas(recipients)}}
    

    The results:

     data-list = "email@email.com;email2@email.com,email3@email.com"
    

    It's only replacing the first comma and not the succeeding emails being added.

  2. I also tried using $watch, but got not success.

     scope.$watch('recipients', function(newValue, oldValue) {
          scope.email = newValue;
    
          // if I did this, this would replace all commas with semicolons on the button attribute AND on the textfield
          scope.email = newValue.replace(',', ';');
    
          // if I did this, this would just replace only the first comma
          scope.emailTags = newValue.replace(',', ';');
     }
    

and then, on the button...

    data-list = {{emailTags}}

Why is this not working?

mkrieger1
  • 19,194
  • 5
  • 54
  • 65
alleycat
  • 41
  • 8
  • Not about your question, just a comment: it is bad to put spaces between equals characters in the nodes attributes: `type = "button"` is not OK, prefer `type="button"`. It may trigger warnings in html validity checkers. – Pierre Emmanuel Lallemant Aug 09 '17 at 11:20

2 Answers2

2

Method 1: split and join:

Having: var list = "email@email.com,email2@email.com,email3@email.com";

Call: list.split(',').join(';')

Method 2: Regex: list.replace(/,/g,';')

The Invocation

I recommend against watchers, and favor creating a submit() function that will perform this operation? Why? Performance. Having to register watchers to see when a value changes is creating additional overhead, and you know when the user is completed because they will click your Submit button. With the watcher method, you will most likely end up running the replacement function more than once.

If you do require the updates as you go, I recommend the use of ng-change, an example of which is outline in this post. Take special note of the debounce function which will limit how frequently this fires.

The submit() function approach:

<button type = "button" class = "btn btn-primary"
        data-factory = "{{dataFactoryCodes}}"
        data-recipients = "{{recipients}}"
        ng-click="submit()"> <!-- Add this -->
            Submit
</button>

Then, create a function:

scope.submit = function(value) {
  // replace function here
}

Also of interest in this matter may be performance. This link will test the different methods. The Regex version wins here for performance.

https://jsperf.com/split-join-vs-replace/2

Brian
  • 4,921
  • 3
  • 20
  • 29
  • Should it be called inside the watch scope so I'm tracking all changes to the model? – alleycat Aug 09 '17 at 11:00
  • No problem. I added some info on invocation, I recommend not watching, and when the submit is clicked, you can operate on the values. You know when the user is ready, so registering a watcher adds more overhead than is necessary. – Brian Aug 09 '17 at 11:05
0

use global replace

scope.replaceCommas = function(value) {
  if (value!==undefined) {
       return value.replace(/,/g,";")
  }
}
phani indra
  • 243
  • 1
  • 10