Luiz Alves
Luiz Alves

Reputation: 2645

Updating model from directive in angularjs

I have a directive to drag and drop.

The drag and drop works well, but I have a problem with updating the model. After I drop some text into textarea, the text is showing ok, but the model is not updating.

What am I missing here?

//markup

 <textarea drop-on-me id="editor-texto" ng-trim="false" ng-model="mymodel"
 name="templateSms.template">test.</textarea>

//directive

angular
  .module('clinang')
  .directive('dragMe', dragMe)
  .directive('dropOnMe', dropOnMe);

dragMe.$inject = [];

function typeInTextarea(el, newText) {
  var start = el.selectionStart
  var end = el.selectionEnd
  var text = el.value
  var before = text.substring(0, start)
  var after  = text.substring(end, text.length)
  el.value = (before + newText + after)
  el.selectionStart = el.selectionEnd = start + newText.length
  el.focus()
}

function dragMe() {
  var DDO = {
    restrict: 'A',
    link: function(scope, element, attrs) {
      element.prop('draggable', true);
      element.on('dragstart', function(event) {
        event.dataTransfer.setData('text', event.target.id)
      });
    }
  };
  return DDO;
}
dropOnMe.$inject = [];
function dropOnMe() {
  var DDO = {
    restrict: 'A',
    link: function(scope, element, attrs) {
      element.on('dragover', function(event) {
        event.preventDefault();
      });
      element.on('drop', function(event) {
        event.preventDefault();
        var data = event.dataTransfer.getData("text");
        var x=document.getElementById(data);
        typeInTextarea(event.target,x.getAttribute('data-value'))
      });
    }
  };
  return DDO;
}

Upvotes: 0

Views: 111

Answers (1)

Shantanu
Shantanu

Reputation: 3513

Update your textarea model inside typeInTextarea function and using $apply run digest cycle to update the model change across whole app. For that with your current structure of directives with only link functions you'll need to pass scope to the typeInTextarea function (as a parameter). So your function will be:

function typeInTextarea(scope, el, newText) {
  var start = el.selectionStart
  var end = el.selectionEnd
  var text = el.value
  var before = text.substring(0, start)
  var after  = text.substring(end, text.length)
  el.value = (before + newText + after);
  scope.mymodel.textnote = el.value;
  el.selectionStart = el.selectionEnd = start + newText.length;
  el.focus();
}

and dropOnMe function will be:

function dropOnMe() {
  var DDO = {
    restrict: 'A',
    link: function(scope, element, attrs) {
      element.on('dragover', function(event) {
        event.preventDefault();
      });
      element.on('drop', function(event) {
        event.preventDefault();
        var data = event.dataTransfer.getData("text");
        var x=document.getElementById(data);
        typeInTextarea(scope, event.target,x.getAttribute('data-value'))
        scope.$apply();
      });
    }
  };
  return DDO;
}

Check out this example (I don't know which element you're dragging so e.g. I've considered span element & just used innerHTML for that ):

https://plnkr.co/edit/wGCNOfOhoopeZEM2WMd1?p=preview

Upvotes: 1

Related Questions