Skip to content Skip to sidebar Skip to footer

How To Edit A Link Within A ContentEditable Div

Does anyone have any suggestions on how to edit an link in a contentEditable div? It would be ideal once the link is either clicked with mouse, or the cursor hits the link, that t

Solution 1:

I'm pretty sure this is what you were looking for, however I used jQuery just to make the concept a little easier to mock. jsbin preview available, so go look at it. If anyone is able to convert this to pure JS for the sake of the answer, I have made it a community wiki.

It works by binding to the keyup/click events on the editable div, then checking for the node that the users caret is being placed at using window.getSelection() for the Standards, or document.selection for those IE people. The rest of the code handles popping/handling the edits.

jQuery methods:

function getSelectionStartNode(){
  var node,selection;
  if (window.getSelection) { // FF3.6, Safari4, Chrome5 (DOM Standards)
    selection = getSelection();
    node = selection.anchorNode;
  }
  if (!node && document.selection) { // IE
    selection = document.selection
    var range = selection.getRangeAt ? selection.getRangeAt(0) : selection.createRange();
    node = range.commonAncestorContainer ? range.commonAncestorContainer :
           range.parentElement ? range.parentElement() : range.item(0);
  }
  if (node) {
    return (node.nodeName == "#text" ? node.parentNode : node);
  }
}

$(function() {
    $("#editLink").hide();
    $("#myEditable").bind('keyup click', function(e) {
        var $node = $(getSelectionStartNode());
        if ($node.is('a')) {
          $("#editLink").css({
            top: $node.offset().top - $('#editLink').height() - 5,
            left: $node.offset().left
          }).show().data('node', $node);
          $("#linktext").val($node.text());
          $("#linkhref").val($node.attr('href'));
          $("#linkpreview").attr('href', $node.attr('href'));
        } else {
          $("#editLink").hide();
        }
    });
    $("#linktext").bind('keyup change', function() {
      var $node = $("#editLink").data('node');
      $node.text($(this).val());
    });
    $("#linkhref").bind('keyup change', function() {
      var $node = $("#editLink").data('node');
      $node.attr('href', $(this).val());
      $node.and('#linkpreview').attr('href',$(this).val());
    });
});

Solution 2:

I tested it only on chrome

button style

button.cmd {
 ...
}

toolbar button

<button type="button" id="linkEditor" class="cmd">link</button>

modal dialog -> link editor

<div id="optionDialog" class="modal">
    <div class="modal-content">
        <div id="linkOption">
            <p>
                <label>Indirizzo link</label><br />
                <input type="text" id="linkUrl" value="" placeholder="http://www..." />
            </p>
            <p>
                <label>Testo link</label><br />
                <input type="text" id="linkData" value="" placeholder="link label" />
            </p>
            <p>
                <button type="button" id="linkDone">apply</button>
                <button type="button" id="cancel">cancel</button>
            </p>
        </div>
    </div>
</div>

javascript, jquery

var cur_range;
var cur_dialog;

$(document).ready(function() {
    $('.editor').focus();

    //on toolbar button mousedown keep current range
    $('.cmd').mousedown(function(event) {
        event.preventDefault();
        try {
            cur_range = document.getSelection().getRangeAt(0);
        }
        catch(error) {
            console.log(error);
        }
    });

    $('#linkEditor').click(function() {
        event.preventDefault();

        //if user select edit link, else insert link
        if (!cur_range.collapsed) {
            //if selection is a link set edit values
            if (cur_range.commonAncestorContainer.parentNode.nodeName.toLowerCase() == 'a') {
                $('#linkUrl').val(cur_range.commonAncestorContainer.parentNode.href);
                $('#linkData').val(cur_range.commonAncestorContainer.data);
            }
            else {
                //alert here
                return false;
            }
        }
        else {
            $('#linkUrl').val('');
            $('#linkData').val('');
        }
        //open link editor dialog
        $('#optionDialog').show();
        $('#linkOption').show();

        //store current dialog section (link, table, header)
        cur_dialog = $('#linkOption');
    });

    $('#linkDone').click(function() {
        event.preventDefault();
        if (cur_range.collapsed) {
            //insert link at caret position
            var node = '<a href="' + $('#linkUrl').val() + '" target="_blank">' + $('#linkData').val() + '</a>';
            cur_range.insertNode(cur_range.createContextualFragment(node));
        }
        else {
            //replace existing link values
            cur_node = cur_range.commonAncestorContainer.parentNode;
            cur_node.href = $('#linkUrl').val();
            cur_node.innerText = $('#linkData').val();
        }
        //update range
        document.getSelection().removeAllRanges();
        document.getSelection().addRange(cur_range);
        document.getSelection().collapseToEnd();
        $('.modal-close').click();

        //if you don't use observer some code is nedeed
        //save_history(1);
    });

    //When the user clicks anywhere outside of the modal, close it
    window.onclick = function(event) {
        optionDialog = document.getElementById('optionDialog');
        if (event.target == optionDialog) {
            $('#optionDialog').hide();
            cur_dialog.hide();
            cur_dialog = null;
        }
    }
});

Post a Comment for "How To Edit A Link Within A ContentEditable Div"