Update attribute model to false when selecting another radio button AngularJS

0

Good evening to everyone:

  • I'm working on a form with AngularJS.

  • The idea is that by marking a field, more options are opened exclusive for that field (that is, only if that option is marked).

  • And I can only mark a field of all possible.

With these premises, especially the number 3, I'm testing with radio buttons. But one thing is getting complicated: when I select a radio button, I can not find a way to make the previous one go to false (all values are true or false). That is, we still see the exclusive options for when that radio button or checkbox are marked (and its model is true). In the image you can see notebooks when they should be hidden.

I leave a capture:

If I use checkbox, it's automatic:

    <label key="admin.prototexto.form.caderno" for="caderno" class="col-sm-8 col-sm-offset-1" >
           <input type="checkbox" id="caderno" ng-model="ctrl.item.caderno">
           {{'admin.prototexto.form.caderno' | translate}}
    </label>

The model is updated automatically when you mark and unmark.

My question is, what is the correct way to do this in angularJS with radio buttons or with checkboxes so that only one can be marked (I'm working with version 1.x, which never I've used so far).

Thank you very much.

Edited 1 to add requested data

The code I use with radio button is as follows:

<label key="admin.prototexto.form.folhasSoltas" for="folhasSoltas" class="col-sm-8 col-sm-offset-1" >
   <input type="checkbox" id="folhasSoltas" ng-model="ctrl.item.folhasSoltas" name="optradio"  ng-value="true" >
   {{'admin.prototexto.form.folhasSoltas' | translate}}
 </label>
 <label key="admin.prototexto.form.caderno" for="caderno" class="col-sm-8 col-sm-offset-1" >
       <input type="radio" id="caderno" ng-model="ctrl.item.caderno" name="optradio"  ng-value="true" >
       {{'admin.prototexto.form.caderno' | translate}}
 </label>

The driver:

(function () {
'use strict';

angular
    .module('app')
    .component('prototextoFormAdmin', {
        templateUrl: 'app/admin/dominio/prototexto/prototexto-form.admin.html',
        controller: Controller,
        controllerAs: 'ctrl',
        bindings: {
            item: '<',
            previousParams: '<',
            tipos: '<',
            genero: '<',
            assunto:'<',
            ciudades: '<',
            pais: '<',
            folha: '<',
        }
    });

/* @ngInject */
function Controller($timeout, $state, ModalService , CIUDAD_FORM_ADMIN, Pais, PAIS_FORM_ADMIN) {
    var vm = this;

    $timeout(function () {
        angular.element('.form-group:eq(0) input').focus();
    });

    vm.mode = $state.current.data.mode;
    vm.canSave = vm.mode === 'create' || vm.mode === 'edit';

    // Guardar formulario
    vm.save = function () {
        vm.item.$save().then(function () {
            ModalService.closeComponent(vm.item, 'admin/prototexto/list', vm.previousParams);
        });
    };

    vm.openCiudadModal = function () {
        ModalService.openComponent('admin.ciudad.create.title', CIUDAD_FORM_ADMIN, {size: 'lg'}).result.then(function (result) {

            // Añadimos el nuevo elemento al select
            vm.ciudades.push(result);
            // Asociamos el nuevo elemento a la entidad
            vm.item.ciudades.push(result);
        });
    };

    vm.openPaisModal = function () {
        ModalService.openComponent('admin.pais.create.title', PAIS_FORM_ADMIN, {size: 'lg'}).result.then(function (result) {
            // Asociamos el nuevo elemento a la entidad
            vm.item.pais = result;
        });
    };

    vm.paisService = Pais;


}

}) ();

    
asked by Hugo L.M 19.08.2017 в 22:26
source

3 answers

1

So that only one radio can be marked, you have to assign the same name to button radios. Once this is done you can show / hide the fields corresponding to each radio with a ngShow directive and a flag in the model.

In this example there is a flag called $scope.opciones.seleccionado that is of intero type. When seleccionado is equal to 1, then notebook options will be shown as ngShow will evaluate the expression and so on with the other options:

