views:

1251

answers:

6

I am using jQuery and trying to find a cross browser way to get the pixel coordinates of the caret in text areas and input boxes such that I can place an absolutely positioned div around this location ?

Is there some jQuery plugin? or javascript snippet to do just that ?

+1  A: 

I don't think it can be done in every browser. Someone has done it in IE6, but it does not work in FF or Opera (AFAIK). Maybe you can get it to work in all the browsers.

More information

Marius
+2  A: 

Note: this answer describes how to get the character co-ordinates of the text-cursor/caret. To find the pixel-co-ordinates, you'll need to extend this further.

The first thing to remember is that the cursor can be in three states

  • a regular insertion cursor at a specific position
  • a text selection that has a certain bounded area
  • not active: textarea does not have focus. Has not been used.

The IE model uses the Object document.selection, from this we can get a TextRange object which gives us access to the selection and thus the cursor position(s).

The FF model/Opera uses the handy variables [input].selectionStart and selectionEnd.

Both models represent a regular ative cursor as a zero-width selection, with the left bound being the cursor position.

If the input field does not have focus, you may find that neither is set. I have had good success with the following code to insert a piece of text at the current cursor location, also replacing the current selection, if present. Depending on the exact browser, YMMV.

function insertAtCursor(myField, myValue) {

/* selecion model - ie */
if (document.selection) {
  myField.focus();
  sel = document.selection.createRange();
  sel.text = myValue;
}

/* field.selectionstart/end  firefox */ 
else if (myField.selectionStart || myField.selectionStart == '0' ) {

  var startPos = myField.selectionStart;
  var endPos = myField.selectionEnd;
  myField.value = myField.value.substring(0, startPos)
    + myValue
    + myField.value.substring(endPos, myField.value.length);

  myField.selectionStart = startPos + myValue.length;
  myField.selectionEnd = startPos + myValue.length;
  myField.focus();
} 

// cursor not active/present
else {
  myField.value += myValue;
}

Bug Note: links are not being correctly marked up in the top para.

Selection object: http://msdn.microsoft.com/en-us/library/ms535869(VS.85).aspx
TextRange object: http://msdn.microsoft.com/en-us/library/ms535872(VS.85).aspx

Cheekysoft
A: 

@Cheekysoft

What you are describing is a way to get the selection range information (number of characters since start of string) which is not what I want, I need the coordinates in pixels (so I can positioned a div there) not the length if characters which is what you function returns.

Here is a link to a jQuery plugin that does what you are describing

Pat
A: 

Pat, I think the functionality you are looking for only exists in IE. MSDN. But this is not an official JS thing nor is it implemented in other browsers so I don't recommend using it.

palotasb
+2  A: 

After I read this question I decided to make my first jQuery plugin as the question was interesting, it's still buggy but I plan on having it working fully in a short time.

It should return the absolute distance from the top and left side of the screen

caretPosition

Annan
A: 

@Annan, that's great!

I was working on it when I saw you comment! That's exactly what I was looking for! there are still some cases that don't work but that should be fixable (like multiple spaces in ie not being handles correctly ...) but all in all it's great :-)

Thanks!

Pat