0

Ich habe eine Direktive, die eine Maske und Validierung für eine Eingabesteuerung hat. Es ist im Grunde eine Zeiteingabe, bei der der Benutzer etwa 45 (45 Minuten) oder 2,5 (2,5 Stunden => 150 Minuten) eingeben kann. Die Eingabe ist eine type=number beim Bearbeiten, aber eine type=text bei der Anzeige des Ergebnisses mit einem Filter.AngularJS Eingabemaske mit Validierung

(Nur Schritte von 15 Minuten sind erlaubt, und die Filter werden auf dem Blur-Ereignisse angewandt)

alle außer gut funktionieren, dass der Anfangswert, wenn ich in das Textfeld klicken, verloren geht. Im Ereignis focus ist der Wert scope.minutes nicht definiert, wobei dies der in der Steuerung eingestellte Wert 90 sein sollte. Ich kann nicht herausfinden warum.

angular.module('demoApp', []) 
 
\t .controller('MainController', MainController) 
 
    .filter("hoursMinutes", function() { 
 
      return function (mins) { 
 
       if (mins == 0) return "0 mins"; 
 
       var hours = ((mins - (mins % 60))/60); 
 
       var minutes = (mins % 60); 
 
       return (hours > 0 ? hours + " hr" + (hours === 1 ? "" : "s") : "") + (minutes > 0 ? " " + minutes + " min" + (minutes === 1 ? "" : "s") : ""); 
 
      } 
 
     }) 
 
    .directive("ixTimeEntry", function ($filter) { 
 
      return { 
 
       restrict: "A", 
 
       require: 'ngModel', 
 
       scope: { 
 
        minutes: "=", 
 
        filter: "@", 
 
        inputFormat: "@" 
 
       }, 
 
       link: function (scope, element, attr, ngModel) { 
 
        
 
        // could set a max attribute, so mins can't be more than 1440 (a day)? 
 

 
        var inputFormat = scope.inputFormat || "minutes"; 
 
        var filter = scope.filter || "hoursMinutes"; 
 

 
        // for DOM -> model validation 
 
        ngModel.$parsers.unshift(function (value) { 
 
         var result = validate(value); 
 
         ngModel.$setValidity('ixTimeEntry', result.valid); 
 
         return result.value; 
 
        }); 
 

 
        // for model -> DOM validation 
 
        ngModel.$formatters.unshift(function (value) { 
 
         ngModel.$setValidity('ixTimeEntry', true); 
 
         return $filter(filter)(value); 
 
        }); 
 

 
        function validate(input) { 
 
         var result = { valid: false, value: input }; 
 
         if (input === undefined) return result; 
 
         input = +input; 
 
         if (input === 0) return result; 
 
         if (input < 0) return result; 
 

 
         if (inputFormat === "minutes") { 
 
          // entering as minutes: 
 
          // if 15, 30, 45, 60, 75, 90, etc  => treat as minutes 
 
          // if .25, .5, .75, 1, 1.25, ...12  => treat as hours 
 
          // else (e.g. 13, 14, 16, 17, 18, etc) => invalid 
 
          if (input % 15 === 0) result = { valid: true, value: input }; 
 
          if (input % .25 === 0 && input <= 12) result = { valid: true, value: input * 60 }; 
 
         } else if (inputFormat === "hours") { 
 
          // entering as hours: 
 
          // if .25, .5, .75, 1, 1.25, etc  => treat as hours 
 
          // else         => invalid 
 
          if (input % .25 === 0) result = { valid: true, value: input * 60 }; 
 
         } else { 
 
          throw "Invalid inputFormat in timeEntry"; 
 
         } 
 

 
         return result; 
 
        } 
 

 
        function addMask(text) { 
 
         return $filter(filter)(text); 
 
        } 
 

 
        function removeMask(text) { 
 
         if (inputFormat === "hours") 
 
          return +text/60; 
 
         return text; 
 
        } 
 

 
        element.val(addMask(scope.minutes)); 
 

 
        element.bind("blur", function() { 
 
         element.attr("type", "text"); 
 
         scope.$apply(function() { 
 
          var value = validate(element.val()).value; 
 
          scope.minutes = value; 
 
          element.val(addMask(value)); 
 
         }); 
 
        }); 
 

 
        element.bind("focus", function() { 
 
         element.attr("type", "number"); 
 
         scope.$apply(function() { 
 
          element.val(removeMask(scope.minutes)); 
 
         }); 
 
        }); 
 
       } 
 
      }; 
 
     });; 
 

 

 
