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

Coders are NERDS | Learning English with Podcast

Let's learn three English vocabulary words based on real-life context through a humorous video about the life of software coders, especially at big tech companies when they work from home. Credit to Joma Tech. 🤓

[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...

Attribute 'for' of label component with id xxxx is not defined

I got the warning in the log file when I have used the tag <h:outputLabel> without attribute " for " in xhtml file. It was really polluting my server log files. The logged information actually makes sense anyway! We could find an answer as the following: "Having h:outputLabel without a "for" attribute is meaningless. If you are not attaching the label, you should be using h:outputText instead of h:outputLabel." However, these solutions are not possible just for my situation. Instead of using h:outputText for only displaying text, my team has used h:outputLabel too many places. We were nearly in our release time (next day) so it is quite risky and takes much efforts if we try to correct it. Because the style (with CSS) is already done with h:ouputLabel . The alternative by adding attribute " for " the existing h:outputLabel is not reasonable either. I really need to find another solution. Fortunately, I came across a way if I cha...

Functional programming in Java 8

In my previous post , we discussed about why we should consider to use functional programming. Now, let's delve into what functional programming in Java is. What is pure functional programming? Shortly,  f unctional programming is programming using functions. A function corresponds to a mathematical function such as log, sin. Basically, it takes zero or more arguments, give one or more result, and has no side effects. We can't completely program in pure functional style in Java Why?  For example, calling Scanner.nextLine twice typically gives different result. So, it's just called "functional-style programming". How is that? - There is no mutating structures visible to callers. That means your side effect may not be visible to a program, but it's visible to the programmer in terms of slower execution. - A function or method shouldn't throw any exceptions (follows the concept "pass arguments, return result"). We can use types like Opti...

Merging source in SVN

My team has used Primefaces for our projects. We sometimes have several branches of the projects with a new Primefaces's release. For example, we currently have a project with two branches, a branch for using Primeface 4.0, a trunk for using Primeface 5.0, and we are working these parallel branches. Our project looks like the following: - myProject - branches + primefaces4 + tag + trunk (primefaces5) My problem is how to copy the same source from the trunk to the branch "primefaces4". That is where SVN Merging can help! Here is the steps those I have conducted in my project. Step 1 : open the project with the branch "primefaces4" Step 2 : Team > Merge... Chose the trunk's URL. For example: http://192.168.9.10/svn/myProject/trunk Step 3 : Select the revision from "trunk" to merge. For example: +--revision--+--date--------+--author----+--comment---+ +  10        + 03.10.2014 + vanhuong   + f1: part 3 + +  9     ...