Je suis développeur web freelance et propose des formations à Symfony2 ! Contactez-moi pour en discuter.

Gérer les cases à cocher avec angularJS est un peu plus compliqué que les autres associations. On ne peut pas simplement utiliser ng-model, il faut gérer la possibilité que plusieurs cases soient cochées et cela nécessite d’implémenter cette logique métier.

Nous allons voir comment le faire à la main, puis à l’aide de la directive checklist-model.

Gérer la checkbox « à la main »

Le moyen le plus simple, c’est d’avoir un tableau des différentes possibilités, de boucler dessus. Pour chaque case à cocher, lors d’un clic on va déclencher une action de contrôleur. On va également tester si la case est cochée ou non via une autre action de contrôleur.

1
2
3
4
5
6
7
8
9
10
11
<ul class="checkboxes">
    <li ng-repeat="(key, text) in availableTypes">
        <label>
            <input type="checkbox"
               name="filterType"
               ng-click="toggleTypeSelection({{ key }})"
               ng-checked="isTypeChecked({{ key }})">
                {{ text }}
        </label>
    </li>
</ul>

Il faut donc dans le contrôleur plusieurs choses :

  • Une liste des différentes possibilités (availableTypes)
  • La propriété qui va stocker le modèle (types)
  • Une méthode pour dire si une case est cochée ou non (isTypeChecked)
  • Une méthode pour cocher les cases (toggleTypeSelection)

Le javascript associé contient donc ces quatres choses :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
$scope.types = [];

$scope.availableTypes = {
    'apple': 'Pomme',
    'peach': 'Peche',
    'pear':  'Poire'
}

// Dit si une case est cochée
// en testant si le tableau types contient la propriété testée.
$scope.isTypeChecked = function(typeName){
    return $scope.types.indexOf(typeName) > -1;
}

// Coche ou décoche une case
// en ajoutant ou supprimant une propriété du tableau types
$scope.toggleTypeSelection = function(typeName){
    if ($scope.isTypeChecked(typeName)) {
        var index = $scope.types.indexOf(typeName);
        $scope.types.splice(index, 1);
    }
    else {
      $scope.types.push(typeName);
    }
}

Factorisation grâce à checklist-model

En fait, on se rend assez vite compte que les deux actions de contrôleur sont toujours les mêmes. Pour éviter de devoir la réécrire à chaque fois, on peut donc les factoriser, dans une directive ou un service. Plutôt que de le faire soi-même, il existe une directive, checklist-model qui fait cela.

Le code HTML fait la même taille, mais la philosophie est différente. checklist-model devient l’équivalent du classique ng-model, et checklist-value va devenir la propriété à ajouter au tableau types lorsque la case est cochée ou non. La directive peut également savoir si une case est cochée, en testant si le tableau du modèle contient cette propriété.

1
2
3
4
5
6
7
8
9
10
<ul class="checkboxes">
    <li ng-repeat="(key, text) in availableTypes">
        <label>
            <input type="checkbox"
               checklist-model="types"
               checklist-value="key">
                {{ text }}
        </label>
    </li>
</ul>

Le contrôleurs devient beaucoup plus simple. Il n’y a plus besoin d’implémenter les logique d’actions au clic, et pour tester si une case est cochée, c’est géré par la directive. Il suffit de déclarer les différents tableaux :

1
2
3
4
5
6
7
$scope.types = [];

$scope.availableTypes = {
    'apple': 'Pomme',
    'peach': 'Peche',
    'pear':  'Poire'
}

Répondre

Unable to load the Are You a Human PlayThru™. Please contact the site owner to report the problem.