function MainController() { 
 
\t var vm = this; 
 
    vm.minutes1 = 90; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> 
 

 
<div ng-app="demoApp" ng-controller="MainController as vm"> 
 
<form id="timeForm" name="timeForm" > 
 
<input type="text" class="form-control" name="time" placeholder="time" ix-time-entry input-format="minutes" minutes="vm.minutes" filter="hoursMinutes" ng-required="true" ng-model="vm.minutes1" /> 
 
</form> 
 
<br> 
 
Model: {{vm.minutes1}}<br> 
 
Valid: {{timeForm.time.$valid}}<br> 
 
</div>

Antwort

1

Sie setzen nur vm.minutes1 = 90; in Ihrem MainController. Es funktioniert, wenn Sie auch vm.minutes = 90; setzen.

angular.module('demoApp', []) 
 
\t .controller('MainController', MainController) 
 
    .filter("hoursMinutes", function() { 
 
      return function (mins) { 
 
       if (mins == 0) return "0 mins"; 
 
       var hours = ((mins - (mins % 60))/60); 
 
       var minutes = (mins % 60); 
 
       return (hours > 0 ? hours + " hr" + (hours === 1 ? "" : "s") : "") + (minutes > 0 ? " " + minutes + " min" + (minutes === 1 ? "" : "s") : ""); 
 
      } 
 
     }) 
 
    .directive("ixTimeEntry", function ($filter) { 
 
      return { 
 
       restrict: "A", 
 
       require: 'ngModel', 
 
       scope: { 
 
        minutes: "=", 
 
        filter: "@", 
 
        inputFormat: "@" 
 
       }, 
 
       link: function (scope, element, attr, ngModel) { 
 
        
 
        // could set a max attribute, so mins can't be more than 1440 (a day)? 
 

 
        var inputFormat = scope.inputFormat || "minutes"; 
 
        var filter = scope.filter || "hoursMinutes"; 
 

 
        // for DOM -> model validation 
 
        ngModel.$parsers.unshift(function (value) { 
 
         var result = validate(value); 
 
         ngModel.$setValidity('ixTimeEntry', result.valid); 
 
         return result.value; 
 
        }); 
 

 
        // for model -> DOM validation 
 
        ngModel.$formatters.unshift(function (value) { 
 
         ngModel.$setValidity('ixTimeEntry', true); 
 
         return $filter(filter)(value); 
 
        }); 
 

 
        function validate(input) { 
 
         var result = { valid: false, value: input }; 
 
         if (input === undefined) return result; 
 
         input = +input; 
 
         if (input === 0) return result; 
 
         if (input < 0) return result; 
 

 
         if (inputFormat === "minutes") { 
 
          // entering as minutes: 
 
          // if 15, 30, 45, 60, 75, 90, etc  => treat as minutes 
 
          // if .25, .5, .75, 1, 1.25, ...12  => treat as hours 
 
          // else (e.g. 13, 14, 16, 17, 18, etc) => invalid 
 
          if (input % 15 === 0) result = { valid: true, value: input }; 
 
          if (input % .25 === 0 && input <= 12) result = { valid: true, value: input * 60 }; 
 
         } else if (inputFormat === "hours") { 
 
          // entering as hours: 
 
          // if .25, .5, .75, 1, 1.25, etc  => treat as hours 
 
          // else         => invalid 
 
          if (input % .25 === 0) result = { valid: true, value: input * 60 }; 
 
         } else { 
 
          throw "Invalid inputFormat in timeEntry"; 
 
         } 
 

 
         return result; 
 
        } 
 

 
        function addMask(text) { 
 
         return $filter(filter)(text); 
 
        } 
 

 
        function removeMask(text) { 
 
         if (inputFormat === "hours") 
 
          return +text/60; 
 
         return text; 
 
        } 
 

 
        element.val(addMask(scope.minutes)); 
 

 
        element.bind("blur", function() { 
 
         element.attr("type", "text"); 
 
         scope.$apply(function() { 
 
          var value = validate(element.val()).value; 
 
          scope.minutes = value; 
 
          element.val(addMask(value)); 
 
         }); 
 
        }); 
 

 
        element.bind("focus", function() { 
 
         element.attr("type", "number"); 
 
         scope.$apply(function() { 
 
          element.val(removeMask(scope.minutes)); 
 
         }); 
 
        }); 
 
       } 
 
      }; 
 
     });; 
 

 

 
function MainController() { 
 
\t var vm = this; 
 
    vm.minutes = 90; 
 
    vm.minutes1 = 90; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> 
 

 
<div ng-app="demoApp" ng-controller="MainController as vm"> 
 
<form id="timeForm" name="timeForm" > 
 
<input type="text" class="form-control" name="time" placeholder="time" ix-time-entry input-format="minutes" minutes="vm.minutes" filter="hoursMinutes" ng-required="true" ng-model="vm.minutes1" /> 
 
</form> 
 
<br> 
 
Model: {{vm.minutes1}}<br> 
 
Valid: {{timeForm.time.$valid}}<br> 
 
</div>

+0

Oh wow. So ein stoischer Tippfehler. Danke Andrew! – Sean