vzhen
vzhen

Reputation: 11157

Pass div text to angularjs directive

I have a contenteditable directive with placeholder which based on Craig Stuntz's javascript contenteditable placeholder. This directive does the following job

  1. Check if div textContent exist, if exists hide placeholder else show placeholder
  2. If user focus on contenteditable then hide placeholder

But I have a problem which already mentioned by Craig Stunt

If you update the div text in JavaScript (instead of just typing into the div on the page), no events are fired, and you must let the plugin know that you've changed the contents by triggering the change event.

I have no idea where to put .triggerHandler('change') and how the directive know if div text from javascript is empty or not empty?

Below is the code

app.directive("contenteditable", function() {
return {
    require: 'ngModel',
    link: function(scope, element, attrs, ctrl) {
        // view -> model
    element.bind('input', function() {
    scope.$apply(function() {
        ctrl.$setViewValue(element.text());
    });

    if (this.textContent) {
            this.setAttribute('data-contenteditable-placeholder', 'true');
            console.log(this);
        } else {
        this.removeAttribute('data-contenteditable-placeholder');
        }
  });
    // model -> view
    //ctrl.$render = function() {
  //    element.text(ctrl.$viewValue);
    //};
    //ctrl.$setViewValue(element.text());
    }
}
});

CSS

*[data-placeholder]:not(:focus):not([data-contenteditable-placeholder])::before {
  content: attr(data-placeholder);
  margin-left: 2px;
  color: #b3b3b3;
}

div[contenteditable]:focus{
  outline: none;
}

Upvotes: 0

Views: 654

Answers (1)

Denison Luz
Denison Luz

Reputation: 3565

I believe you are almost there.

You just need to 'watch' the value of the input field so you can trigger your .triggerHandler('change') event.

The directive should $watch() your model for changes, and the watch callback should 1 - check if the div is empty and 2 - call your trigger event (or any DOM manipulation) - you can see pseudo code below.

scope.$watch('yourViewModel', function(newValue, oldValue) {

 // here you check if the newValue is empty

 // depending on the check above you call (or not) triggerHandler('change')

});

You can see that the second argument of the scope.$watch is a function that receives the newValue and oldValue of your model, so you can test inside that function if the newValue is empty (therefore checking if the div text is empty).

Hope that helps or at least points you to the right direction.

Upvotes: 1

Related Questions