2014-01-25 4 views
8

Gibt es eine einfache Möglichkeit, ein einzelnes Tristate-Kontrollkästchen auf einer Webseite zu platzieren und es an ein boolesches Modell zu binden, damit letzteres die Werte true, false oder null annehmen kann?Was ist der beste Weg, um ein einzelnes Tristate-Kontrollkästchen innerhalb angularjs zu implementieren?

Die nächste Lösung, die ich bisher gefunden habe, ist http://jsfiddle.net/HB7LU/454/, aber es hat einen Fehler beim Einrichten eines anfänglichen Ansichtszustands (da es keine Möglichkeit gibt, beim ersten Rendering einen Modellwert zu erhalten). Alle anderen Vorschläge befassen sich mit mehreren untergeordneten Kontrollkästchen und lösen das Problem, indem Sie auf sie aufpassen.

Antwort

7

http://jsfiddle.net/xJhEG/ Ich habe es in einem kommerziellen Projekt gemacht. Tristates sind wahr, falsch, null (nicht "unbekannt")

.directive('indeterminate', [function() { 
    return { 
     require: '?ngModel', 
     link: function(scope, el, attrs, ctrl) { 
     var truthy = true; 
     var falsy = false; 
     var nully = null; 
     ctrl.$formatters = []; 
     ctrl.$parsers = []; 
     ctrl.$render = function() { 
      var d = ctrl.$viewValue; 
      el.data('checked', d); 
      switch(d){ 
      case truthy: 
      el.prop('indeterminate', false); 
      el.prop('checked', true); 
      break; 
      case falsy: 
      el.prop('indeterminate', false); 
      el.prop('checked', false); 
      break; 
      default: 
      el.prop('indeterminate', true); 
      } 
     }; 
     el.bind('click', function() { 
      var d; 
      switch(el.data('checked')){ 
      case falsy: 
      d = truthy; 
      break; 
      case truthy: 
      d = nully; 
      break; 
      default: 
      d = falsy; 
      } 
      ctrl.$setViewValue(d); 
      scope.$apply(ctrl.$render); 
     }); 
     } 
    }; 
    }]) 
+0

Ist das Browser abhängig? Ich konnte nur sehen, dass es sich von "wahr" zu "falsch" ändert (genauso wie es keine Anweisung oder Änderungshandler gibt) ?! Getestet über IE11. – Sebastian

+0

Danke.Ich gab Ihrer Anweisung nach und erstellte eine Dreistaaten-Richtlinie mit 2 Ankreuzfeldern. http://jsfiddle.net/laurilubi/dj6gkzrg/2/ –

1

Ich habe erstellt Wechsel Richtlinie, die Sie verwenden können. Three-state checkbox AngularJS Directive on GitHub

Es gibt auch einen Beitrag, wie es gebaut wurde: Creating Angulr Directive "Three-state checkbox

können Sie versuchen, eine DEMO

und die Richtlinie sieht wie folgt aus:

angular.module("threeStateCheckbox", []) 
    .directive("threeStateCheckbox", ['$compile', function($compile){ 
     return { 
      restrict: "A", 
      transclude: true, 
      require: 'ngModel', 
      link: function(scope, element, attrs, ngModel){ 
       var states = [true, false, null]; 
       var classNames = ["checked", "unchecked", "clear"]; 
       scope.click = function(){ 
        var st; 
        states.map(function(val, i){ 
         if(ngModel.$modelValue === val){ 
          st = states[(i+1)%3]; 
         } 
        }); 
        ngModel.$setViewValue(st); 
        ngModel.$render(); 
       }; 
       scope.tscClassName = function(){ 
        var className; 
        states.map(function(val, i){ 
         if(ngModel.$modelValue=== val){ 
          className = classNames[i]; 
         } 
        }); 
        return className; 
       }; 
       element.attr("class", "tri-sta-che "); 
       element.attr("ng-click", "click()"); 
       element.attr("ng-class", "tscClassName()"); 
       element.removeAttr("three-state-checkbox"); 
       $compile(element)(scope); 
      } 
     }; 
    }]); 
1

Sie nehmen Vorteil der unbestimmte Zustand von <input type="checkbox">.

MDN web docs: Es gibt einen unbestimmten Status von Kontrollkästchen, von denen eines nicht aktiviert oder deaktiviert ist, aber nicht festgelegt ist. Dies wird mithilfe der unbestimmten Eigenschaft des HTMLInputElement-Objekts über JavaScript festgelegt (es kann nicht mithilfe eines HTML-Attributs festgelegt werden).

Plunker: TRISTATE DIRECTIVE

HTML

<label> 
    <input type="checkbox" ng-model="state" indeterminate /> {{state}} 
</label> 

RICHTLINIE

app.directive('indeterminate', function() { 
    return { 
    restrict: 'A', 
    scope: { 
     model: '=ngModel' 
    }, 
    link: function(scope, el, attrs, ctrl) { 
     var states = [true, false, undefined]; 
     var index = states.indexOf(scope.model); 
     setIndeterminate(); 

     el.bind('click', function() { 
     scope.model = states[++index % 3]; 
     setIndeterminate(); 
     }); 

     function setIndeterminate() { 
     scope.$applyAsync(function() { 
      el[0].indeterminate = (scope.model === undefined); 
     }); 
     } 
    } 
    }; 
}); 

EXTRA: Wenn Sie eine Zeichenfolge darzustellen unbestimmten Zustand hinzufügen wollen, benutzen Sie diese CSS

input:indeterminate:after { 
    content: "indeterminate"; 
    padding-left: 20px; 
    display: inline-block; 
    width: 80px; 
} 
Verwandte Themen