在angularjs中光标位置的contenteditable div中插入div或custom-directive

时间:2014-04-24 13:33:28

标签: javascript jquery html angularjs contenteditable

我必须在我的contenteditable div中插入自定义指令。

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

我试过了:

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

请帮帮我。小提琴: - http://jsfiddle.net/k2SUJ/1/

这是我试过的fiddle demo

2 个答案:

答案 0 :(得分:1)

为了让Angular了解您添加的元素并发挥其魔力,您需要 $compile 元素并将其链接到范围。

所以你需要一个带范围的控制器。您还需要将onclick处理程序替换为 ng-click 以及 $compile 元素:

在HTML中:

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

在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);
        ...
    };
});

另请参阅此 short demo

答案 1 :(得分:-1)

在执行粘贴之前最好保存光标并恢复它。在按钮的情况下,只有上面的工作。但是如果您在按钮上使用Popover或Dialog,并且在关闭对话框后,Content Editable Div Focus将首先在AngularJS App中使用。所以在做之前,请也这样做。 考虑这是您的内容可编辑Div,如下所示。 在ng-click和ng-keyup上我只保存可编辑DIV的当前Cursor,当用户打开一个对话框,或弹出或执行任何操作并调用addHtmlAtCaret(html)函数时,只需将光标重新调到最后一个输入位置,按照上面用户gkalpak的说明进行操作。

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>