Frage

I have to insert a custom directive in my contenteditable div.

   /*Editor Div*/
      <div id="edBody"  contenteditable="true"></div>
   /*Insert one custom directive*/
   <a ng-click="insertType('fibtext')">Add Directive</a>

I tried this:

  <input type="button" value="Insert" ng-click="addHtmlAtCaret('<dc-tags></dc-tags>')">
   /* Directive */
    asignmentApp.directive('dcTags', function() {
       return {
          restrict: 'E',
          template: 'new <b> Value </b>'
       };
    });

Please help me. Fiddle:- http://jsfiddle.net/k2SUJ/1/

Here's a fiddle demo which i tried.

War es hilfreich?

Lösung

In order for Angular to be aware of your added element and do its magic, you need to $compile the element and link it to a scope.

So you'll need a controller with a scope. You also need to replace the onclick handlers with ng-click and also $compile the element:

In HTML:

<input type="button" value="..." ng-click="addHtmlAtCaret(...)">

In JS:

app.controller('ctrl', function ($compile, $scope) {
    $scope.addHtmlAtCaret = function (html) {
        document.getElementById('test').focus();
        ...
        var el = document.createElement("div");
        el.innerHTML = html;
        $compile(el)($scope);
        ...
    };
});

See, also, this short demo.

Andere Tipps

Before Doing the paste It will be good to save the cursor and Restore it. In the case of button only above will work. but if you use Popover or Dialog on button and after Closing the dialog the Content Editable Div Focus will go at first in AngularJS App. So Before doing Above please do this too. Consider This is your Content Editable Div as i show below. on ng-click and ng-keyup i just save the current Cursor of the editable DIV and when user open a dialog ,or popup or perform any action and call the function addHtmlAtCaret(html), just resotred the cursor to the last inputed position and proceed the same way as explained by the user gkalpak above.

var saveSelection, restoreSelection;
$scope.commentKeyInput = function(keyEvent,id) {  // (keyEvent.target).innerHTML='';
   		  if (keyEvent.which === 13){
   		    //alert('I am an alert');
   		  }
   		  else{
 		    var divID='comment'+id;   			  
   			savedSelection = saveSelection(document.getElementById(divID));
//   			savedSelection.start++;
//   			console.log(savedSelection.start);
   		  }
   		}   	     
   	  $scope.commentBoxClicked=function(event,id){  
   		  try{
   		    var divID='comment'+id;   			  
   			savedSelection = saveSelection(document.getElementById(divID));  
//   			console.log(savedSelection.start);
   		  }
   		  catch(e){
   			  alert(e);
   		  }  
   	  } 
      
      if (window.getSelection && document.createRange) {
    	    saveSelection = function(containerEl) {
    	        var range = window.getSelection().getRangeAt(0);
    	        var preSelectionRange = range.cloneRange();
    	        preSelectionRange.selectNodeContents(containerEl);
    	        preSelectionRange.setEnd(range.startContainer, range.startOffset);
    	        var start = preSelectionRange.toString().length;

    	        readCounter++;     	        
    	        return {
    	            start: start,
    	            end: start + range.toString().length
    	        }
    	    };

    	    restoreSelection = function(containerEl, savedSel) {
    	        var charIndex = 0, range = document.createRange();
    	        range.setStart(containerEl, 0);
    	        range.collapse(true);
    	        var nodeStack = [containerEl], node, foundStart = false, stop = false;
//            	  console.log('Read Called '+readCounter+ " Node Type ="+node.nodeType);
//            	  readCounter++;    	        	
    	        while (!stop && (node = nodeStack.pop())) {
    	            if (node.nodeType == 3) {
    	                var nextCharIndex = charIndex + node.length;
    	                if (!foundStart && savedSel.start >= charIndex && savedSel.start <= nextCharIndex) {
    	                    range.setStart(node, savedSel.start - charIndex);
    	                    foundStart = true;
    	                }
    	                if (foundStart && savedSel.end >= charIndex && savedSel.end <= nextCharIndex) {
    	                    range.setEnd(node, savedSel.end - charIndex);
    	                    stop = true;
    	                }
    	                charIndex = nextCharIndex;
    	            } else {
    	                var i = node.childNodes.length;
    	                while (i--) {
    	                    nodeStack.push(node.childNodes[i]);
    	                }
    	            }
    	        }

    	        var sel = window.getSelection();
    	        sel.removeAllRanges();
    	        sel.addRange(range);
    	    }
    	} else if (document.selection && document.body.createTextRange) {
    	    saveSelection = function(containerEl) {
    	        var selectedTextRange = document.selection.createRange();
    	        var preSelectionTextRange = document.body.createTextRange();
    	        preSelectionTextRange.moveToElementText(containerEl);
    	        preSelectionTextRange.setEndPoint("EndToStart", selectedTextRange);
    	        var start = preSelectionTextRange.text.length;

    	        return {
    	            start: start,
    	            end: start + selectedTextRange.text.length
    	        }
    	    };

    	    restoreSelection = function(containerEl, savedSel) {
    	        var textRange = document.body.createTextRange();
    	        textRange.moveToElementText(containerEl);
    	        textRange.collapse(true);
    	        textRange.moveEnd("character", savedSel.end);
    	        textRange.moveStart("character", savedSel.start);
    	        textRange.select();
    	    };
    	} 
      
    $scope.addHtmlAtCaret = function (html) {
                if (savedSelection) {
                   restoreSelection(document.getElementById('comment0'), savedSelection);
                }          //document.getElementById('comment0').focus();
        var sel, range;
        if (window.getSelection) {
            // IE9 and non-IE
            sel = window.getSelection();
            if (sel.getRangeAt && sel.rangeCount) {
                range = sel.getRangeAt(0);
                range.deleteContents();
    
                // Range.createContextualFragment() would be useful here but is
                // non-standard and not supported in all browsers (IE9, for one)
                var el = document.createElement("div");
                el.innerHTML = html;
                $compile(el)($scope);
                var frag = document.createDocumentFragment(), node, lastNode;
                while ( (node = el.firstChild) ) {
                    lastNode = frag.appendChild(node);
                }
                range.insertNode(frag);
                
                // Preserve the selection
                if (lastNode) {
                    range = range.cloneRange();
                    range.setStartAfter(lastNode);
                    range.collapse(true);
                    sel.removeAllRanges();
                    sel.addRange(range);
                }
            }
        } else if (document.selection && document.selection.type != "Control") {
            // IE < 9
            document.selection.createRange().pasteHTML(html);
        }
    }      
<div contenteditable   ng-model="commentform.comment name="comment0" id="comment0"  placeholder="Write a comment..." ng-keyup="commentKeyInput($event,0)" ng-click="commentBoxClicked($event,0)" ></div> 

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top