lundi 22 mai 2017

Angular checkboxes not independent

I'm having a peculiar issue some angular checkboxes

I create them in separate divs, with different ids per checkbox and they will be checked-unchecked depending on a set of data coming from a database.

I think this one is best understood with the code:

The html:

 <div class="form-group row">
     <label for="field_publication" class="col-md-2 form-control-label">Drug/s:</label>
       <div class="btn btn-sm btn-primary">
        <input type="checkbox" id="check1" ng-checked="drugTypeIds.indexOf(1)!==-1" ng-click="updateSelection(1, publication, 'antimalarials')"> Antimalarial
         </div>
         <div class="btn btn-sm btn-primary">
         <input type="checkbox" id="check2" ng-checked="drugTypeIds.indexOf(2)!==-1" ng-click="updateSelection(2, publication, 'antibiotics')"> Antibiotic
        </div>
       <div class="btn btn-sm btn-primary">
      <input type="checkbox" id="check3" ng-checked="drugTypeIds.indexOf(3)!==-1" ng-click="updateSelection(3, publication, 'antiretrovirals')"> Antiretroviral
      </div>
       <div class="btn btn-sm btn-primary">
       <input type="checkbox" id="check4" ng-checked="drugTypeIds.indexOf(4)!==-1" ng-click="updateSelection(4, publication, 'antidiabetics')"> Antidiabetic
       </div>
       <div class="btn btn-sm btn-primary">
       <input type="checkbox" id="check5" ng-checked="drugTypeIds.indexOf(6)!==-1" ng-click="updateSelection(6, publication, 'antituberculosis')"> Antituberculosis
       </div>
       <div class="btn btn-sm btn-primary">
       <input type="checkbox" id="check6" ng-checked="drugTypeIds.indexOf(5)!==-1" ng-click="updateSelection(5, publication, 'maternal and reproductive')"> Maternal Health
       </div>
</div>

So, the ng-checked is telling the code to look for the id of the object amongst the ones in an array that I've created once the data has been uploaded to the form, this happens in the controller, with this method:

$scope.drugTypeIds = null;
    $scope.checkboxes = function (publicationDrugTypes) {
                    $scope.drugTypeIds = [];
                    publicationDrugTypes.forEach(function (typeDrug) {
                        $scope.drugTypeIds.push(typeDrug.id);
                    });
                };

So, here the drugTypeIds is initialized with a null value until the data is loaded, once the data is loaded it will go to the variable publicationDrugTypes of the publication object and pass that as a parameter to the checkboxes function:

 $scope.checkboxes(formDTO.publication.publicationDrugTypes);

Now the array(drugTypeIds) which was null will get the values of the ids that are in the publicationDrugTypes variable and the HTML code will check the right boxes. Up to here it works just fine

Now, if the user wants to add/remove drugTypes from the publication, the HTML uses the updateSelection() code from the controller:

$scope.updateSelection = function (drugTypeId, publication, type){
                if ($scope.drugTypeIds.indexOf(drugTypeId)!==-1){
                    publication.publicationDrugTypes.splice(publication.publicationDrugTypes.indexOf($scope.publicationDrugTypes[drugTypeId-1]),1);
                    $scope.drugTypeIds.splice($scope.drugTypeIds.indexOf(drugTypeId));
                }
                else {
                publication.publicationDrugTypes.push({id:$scope.publicationDrugTypes[drugTypeId-1].id,name:$scope.publicationDrugTypes[drugTypeId-1].name}); $scope.drugTypeIds.push(drugTypeId);
            };

This code is expecting the id of the new drugType, the publication we're going to add it to and the type (this variable is currently unused)

So, now it checks if the id was in the previous list, if it was, it will erase it, if not, it will add it.

The adding works just fine in both the frontend and the database, it's when splicing that I get several checkboxes unchecking themselves at the same time, I can't figure out why as they all have different ids, different conditions and no particular model attached.

I have adapted the code in a jsfiddle, the error is only reproduceable the first time you run it (unlike in my application where it happens every time), and you need to click the button first so the code from the first method will run. The error will occur when you attempt to uncheck Antidiabetic checkbox




Aucun commentaire:

Enregistrer un commentaire