Search code examples
javascriptangularjsumbracoangular-changedetection

Umbraco v8: custom script call model change


I have an Umbraco plugin that is literally a vanilla .js file that allows me to retrieve some JSON from a service, then it fills in some of the fields on the current page, e.g by doing:

var setTxt = function(id, val) {
  var txt = document.getElementById(id);
  if (txt && val != null && val != undefined) {
    return txt.value = val;
  };
};

However, when I hit save, the angular model doesn't save any of the changes to the inputs - probably because no change detection has been triggered.

I've tried e.g with the field 'publisher':

angular.element(document.querySelector("#publisher")).scope().apply()

but I get the error:

VM94421:95 TypeError: Cannot read property 'apply' of undefined

I really don't want to get stuck into angular 1, my vanilla js is all working, I just need to get umbraco to scoop up all the values that I've set on the various fields.

Q) How can I force this?

p.s. - please don't comment that this is bad practice, I just need to get this job done.


Solution

  • EDIT by question poster: Turns out as jQuery Lite is included already, you can just call:

    $('#' + id).trigger('input');

    Original answer below also works:

    You should trigger "input" event to let angular know your changes:

    var setTxt = function(id, val) {
      var txt = document.getElementById(id);
      if (txt && val != null && val != undefined) {
        txt.value = val;
        raiseEvent(txt, 'input');
    
        return val;
      };
    };
    
    var raiseEvent = function(el, eventType) {
        var event = document.createEvent('Event');
        event.initEvent(eventType, true, true);
        el.dispatchEvent(event);
    };
    

    BTW, $scope doesn't have "apply" function. Its name is "$apply". Also as far I understand "scope.$appy(cb)" will pick up changes that are applied to the scope variable, in your case you manipulate directly with dom element.