2013-10-28 24 views
51

Ho una lista di caselle di controllo, di cui almeno una è obbligatoria. Ho cercato di ottenere questo risultato tramite la convalida di AngularJS, ma ho avuto un momento difficile. Qui di seguito è il mio codice:Convalida casella di controllo Gruppo angolare

// Code goes here for js 

var app = angular.module('App', []); 

function Ctrl($scope) { 
    $scope.formData = {}; 
    $scope.formData.selectedGender = ''; 
    $scope.gender = [{ 
    'name': 'Male', 
    'id': 1 
    }, { 
    'name': 'Female', 
    'id': 2 
    }]; 
    $scope.formData.selectedFruits = {}; 
    $scope.fruits = [{ 
    'name': 'Apple', 
    'id': 1 
    }, { 
    'name': 'Orange', 
    'id': 2 
    }, { 
    'name': 'Banana', 
    'id': 3 
    }, { 
    'name': 'Mango', 
    'id': 4 
    }, ]; 
    $scope.submitForm = function() { 

    } 
} 
// Code goes here for html 
<!doctype html> 
<html ng-app="App"> 

<head> 
    <!-- css file --> 
    <!--App file --> 
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.js"></script> 
    <!-- External file --> 
</head> 

<body> 
    <div ng-controller="Ctrl"> 
    <form class="Scroller-Container"> 
     <div ng-app> 

     <form class="Scroller-Container" ng-submit="submit()" ng-controller="Ctrl"> 
      <div> 
      What would you like? 
      <div ng-repeat="(key, val) in fruits"> 
       <input type="checkbox" ng-model="formData.selectedFruits[val.id]" name="group[]" id="group[{{val.id}}]" required />{{val.name}} 
      </div> 
      <br /> 
      <div ng-repeat="(key, val) in gender"> 
       <input type="radio" ng-model="$parent.formData.selectedGender" name="formData.selectedGender" id="{{val.id}}" value="{{val.id}}" required />{{val.name}} 
      </div> 
      <br /> 
      </div> 
      <pre>{{formData.selectedFruits}}</pre> 
      <input type="submit" id="submit" value="Submit" /> 
     </form> 
     </div> 
     <br> 
    </form> 
    </div> 
</body> 

</html> 

Ecco il codice in plunker: http://plnkr.co/edit/Bz9yhSoPYUNzFDpfASwt?p=preview qualcuno ha fatto questo su AngularJS? Rendendo necessarie le caselle di controllo, mi costringe a selezionare tutti i valori della casella di controllo. Anche questo problema non è documentato nella documentazione di AngularJS.

risposta

98

Se si desidera richiedere almeno un elemento in gruppo viene selezionato, è possibile definire dinamica richiesto attributo con ng-richiesta.

Per i pulsanti di opzione genere questo sarebbe facile:

<input 
    type="radio" 
    ng-model="formData.selectedGender" 
    value="{{val.id}}" 
    ng-required="!formData.selectedGender" 
> 

gruppo Casella di controllo sarebbe troppo facile, se è stato utilizzato matrice per memorizzare frutti selezionati (basta controllare la lunghezza array), ma con l'oggetto è necessario verificare se qualsiasi dei valori sono impostati per allineare con filtro o funzione nel regolatore:

$scope.someSelected = function (object) { 
    return Object.keys(object).some(function (key) { 
    return object[key]; 
    }); 
} 
<input 
    type="checkbox" 
    value="{{val.id}}" 
    ng-model="formData.selectedFruits[val.id]" 
    ng-required="!someSelected(formData.selectedFruits)" 
> 

Aggiornamento:

const someSelected = (object = {}) => Object.keys(object).some(key => object[key]) 

Anche tenere a mente che restituirà false se il valore è 0.

+8

fatto l'uomo di trucco .... posso comprare la birra per te !! ..thnks man ... @ klaster_1 –

+1

Grazie Klaster_1 esempio http://embed.plnkr.co/i0MSPVXmZFVNrfbaT2aK/script.js –

+1

Ciao Klaster_1. Non penso che questa sia una buona soluzione. Wehn Ho un gruppo di checkbox che sta controllando tutti loro. Non è ottimizzato e in IE8 devi selezionare tutte le caselle di controllo richieste = true. Aggiungo un console.log sull'esempio di @Fatih Hayrioglu per vedere quante console vengono aggiunte con un solo clic: [campione] (http://plnkr.co/edit/yrvalu7Mg851PsvLeFEb?p=preview) – Kosmonaft

2

Grazie a Klaster_1 per la risposta accettata. Mi sono basato su questo utilizzando ng-change sugli input della casella di controllo per impostare una variabile dell'ambito locale, che verrebbe utilizzata come espressione ng-required. Ciò impedisce l'esecuzione di someSelected() in ogni digest.

