Okay, I find half of the solution. I still need help with the other
half.

To get the caret position within an editable content div, we need to
the following:

1) Turn all nodes into HTML elements. Meaning, nothing can be a
regular text node. Basically, we need to wrap everything in a <span>
tag that doesn't do anything. This makes sure that all children are
ordered and accounted for.

2) Get the current selection and range object. If none exists, just
stop running the function ;)

3) Create a variable to track the caret position. Set it to 0.

4) Next, loop through all the children of the editable content div.
For each child, we check to see if that child is the same as the
startContainer of the selection's range.

    -> If it isn't, we add the length of the text of the <span> to the
caretPosition counter. We keep iterating.
    -> If it is, we take the range's offset and add it to the
caretPosition counter. We are done.

Since the children come in the order they are in the div container,
this works. It is a bit verbose, but it works. There are a few outlier
cases at the beginning and end of the container, but I'll worry about
those later.

To set the caret position, we basically do the reverse.

1) Make a new variable called "charactersLeft" and set it to the
desired caret position.

2) Loop through all the children of the editable content div. For each
child

    -> if the length of the span element is <= charactersLeft, we
subtract that number from charactersLeft and keep looping.
    -> otherwise, we found the text node that caret is supposed to be
in. We are done with the loop. We return the childNode and
charactersLeft.

3) We create a new range and set it's startContainer and endContainer
to the childNode and we set its text offset to "charactersLeft".

This is pretty simple solution. In theory it should work. However, the
range object in Mozilla isn't doing what I'm telling it what to do.

if( document.createRange ) {
    range = document.createRange();
    range.setStart( domElement, offset );
    range.setEnd( domElement, offset );
    range.select();
}

Basically, any offset I send to this, Firefox gets it entirely wrong.
It either resets the cursor to the beginning of the div container, or
to the beginning/end of some other node entirely. ARGH!

This is kind of crappy because I really thought I had a solution. It
is logical and I know "my part" works, just the browser part of it
doesn't work.

Help? :/

On Apr 7, 1:38 pm, egervari <[email protected]> wrote:
> Yes, I am using jQuery.
>
> I found that it's pretty trivial to set the position for a single text
> node.
>
> The problem I run into is when there are multiple elements within the
> div. For example:
>
> <div editableContent="true>
>     Here is <span class="GrammarError" message="Repeated Word">some
> some</span> text.
> </div>
>
> It is easy to set the position to "4" in this case, because the first
> text node will report the offset as "4".
>
> The problem is if the user has the cursor within "some some". If they
> had it between the "so" and "me", it would report an offset of 1 (or
> 2) - not 10 (or 11) like you would expect.
>
> Basically, the cursor position resets to 0 for every kind of node
> inside of the div.
>
> I will try out that jquery code just to make sure. Maybe it'll work.
> It's looks too simple though as I have built my own abstractions on
> the around selection/range to take care of cross browser and find
> myself trying the same kind of thing as suggested on that page :(
>
> On Apr 7, 1:09 pm, Steel City Phantom <[email protected]> wrote:
>
> > are you using jquery?  if so,
>
> >http://stackoverflow.com/questions/499126/jquery-set-cursor-position-...
>
> > <http://stackoverflow.com/questions/499126/jquery-set-cursor-position-...>i
> > have to put some more thought on which event you would have to use to
> > trigger it.
>
> > in worst case, pull down the jquery code and find the method and see how
> > they do it.  i switched to jquery a long time ago, makes everything much
> > easier and you have a fairly reasonable guarantee that it will work cross
> > browser.
>
> > On Wed, Apr 7, 2010 at 9:49 AM, egervari <[email protected]> wrote:
> > > I'm a long time listener. I'm actually the guy that sent him that
> > > scala question with the name "Huge G. Rection" if you remember that ;)
> > > That crazy guy from Canada!
>
> > > Anyway... I'm having a problem with JavaScript and I thought since
> > > this community is way smarter than average communities, I might be
> > > able to find an answer here.
>
> > > If I'm using editable content divs... is there a way to easily get/set
> > > the cursor? Gmail makes this look easy, but it's actually not an easy
> > > problem.
>
> > > My div contains text and other html elements - notably several
> > > <span>'s. These span's indicate grammar errors and the like. So when
> > > the person types text into the editor, we have to drop some text nodes
> > > from the div and replace them with the spans. These spans add those
> > > nice red squiggles and also provide tooltips indicating how to fix the
> > > grammar error.
>
> > > Every time I change the contents of the editable div, firefox will
> > > reset the cursor to the beginning of the content box (annoying!) and
> > > IE will reset it to the end (not as bad, but still a problem if they
> > > edit text in the middle).
>
> > > Now, I know there's selection objects and range objects. The problem
> > > with these is that if the anchor/start nodes they were pointing to are
> > > deleted, the browser auto-magically points them to other elements of
> > > the DOM. In Firefox, it's the parent div container. In IE, it's
> > > something else.
>
> > > Is there another way I can save/restore selection (i.e. cursor) state?
> > > Or do I have to wrap every word and space character with a <span> tag
> > > just to avoid deletions?
>
> > > I've spent about 6 hours on this problem, which is actually more than
> > > it took to build the entire ajax grammar checker. I'm a little
> > > frustrated and looking for help.
>
> > > I realize this is a JavaScript question, but it's for a Java
> > > application :)
>
> > > Thanks!
>
> > > --
> > > You received this message because you are subscribed to the Google Groups
> > > "The Java Posse" group.
> > > To post to this group, send email to [email protected].
> > > To unsubscribe from this group, send email to
> > > [email protected]<javaposse%[email protected]>
> > > .
> > > For more options, visit this group at
> > >http://groups.google.com/group/javaposse?hl=en.
>
> > --
> > You want it fast, cheap, or right.  Pick two!!

-- 
You received this message because you are subscribed to the Google Groups "The 
Java Posse" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/javaposse?hl=en.

Reply via email to