Search code examples
angularjsformsschemawatchangular-schema-form

how to detect a change inside angular schema form?


I'm using angular schema form and I need to detect when a generated element is deleted.

For your comfort I have made a plunker: https://plnkr.co/edit/ogaO8MBmNtxYBPHR67NC?p=info

controller file:

   //model form
    vm.modelForm = {"beneficiaries":[]};

    /*
    ================
    schema
    ================
    */
    vm.schema = {
      "type": "object",
      "title": "Beneficiario",
      "required": [
        "beneficiaries"
      ],
      "properties": {
        "beneficiaries": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "name": {
                "type": "number",
                "description": "Monto a transferir",
                "minimum": 1,
                "maximum": 500,
                "validationMessage": {
                   101: "El valor de este campo debe ser de al menos {{schema.minimum}} Bs",
                   103: "{{viewValue}} Bs es mayor que el máximo permitido para una transferencia: {{schema.maximum}} Bs",
                   302: "Este campo es requerido"
                }
              },
              "spam": {
                "title": "Spam",
                "type": "boolean",
                "default": true
              },
              "comment": {
                "type": "string",
                "maxLength": 20,
                "validationMessage": "Cantidad máxima de carácteres excedida"
              }
            },
            "required": [
              "name",
              "comment"
            ]
          }
        }
      }
    };

    /*
    ===============
    form
    ===============
    */
    vm.form = [
      {
        "type": "help",
        "helpvalue": "<h4>Transferencias y pagos</h4><h5>Lista de elementos seleccionados</h5>"
      },
      {
        "key": "beneficiaries",
        "title": "Selección",
        "autocomplete": "off",
        "add": null,
        "style": {
          "add": "btn-success"
        },
        "items": [
          {
            "key": "beneficiaries[].name",
            "title": "Monto Bs",
            "feedback": false
          },
          {
            "key": "beneficiaries[].spam",
            "type": "checkbox",
            "title": "Agregar a pagos frecuentes",
            "condition": "model.beneficiaries[arrayIndex].name"
          },
          {
            "key": "beneficiaries[].description",
            "title": "Descripción",
            "feedback": false
          }
        ],
        "startEmpty": true
      },
      {
        "type": "submit",
        "style": "btn-success btn-block",
        "title": "Agregar"
      }
    ];

    //form data
    vm.elements = [
      {
        "idE":1,
        "name": "Elemento 1",
        "selected": false
      },
      {
        "idE":2,
        "name": "Elemento 2",
        "selected": false
      },
      {
        "idE":3,
        "name": "Elemento 3",
        "selected": false
      },
      {
        "idE":4,
        "name": "Elemento 4",
        "selected": false
      }
    ];


    //function to select a element to put it inside of form
    vm.select = function(){
      //active elements
      var actives = _.filter(vm.elements, function(element) { 
        return element.selected == true; 

      });

      vm.modelForm.beneficiaries = new Array(actives.length);

      _.forEach(actives, function(value, key) {
        vm.modelForm.beneficiaries[key] = {"spam":true};
      });

    };

    //watch schema form
    $scope.$watch(function(){
      return vm.modelForm.beneficiaries;
    }, function(newValue, oldValue){
      if(newValue === oldValue) {
       return;
      }
      console.log("change");
    });

I can detect when a element is deleted if I change the model of the form, but if I try to delete a element of that form using the "x" from any generated element, it's not possible detect if the model has changed.

So, looking the plunker, I tried to detect a change with a $watch over the model of the form, but nothing happens if I delete a element doing click over the "X", I need detect when this action be done.


Solution

  • The reference is most likely not changing, so you'll have to use the third parameter on the $watch statement:

    $scope.$watch(function () {
        return vm.modelForm.beneficiaries;
    }, function (newValue, oldValue) {
        if (newValue === oldValue) {
            return;
        }
        console.log("change");
    }, true);
    

    The ,true tells it to do a full traversal of the object to check if it's changed. Look at objectEquality here: https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$watch