Skip to main content

AngularJS - Build a custom validation directive for using multiple emails in textarea

AngularJS already supports the built-in validation with text input with type email. Something simple likes the following:
<input name="input" ng-model="email.text" required="" type="email" />
<span class="error" ng-show="myForm.input.$error.email">
        Not valid email!</span>

However, I used a text area and I wanted to enter some email addresses that's saparated by a comma (,). I had a short research and it looked like AngualarJS has not supported this functionality so far. Therefore, I needed to build a custom directive that I could add my own validation functions. My validation was done only on client side, so I used the $validators object.

Note that, there is the $asyncValidators object which handles asynchronous validation, such as making an $http request to the backend.

This is just my implementation on my project. In order to understand that, I supposed you already had experiences with AngularJS and you can catch my point here.

Html code
<textarea rows="3" class="form-control"
 id="dnNoticeInterfaceOtherEmail" name="dnNoticeInterfaceOtherEmail" 
 ng-model='noticeInterface.email.toAddress' ng-maxlength="500" ng-required="true"
 ng-init="dnNoticeInterfaceDialogForm.dnNoticeInterfaceOtherCCEmail.$validate()"
 dn-multiple-email-validator>
</textarea>

<div ng-messages="dnNoticeInterfaceDialogForm.dnNoticeInterfaceOtherEmail.$error" ng-show="dnNoticeInterfaceDialogForm.$submitted" role="alert">
 <div class="alert alert-danger" ng-message="required">
  This field is required.
 </div>
 <div class="alert alert-danger" ng-message="maxlength">
  This field only is allowed up to 500 characters
 </div>
 
 <div class="alert alert-danger" ng-message="dnMultipleEmailValidator">
  This field required a valid email format
 </div>
</div>

Javascript code
//DIRECTIVE FOR NAME MULTIPLE EMAILS
angular.module("dnStandard").directive("dnMultipleEmailValidator", dnMultipleEmailValidatorImpl);
function dnMultipleEmailValidatorImpl() {
 return {
  require: 'ngModel',
  link: dnMultipleEmailValidatorLinkImpl
 };
};

function dnMultipleEmailValidatorLinkImpl(scope, element,  attributes, controller) {
  controller.$validators.dnMultipleEmailValidator = function(modelValue, viewValue) {
   var errorFlag = true;
   if (!controller.$isEmpty(viewValue)) {
   var emailIdsArr = viewValue.split(/,|;/g);
       angular.forEach( emailIdsArr, function( value, key ) {
         if (!dnPattern.EMAIL_PATTERN.test(value.trim())) {
            errorFlag = false;
         }
       });
  }
    return errorFlag;
  };
}

dnPattern.EMAIL_PATTERN =  /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/

References:
[1]. https://docs.angularjs.org/api/ng/input/input%5Bemail%5D
[2]. http://www.treselle.com/blog/angularjs-directives/
[3]. https://docs.angularjs.org/guide/forms

Comments

Popular posts from this blog

[Snippet] CSS - Child element overlap parent

I searched from somewhere and found that a lot of people says a basic concept for implementing this feature looks like below: HTML code: <div id="parent">  <div id="child">  </div> </div> And, CSS: #parent{   position: relative;   overflow:hidden; } #child{   position: absolute;   top: -1;   right: -1px; } However, I had a lot of grand-parents in my case and the above code didn't work. Therefore, I needed an alternative. I presumed that my app uses Boostrap and AngularJs, maybe some CSS from them affects mine. I didn't know exactly the problem, but I believed when all CSS is loaded into my browser, I could completely handle it. www.tom-collinson.com I tried to create an example to investigated this problem by Fiddle . Accidentally, I just changed: position: parent; to position: static; for one of parents -> the problem is solved. Look at my code: <div class="modal-body dn-placeholder-parent-positi...

My must-have apps for daily work

There is no doubt that cool apps can help us be more productive and enjoyable at work. For the time being, I really love the following apps which are used by me almost every day. 1. A personal Kanban In fact, a personal kanban is the most useful app for me. Why does it matter? It is not just a to-do list, but it keeps me motivated every day because it helps me be able to know what my "big picture" is. I usually set up my plans together with a path to reach them.  KanbanFlow  is my preferred tool. KanbanFlow 2. A terminal Needless to say, a terminal is a must-have app for every developer, especially the ones use macOS/Linux. Due to its importance, I love to decorate and enhance it to be super exciting with various tools such as  iTerm ,  oh-my- zsh , and  thefuck . ;) iTerm + oh-my-zsh 3. A documentation "ecosystem" As a developer, I can not remember all things that I have experimented a day. Moreover, a document is really useful for sharing an...

PSMDB - A MongoDB alternative for having Encryption At Rest

Encryption is the most popular tool for securing data both in transit and at rest. - For protecting data in transit, we can configure to use the TLS connection - For protecting data at rest, we can use Percona Server for MongoDB (PSMDB), an open-source alternative for MongoDB Enterprise. License PSMDB Docker images follow the SSPL license. Therefore, it is not a problem when I only have my containers deployed in on-premises environments. Running MongoDB Replication on OpenShift I have successfully installed the replication by following the guide Install Percona Server for MongoDB on OpenShift . In order to make it work properly with my needs, I disabled some features from the default deployment. See the detail in this change Basically, I needed to create a CRD (Custom Resource Definition) to let OpenShift/Kubernetes what PSMDB is. Then, I deployed the Operator pod. Finally, I deployed the PSMDB StatefulSet. I used NFS shares for Persistent Volumes. Create CRD for PSMDB 2 git clone http...

Adding a default text to the beginning of an text area

I have a text area where I can enter a SQL statement. The text "SELECT TOP 1" is used at the begining of the sql statement as a default prefix that can not be removed. In order to archive this functionality, I found three options: 1. Use an inputMask and build a pattern for the entered text. We can use the prefix inside the text area: http://jsfiddle.net/SEXAj/2130/ 2. Create an javascript event listener on event "input" and calculate to prevent the prefix is removed http://jsfiddle.net/sarbbottam/TUc94/ 3. Use another html tag like "div"/"span" that contains the prefix and calculate the suitable position + Tag "span": http://jsfiddle.net/4YzZy/ + Tag "div": http://jsfiddle.net/215b34fs/ I chose the 3rd approach with tag "div" because it's the most easiest solution and suitable for me at that monment. References: [1].  http://stackoverflow.com/questions/24846041/how-do-i-add-a-default-text...

Safari (older than 14.1.1) rejects TLS connections of TURN with Let's Encrypt certificates

Summary We could not make a video call successfully on Safari older than 14.1.1. The call kept disconnecting for some seconds. We got the following error in Nginx’s log SSL: error:14094418:SSL routines:ssl3_read_bytes:tlsv1 alert unknown ca:SSL alert number 48   Root cause The Safari didn’t trust our TLS certificates (certified by Let’s Encrypt) when establishing a TLS connection into our TURN server. It is a known issue that could be found at Bug 219274 - ICE does not resolve for `turns` relay candidates rooted in LetsEncrypt CA . The issue was just recently fixed (end of 2020), therefore old versions of Safari still meet the issues.   Solution In our development environment, we replaced the untrusted certificate with a trusted one. We will warn our customers about this issue in our installation guide. Technical explained WebKit is a browser engine developed by Apple and primarily used in its Safari web browser, as well as all iOS web browsers. The WebRTC of WebKit relied on ...