0

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;
}

1 Answer 1

1

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

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.