angular.module("app",[])
.controller("ctrl", function($scope){
  $scope.opciones = {
    seleccionado: -1
  };
  
  
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular.min.js"></script>

  <div ng-app="app" ng-controller="ctrl">
  <div >
    <label for="">
      Cuadernos <input type="radio" name="opciones" ng-click="opciones.seleccionado = 1">
    </label>
    
    <label for="">
      Libros <input type="radio" name="opciones" ng-click="opciones.seleccionado = 2">
    </label>
  </div>
  
  <label for="">
      Revistas <input type="radio" name="opciones" ng-click="opciones.seleccionado = 3">
  </label>
  
  <div ng-show="opciones.seleccionado == 1">
    Mostrando cuadernos
  </div>
  <div ng-show="opciones.seleccionado == 2">
    Mostrando libros
  </div>
  <div ng-show="opciones.seleccionado == 3">
    Mostrando revistas
  </div>
    
  </div>

Update.

Now that I stop to read your question I notice that you want to show / hide the controllers with a model of type boolean.

It would be the same as this in the example above only it will be valid for 2 options because boolean is true | false.

In the following example you will assign true or false opciones.cuadernos instead of a number when clicking on a radio:

angular.module("app",[])
.controller("ctrl", function($scope){
  $scope.opciones = {
    cuadernos : true
  };
  
  
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular.min.js"></script>

  <div ng-app="app" ng-controller="ctrl">
  <div >
    <label for="">
      Cuadernos <input checked type="radio" name="opciones" ng-click="opciones.cuadernos = true">
    </label>
    
    <label for="">
      Libros <input type="radio" name="opciones" ng-click="opciones.cuadernos = false">
    </label>
  </div>
 
  
  <div ng-show="opciones.cuadernos ">
    Mostrando cuadernos
  </div>
  <div ng-show="!opciones.cuadernos ">
    Mostrando libros
  </div>
 
    
  </div>
    
answered by 20.08.2017 в 18:44
0

I do not know if it will be the correct way or not, but I have come to a solution that does not do what I want, if it prevents me from marking more checkboxes without having left the previous one unchecked.

    var limit = 1;
    $('input.single-checkbox').on('click', function (evt) {
        if ($('.single-checkbox:checked').length > limit) {
            this.checked = false;
        }
    });

And each checkbox marked it with the single-checkbox class:

    <input class="single-checkbox" type="checkbox" id="folhasSoltas" ng-model="ctrl.item.folhasSoltas">

This way I can limit the number of checkboxes to the limit that I put: 1, 2, 3 ...

Original idea or at least from where I have obtained it and adapted it to my case: Link to Stackoverflow with the proposal

I do not give it as a solution, in case someone can get an option by checking an option, put the rest to false. Also in case someone offers the alternative with the radio buttons. And also because the question was not to limit the number of options. But if it is a partial solution to the problem of not finding a better one, it would be useful and could be useful to other people.

I've added it to my controller as follows:

    /* @ngInject */
function Controller($timeout, $state, ModalService , CIUDAD_FORM_ADMIN, Pais, PAIS_FORM_ADMIN) {

    var vm = this;

    var limit = 1;
    $('input.single-checkbox').on('click', function (evt) {
        if ($('.single-checkbox:checked').length > limit) {
            this.checked = false;
        }
    });

   [... Código no referente a la pregunta  ...]
    
answered by 21.08.2017 в 10:09
0

function MyController($scope) {

  $scope.opciones = [{
    id: 1,
    nombre: 'opt1',
    valor: true
  }, {
    id: 2,
    nombre: 'opt2',
    valor: false
  }, {
    id: 3,
    nombre: 'opt3',
    valor: false
  }, ];

  $scope.toggle_opts = function(id) {
    for (var i = 0; i < $scope.opciones.length; i++) {
      if ($scope.opciones[i].valor === true) {
        $scope.opciones[i].valor = false;
      }
    }
  }
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.1/angular.min.js"></script>
<div ng-app ng-controller="MyController">
  <div ng-repeat="opcion in opciones">
    <input type="checkbox" ng-click="toggle_opts(opcion.id)" ng-model="opcion.valor"> #{{opcion.nombre}}
    <br>
    <div ng-if="opcion.valor===true">
      Aqui van las opciones del {{opcion.nombre}}
    </div>
  </div>

This solution that I propose would work if you want to use "checkbox", I create a function toggle_opts that is in charge of unmarking the marking and the bindeo to the ng-click of each check box. It is a CONCEPT that you should apply if it serves you.

    
answered by 21.08.2017 в 10:46