How to get a specific selection from contenteditable





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







0















What I'm trying to do is to get a selection only for a word I want from contenteditable inputs. For example,



Hello My World



from the above input value, I want to select only the word 'My' and get the string value of it.



so far, I have written a function that gets a selection upto the caret from 0 range like so:



function selectUptoCaret(el){
var range = window.getSelection().getRangeAt(0);
var preCaretRange = range.cloneRange();
preCaretRange.selectNodeContents(el);
preCaretRange.setEnd(range.endContainer, range.endOffset);

var sel = window.getSelection()
sel.removeAllRanges()
sel.addRange(preCaretRange)
}


When I click 'y' from the word, 'My', it selects 'Hello My'.
but again, I only want to select 'My', not 'Hello My'.










share|improve this question





























    0















    What I'm trying to do is to get a selection only for a word I want from contenteditable inputs. For example,



    Hello My World



    from the above input value, I want to select only the word 'My' and get the string value of it.



    so far, I have written a function that gets a selection upto the caret from 0 range like so:



    function selectUptoCaret(el){
    var range = window.getSelection().getRangeAt(0);
    var preCaretRange = range.cloneRange();
    preCaretRange.selectNodeContents(el);
    preCaretRange.setEnd(range.endContainer, range.endOffset);

    var sel = window.getSelection()
    sel.removeAllRanges()
    sel.addRange(preCaretRange)
    }


    When I click 'y' from the word, 'My', it selects 'Hello My'.
    but again, I only want to select 'My', not 'Hello My'.










    share|improve this question

























      0












      0








      0








      What I'm trying to do is to get a selection only for a word I want from contenteditable inputs. For example,



      Hello My World



      from the above input value, I want to select only the word 'My' and get the string value of it.



      so far, I have written a function that gets a selection upto the caret from 0 range like so:



      function selectUptoCaret(el){
      var range = window.getSelection().getRangeAt(0);
      var preCaretRange = range.cloneRange();
      preCaretRange.selectNodeContents(el);
      preCaretRange.setEnd(range.endContainer, range.endOffset);

      var sel = window.getSelection()
      sel.removeAllRanges()
      sel.addRange(preCaretRange)
      }


      When I click 'y' from the word, 'My', it selects 'Hello My'.
      but again, I only want to select 'My', not 'Hello My'.










      share|improve this question














      What I'm trying to do is to get a selection only for a word I want from contenteditable inputs. For example,



      Hello My World



      from the above input value, I want to select only the word 'My' and get the string value of it.



      so far, I have written a function that gets a selection upto the caret from 0 range like so:



      function selectUptoCaret(el){
      var range = window.getSelection().getRangeAt(0);
      var preCaretRange = range.cloneRange();
      preCaretRange.selectNodeContents(el);
      preCaretRange.setEnd(range.endContainer, range.endOffset);

      var sel = window.getSelection()
      sel.removeAllRanges()
      sel.addRange(preCaretRange)
      }


      When I click 'y' from the word, 'My', it selects 'Hello My'.
      but again, I only want to select 'My', not 'Hello My'.







      javascript range selection contenteditable caret






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Jan 3 at 7:09









      Jay JeongJay Jeong

      175210




      175210
























          1 Answer
          1






          active

          oldest

          votes


















          1














          I think you're mostly there, but the problem you're getting of having everything to the left of the caret highlighted probably has to do with the fact you're not calling preCaretRange.setStart() and so it's thinking the start should be zero. I modified your function a little bit in order to get it to select the actual word your cursor is at:



          function selectUptoCaret(el){
          var range = window.getSelection().getRangeAt(0);
          var preCaretRange = range.cloneRange();

          var startOffset = range.startContainer.textContent.lastIndexOf(' ', range.startOffset);
          var endOffset = range.endContainer.textContent.indexOf(' ', range.endOffset);

          preCaretRange.selectNodeContents(el);
          preCaretRange.setStart(range.startContainer, ~startOffset ? startOffset + 1: 0);
          preCaretRange.setEnd(range.endContainer, ~endOffset ? endOffset : range.endContainer.textContent.length);

          var sel = window.getSelection()
          sel.removeAllRanges()
          sel.addRange(preCaretRange)
          }


          My assumption is that the el param passed into selectUptoCaret is the actual contentEditable HTML element.



          My changes were:




          • take the cursor position and get the position of the next and previous spaces

          • if there is no previous space (determined by the ~startOffset check) we will start at 0 because we are in the first word

          • if there is no following space (determined by the ~endOffset check) we will use the full length of the text content because we are in the last word.

          • set the setStart on our preCaretRange object to make sure we have a finite start point that is not necessarily the beginning of the text content


          Note: my ternary ~startOffset ? startOffset + 1 : 0 is equivalent to saying startOffset > -1 ? startOffset + 1 : 0. Using the ~ bitwise operator is a convenient way of checking that a value is not -1 (since ~ -1 === 0).



          This now will only select the current word at your caret's position.






          share|improve this answer
























            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54017798%2fhow-to-get-a-specific-selection-from-contenteditable%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            1














            I think you're mostly there, but the problem you're getting of having everything to the left of the caret highlighted probably has to do with the fact you're not calling preCaretRange.setStart() and so it's thinking the start should be zero. I modified your function a little bit in order to get it to select the actual word your cursor is at:



            function selectUptoCaret(el){
            var range = window.getSelection().getRangeAt(0);
            var preCaretRange = range.cloneRange();

            var startOffset = range.startContainer.textContent.lastIndexOf(' ', range.startOffset);
            var endOffset = range.endContainer.textContent.indexOf(' ', range.endOffset);

            preCaretRange.selectNodeContents(el);
            preCaretRange.setStart(range.startContainer, ~startOffset ? startOffset + 1: 0);
            preCaretRange.setEnd(range.endContainer, ~endOffset ? endOffset : range.endContainer.textContent.length);

            var sel = window.getSelection()
            sel.removeAllRanges()
            sel.addRange(preCaretRange)
            }


            My assumption is that the el param passed into selectUptoCaret is the actual contentEditable HTML element.



            My changes were:




            • take the cursor position and get the position of the next and previous spaces

            • if there is no previous space (determined by the ~startOffset check) we will start at 0 because we are in the first word

            • if there is no following space (determined by the ~endOffset check) we will use the full length of the text content because we are in the last word.

            • set the setStart on our preCaretRange object to make sure we have a finite start point that is not necessarily the beginning of the text content


            Note: my ternary ~startOffset ? startOffset + 1 : 0 is equivalent to saying startOffset > -1 ? startOffset + 1 : 0. Using the ~ bitwise operator is a convenient way of checking that a value is not -1 (since ~ -1 === 0).



            This now will only select the current word at your caret's position.






            share|improve this answer




























              1














              I think you're mostly there, but the problem you're getting of having everything to the left of the caret highlighted probably has to do with the fact you're not calling preCaretRange.setStart() and so it's thinking the start should be zero. I modified your function a little bit in order to get it to select the actual word your cursor is at:



              function selectUptoCaret(el){
              var range = window.getSelection().getRangeAt(0);
              var preCaretRange = range.cloneRange();

              var startOffset = range.startContainer.textContent.lastIndexOf(' ', range.startOffset);
              var endOffset = range.endContainer.textContent.indexOf(' ', range.endOffset);

              preCaretRange.selectNodeContents(el);
              preCaretRange.setStart(range.startContainer, ~startOffset ? startOffset + 1: 0);
              preCaretRange.setEnd(range.endContainer, ~endOffset ? endOffset : range.endContainer.textContent.length);

              var sel = window.getSelection()
              sel.removeAllRanges()
              sel.addRange(preCaretRange)
              }


              My assumption is that the el param passed into selectUptoCaret is the actual contentEditable HTML element.



              My changes were:




              • take the cursor position and get the position of the next and previous spaces

              • if there is no previous space (determined by the ~startOffset check) we will start at 0 because we are in the first word

              • if there is no following space (determined by the ~endOffset check) we will use the full length of the text content because we are in the last word.

              • set the setStart on our preCaretRange object to make sure we have a finite start point that is not necessarily the beginning of the text content


              Note: my ternary ~startOffset ? startOffset + 1 : 0 is equivalent to saying startOffset > -1 ? startOffset + 1 : 0. Using the ~ bitwise operator is a convenient way of checking that a value is not -1 (since ~ -1 === 0).



              This now will only select the current word at your caret's position.






              share|improve this answer


























                1












                1








                1







                I think you're mostly there, but the problem you're getting of having everything to the left of the caret highlighted probably has to do with the fact you're not calling preCaretRange.setStart() and so it's thinking the start should be zero. I modified your function a little bit in order to get it to select the actual word your cursor is at:



                function selectUptoCaret(el){
                var range = window.getSelection().getRangeAt(0);
                var preCaretRange = range.cloneRange();

                var startOffset = range.startContainer.textContent.lastIndexOf(' ', range.startOffset);
                var endOffset = range.endContainer.textContent.indexOf(' ', range.endOffset);

                preCaretRange.selectNodeContents(el);
                preCaretRange.setStart(range.startContainer, ~startOffset ? startOffset + 1: 0);
                preCaretRange.setEnd(range.endContainer, ~endOffset ? endOffset : range.endContainer.textContent.length);

                var sel = window.getSelection()
                sel.removeAllRanges()
                sel.addRange(preCaretRange)
                }


                My assumption is that the el param passed into selectUptoCaret is the actual contentEditable HTML element.



                My changes were:




                • take the cursor position and get the position of the next and previous spaces

                • if there is no previous space (determined by the ~startOffset check) we will start at 0 because we are in the first word

                • if there is no following space (determined by the ~endOffset check) we will use the full length of the text content because we are in the last word.

                • set the setStart on our preCaretRange object to make sure we have a finite start point that is not necessarily the beginning of the text content


                Note: my ternary ~startOffset ? startOffset + 1 : 0 is equivalent to saying startOffset > -1 ? startOffset + 1 : 0. Using the ~ bitwise operator is a convenient way of checking that a value is not -1 (since ~ -1 === 0).



                This now will only select the current word at your caret's position.






                share|improve this answer













                I think you're mostly there, but the problem you're getting of having everything to the left of the caret highlighted probably has to do with the fact you're not calling preCaretRange.setStart() and so it's thinking the start should be zero. I modified your function a little bit in order to get it to select the actual word your cursor is at:



                function selectUptoCaret(el){
                var range = window.getSelection().getRangeAt(0);
                var preCaretRange = range.cloneRange();

                var startOffset = range.startContainer.textContent.lastIndexOf(' ', range.startOffset);
                var endOffset = range.endContainer.textContent.indexOf(' ', range.endOffset);

                preCaretRange.selectNodeContents(el);
                preCaretRange.setStart(range.startContainer, ~startOffset ? startOffset + 1: 0);
                preCaretRange.setEnd(range.endContainer, ~endOffset ? endOffset : range.endContainer.textContent.length);

                var sel = window.getSelection()
                sel.removeAllRanges()
                sel.addRange(preCaretRange)
                }


                My assumption is that the el param passed into selectUptoCaret is the actual contentEditable HTML element.



                My changes were:




                • take the cursor position and get the position of the next and previous spaces

                • if there is no previous space (determined by the ~startOffset check) we will start at 0 because we are in the first word

                • if there is no following space (determined by the ~endOffset check) we will use the full length of the text content because we are in the last word.

                • set the setStart on our preCaretRange object to make sure we have a finite start point that is not necessarily the beginning of the text content


                Note: my ternary ~startOffset ? startOffset + 1 : 0 is equivalent to saying startOffset > -1 ? startOffset + 1 : 0. Using the ~ bitwise operator is a convenient way of checking that a value is not -1 (since ~ -1 === 0).



                This now will only select the current word at your caret's position.







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Jan 7 at 20:44









                Ryan DablerRyan Dabler

                17117




                17117
































                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54017798%2fhow-to-get-a-specific-selection-from-contenteditable%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Can a sorcerer learn a 5th-level spell early by creating spell slots using the Font of Magic feature?

                    Does disintegrating a polymorphed enemy still kill it after the 2018 errata?

                    A Topological Invariant for $pi_3(U(n))$