Ecco un plunkr dimostra questo: http://embed.plnkr.co/ScqA4aqno5XFSp9n3q6d/

Ecco il codice HTML e JS per i posteri.

<!DOCTYPE html> 
<html ng-app="App"> 

<head> 
    <meta charset="utf-8" /> 
    <script data-require="[email protected]" data-semver="1.4.9" src="https://code.angularjs.org/1.4.9/angular.js"></script> 
    <script src="script.js"></script> 
</head> 

<body> 
    <div ng-controller="AppCtrl"> 
    <form class="Scroller-Container" name="multipleCheckbox" novalidate=""> 
     <h3>What would you like?</h3> 
     <div ng-repeat="fruit in fruits"> 
     <input type="checkbox" ng-model="formData.selectedFruits[fruit.name]" ng-change="checkboxChanged()" ng-required="!someSelected" /> {{fruit.name}} 
     </div> 
     <p style="color: red;" ng-show="multipleCheckbox.$error.required">You must choose one fruit</p> 
    </form> 
    <pre>Fruits model: 
{{formData.selectedFruits | json}}</pre> 
    </div> 
</body> 

</html> 
angular 
    .module('App', []) 
    .controller('AppCtrl', function($scope) { 

    var selectedFruits = { 
     Mango: true 
    }; 

    var calculateSomeSelected = function() { 
     $scope.someSelected = Object.keys(selectedFruits).some(function(key) { 
     return selectedFruits[key]; 
     }); 
    }; 

    $scope.formData = { 
     selectedFruits: selectedFruits 
    }; 

    $scope.fruits = [{ 
     'name': 'Apple' 
    }, { 
     'name': 'Orange' 
    }, { 
     'name': 'Banana' 
    }, { 
     'name': 'Mango' 
    }]; 

    $scope.checkboxChanged = calculateSomeSelected; 

    calculateSomeSelected(); 
    }); 
1

Siamo in grado di realizzare il vostro requisito, senza attraversare tutta esempio le caselle di controllo. Ecco il codice di esempio

<script> 
angular.module('atLeastOneExample', []) 
.controller('ExampleController', ['$scope', function($scope) { 
    $scope.e = function(s){ 
    eval(s); 
    }; 
}]); 
</script> 

Eccomi avvolgendo javascript funzione eval in funzione "e" per accedervi.

<form name="myForm" ng-controller="ExampleController" ng-init="c=0"> 
    <label> 
     Value1: <input type="checkbox" ng-model="checkboxModel.value[0]" ng-change="e('($scope.checkboxModel.value[0])?$scope.c++:$scope.c--')"/> 
    </label><br/> 
    <label> 
     Value2: <input type="checkbox" ng-model="checkboxModel.value[1]" ng-change="e('($scope.checkboxModel.value[1])?$scope.c++:$scope.c--')"/> 
    </label><br/> 
    value = {{checkboxModel.value}}<br/> 
    isAtLeastOneChecked = {{c>0}} 
</form> 
2

Va bene forse molto in ritardo alla festa, ma se si dispone di un array di oggetti che si sta guardando, la soluzione del solo controllando la lunghezza della matrice di oggetti selezionati lavorato per me.
HTML

<div ng-repeat="vehicle in vehicles"> 
    <input type="checkbox" name="car" ng-model="car.ids[vehicle._id]" ng-required=" car.objects.length <= 0"> {{vehicle.model}} {{vehicle.brand}} <b>{{vehicle.geofenceName}}</b> 
</div> 

JS

$scope.vehicles = [{},{}] // Your array of objects; 
$scope.car = { 
    ids: {}, 
    objects: [] 
}; 

$scope.$watch(function() { 
    return $scope.car.ids; 
}, function(value) { 
    $scope.car.objects = []; 
    angular.forEach($scope.car.ids, function(value, key) { 
     value && $scope.car.objects.push(getCategoryById(key)); 
    }); 
}, true); 

function getCategoryById(id) { 
    for (var i = 0; i < $scope.vehicles.length; i++) { 
     if ($scope.vehicles[i]._id == id) { 
      return $scope.vehicles[i]; 
     } 
    } 
} 

capisco cosa sta succedendo in questa soluzione che si sta verificando tutte le opzioni casella di controllo per sapere quale viene cliccato. Ma da quello che so questa è di gran lunga la soluzione più semplice (da capire e implementare) e funziona come un fascino se sai che le tue opzioni saranno limitate. Per una soluzione più ottimizzata. Controlla le risposte sopra.

Problemi correlati