0

I have a piece of code that sets the document to designMode and then operates on pieces of selected text using the document.execCommand() function.

It provides various functionality - for example it allows the user to turn a selected line of text to bold or italic (essentially the functionality of a text editor like this one that I am typing into now).

Here is a simplified example of the code:

<!DOCTYPE html>
<html>
<head>
      <meta charset="utf-8">
</head>
<body>
    <div>
          This is some text - highlight a section of it and press h1 then li
    </div>
    <button onclick="setToHeader()" id="h1" style="width:100px" unselectable="on">h1</button>
    <button onclick="setToList()" id="li" style="width:100px" unselectable="on">li</button>

    <script>
          document.designMode = 'on';
            function setToHeader() {
                  document.execCommand('formatBlock', false, 'h1');
            }
            function setToList() {
                    document.execCommand('insertUnorderedList', false, null);
            }
    </script>
</body>
</html>

My problem here is that I do not want to be able to use the li button - i.e. convert the selected text to list format, when it is already converted into heading format with the h1 button.

I think I want to be able to read the selected text and simply check it with something like:

// var selectedText = ???
var isHeading = selectedText.search('h1') > -1 

Is this the way, or is there a better approach?

How can I get hold of the relevant selected text and assign it to a variable?

Sam Redway
  • 7,605
  • 2
  • 27
  • 41

2 Answers2

1

You can get hold of the selected text using the selection object.

e.g. in IE11:

getSelection()

Full documentation can be found here:

 https://msdn.microsoft.com/en-us/library/ms535869(v=vs.85).aspx
Sam Redway
  • 7,605
  • 2
  • 27
  • 41
0

You need a little bit more effort. Need to use jquery also, check it out:

<!DOCTYPE html>
<html>
<head>
      <meta charset="utf-8">
</head>
<body>
    <div>This is some text - highlight a section of it and press h1 then li </div>
    <div>This is some other text - highlight a section of it and press h1 then li </div>
    <button onclick="setToHeader()" id="h1" style="width:100px" unselectable="on">h1</button>
    <button onclick="setToList()" id="li" style="width:100px" unselectable="on">li</button>
   <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
    <script>

          document.designMode = 'on';


          setInterval(function () {
                 var el = getSelectionContainerElement();
                    if($(el).is('h1')){  
                        $("#li").attr("disabled", true);
                    }
                    else
                    {
                        $("#li").attr("disabled", false);
                    }
                  }, 100);


            function setToHeader() {                    
                document.execCommand('formatBlock', false, 'h1');                 

            }
            function setToList() {                              
                document.execCommand('insertUnorderedList', false, null);           

            }

            function getSelectionContainerElement() {
                    var range, sel, container;
                    if (document.selection && document.selection.createRange) {
                        // IE case
                        range = document.selection.createRange();
                        return range.parentElement();
                    } else if (window.getSelection) {
                        sel = window.getSelection();
                        if (sel.getRangeAt) {
                            if (sel.rangeCount > 0) {
                                range = sel.getRangeAt(0);
                            }
                        } else {
                            // Old WebKit selection object has no getRangeAt, so
                            // create a range from other selection properties
                            range = document.createRange();
                            range.setStart(sel.anchorNode, sel.anchorOffset);
                            range.setEnd(sel.focusNode, sel.focusOffset);

                            // Handle the case when the selection was selected backwards (from the end to the start in the document)
                            if (range.collapsed !== sel.isCollapsed) {
                                range.setStart(sel.focusNode, sel.focusOffset);
                                range.setEnd(sel.anchorNode, sel.anchorOffset);
                            }
                        }

                        if (range) {
                           container = range.commonAncestorContainer;

                           // Check if the container is a text node and return its parent if so
                           return container.nodeType === 3 ? container.parentNode : container;
                        }   
                    }
            }
    </script>
</body>
</html>
alessalessio
  • 1,224
  • 1
  • 15
  • 28
  • Unfortunately this does not work. My first thought was something similar but in the actual code the user is editting a text field - a WYSIWIG editor. This means they can togle a line to h1 then press return and the next line is a

    . I don't want the button disabled on this next line. As such I need to check the actual line that the cursor is on, or the text selected to decide whether to enable or disable the button for that given piece of selected text.

    – Sam Redway Mar 30 '16 at 11:59
  • well, you can get the selected text by using this function: function getSelectionText() { var text = ""; if (window.getSelection) { text = window.getSelection().toString(); } else if (document.selection && document.selection.type != "Control") { text = document.selection.createRange().text; } return text; }. However, i believe that it is not the text that you need, but if it is wrapped inside an

    tag. Am i right?

    – alessalessio Mar 30 '16 at 12:24