views:

541

answers:

3

I am trying (and failing) to implement a drag&drop mechanism into an HTML textarea.

Drag&Drop mechanism is relatively easy with jQuery or Scriptaculous (we use both), so I am willing to accept an answer that uses either of these two.

Problem is, I cannot seem to find a way to read or set the insertion point.

What I ultimately want to be able to do is determine the drop location, do some kind of mathematical calculation to determine where on the textarea that is exactly, then set the caret position (or insertion point), and place (insert) dropped text there.

I can handle the calculations, I just need to know how the heck to read and set the caret position (which will ultimately be my insertion point for the dropped text). Is this even possible?

Thanks -

A: 

I recommend starting out with reading up on the Range object in JS, see http://www.quirksmode.org/dom/range%5Fintro.html

evaneykelen
A: 

Since you mention you're using jQuery, I would recommend you to give a look to the FieldSelection plugin. That plugin will help you to get information about where the cursor is currently placed.

For setting the cursor position, I use the following functions:

function setSelectionRange(input, selectionStart, selectionEnd) {
  if (input.setSelectionRange) {
    input.focus();
    input.setSelectionRange(selectionStart, selectionEnd);
  }
  else if (input.createTextRange) {
    var range = input.createTextRange();
    range.collapse(true);
    range.moveEnd('character', selectionEnd);
    range.moveStart('character', selectionStart);
    range.select();
  }
}

function setCaretToPos (input, pos) {
  setSelectionRange(input, pos, pos);
}

The you can use the setCaretToPos function like this:

setCaretToPos(document.getElementById("textareaId"), 4);
CMS
A: 

I worked this out by piecing together a few snippets and ideas from around here. Here is how I solved this one:

  1. I placed each section of text I wanted to make draggable into a span with a class of 'draggable_text'

  2. used jquery (in document ready function) to auto-select/deselect the text inside the span each time mouseover/mouseout fired.

.. here is the code:

$(document).ready (

    $('.draggable_text').mouseover(
        function () {
          selectNode(this);
        }
    );

    $('.draggable_text').mouseout(
        function () {
          clearSelection(this);
        }
    );

);

function selectNode (node) {
    var selection, range, doc, win;
    if ( (doc = node.ownerDocument) 
       && (win = doc.defaultView) 
       && typeof win.getSelection != 'undefined' 
       && typeof doc.createRange != 'undefined' 
       && (selection = window.getSelection()) 
       && typeof selection.removeAllRanges != 'undefined'
     ) {
     range = doc.createRange();
     range.selectNode(node);
     selection.removeAllRanges();
     selection.addRange(range);
    } else if ( document.body 
                && typeof document.body.createTextRange != 'undefined' 
                && (range = document.body.createTextRange()) ) {
     range.moveToElementText(node);
     range.select();
    }
}

function clearSelection () {
    if (document.selection) {
     document.selection.empty();
    } else if (window.getSelection) {
     window.getSelection().removeAllRanges();
    }
}

Interestingly, using this methodology, no special drag & drop mechanisms need to be implemented - it seems that the browser automatically assumes when you drag selected text into a text area, that you want to copy it there. Perfect!

I tested this on FF3, IE6, and IE7 (WinXP and Vista). The drag/drop graphic was slightly different on each, but all worked.

OneNerd