long hoangvan long hoangvan - 4 months ago 9
Javascript Question

How to use directives for multiple form elements

I want to check if an input is katakana characters or not.

This code works for one element :

var KANA_FULL_SIZE_REGEXP = /^([ァ-ン。、ー「」.\s]+)$/;
var KANA_HAFL_SIZE_REGEXP = /^([ァ-ン゙゚。「」、・ー\s]+)$/;
var KANA_ALL_SIZE_REGEXP = /^([ァ-ンァ-ン゙゚。`-「」.。、ー「」・\s]+)$/;

app.directive('kataKana', function() {
return {
// restrict: 'A',
// scope: {},
require: '?ngModel',
link: function(scope, element, attrs, ngModelCtrl) {

if(!ngModelCtrl) {
return;
}

if (ngModelCtrl.$isEmpty(element.val())) {
scope.kanaerror = false;
}

element.bind('keypress', function(event) {

if(event.keyCode === 32) {
event.preventDefault();
}
});
/**
* var setObjFill
* setObjFill == 0 check katakana full size and half size
* setObjFill == 1 check katakana only full size
* setObjFill == 2 check katakana only half size
*/
element.bind('keyup', function(event) {
if (!element.val() || element.val() == null || element.val() == '') {
scope.kanaerror = false;
} else {
var setObjFill = attrs.kataKana.split(',');
if(setObjFill == 0) {
if (KANA_ALL_SIZE_REGEXP.test(element.val())) {
scope.kanaerror = false;
} else {
scope.kanaerror = true;
}
} else if (setObjFill == 1) {
console.log('ee');
if (KANA_FULL_SIZE_REGEXP.test(element.val())) {
scope.kanaerror = false;
} else {
scope.kanaerror = true;
}
} else {
if (KANA_HAFL_SIZE_REGEXP.test(element.val())) {
scope.kanaerror = false;
} else {
scope.kanaerror = true;
}
}
}

scope.$apply();
});
}
};
});


in html:

<input id="txt_kana" kata-kana="1" name="txt_kana">


The problem



If in that form we use
kata-kana="1"
twice, my code always return
true
or
false
for two elements using
kata-kana="1"
. Because my code return
scope.kanaerror
. But I don't know how to resolve that problem.

Answer

I guess you want to check if the input is Katakana japanese language by watching scope.kanaerror which is a share scope. if you have multiple inputs but your scope.kanaerror is only one, then scope is not issolated that why you always get true or false(i guess).

I suggest you use ng-model for your input and check the model itself for each input if you have them more than two.

<input id="txt_kana" ng-model='input1' kata-kana name="txt_kana">
<input id="txt_kana" ng-model='input2' kata-kana name="txt_kana">

And in your directive:

app.directive('kataKana', function() {
  return {
    // restrict: 'A',
    // scope: {},
    require: '?ngModel',
    link: function(scope, element, attrs, ngModelCtrl) {
      var KANA_ALL_SIZE_REGEXP = /\d+/g;
      var KANA_FULL_SIZE_REGEXP = /[A-Z]/g;
      var KANA_HAFL_SIZE_REGEXP = /[a-z]/g;


      ngModelCtrl.$parsers.push(function(viewValue) {
        // this is to limit input charactor
        element.bind('keypress', function(event) {
          if (event.keyCode === 5) {
            event.preventDefault();
            return false;
          }
        });
        if (!viewValue) {
          return false; // return to modelValue for controller
        }
        if (KANA_ALL_SIZE_REGEXP.test(viewValue)) {
          return 'helo'; // return to modelValue for controller and interpolation
        } else if (KANA_FULL_SIZE_REGEXP.test(viewValue)) {
          return 'hi'; //return to modelValue for controller
        } else if (KANA_HAFL_SIZE_REGEXP.test(viewValue)) {
          return 'hey'; //return to modelValue for controller
        }

      })
    }
  };
});

I refactor your code but as I cannot type japanese so I change Regex. I hope you get the idea. in my code I make use the ngModelcontroler.$parsers and viewValue to return modelValue which use by controller and interpolation. Here is a working plunker. hope that help.