javascript – Multiple and Separate Text Selection Highlights within textarea Oracle Apex-ThrowExceptions

Exception or error:

The requirement is for the user to be able to highlight separate parts of text.

For example if the textarea contained “01234567” the user should be able to highlight “1357” without highlighting “0246”.

selectionStart and selectionEnd are returning greater, random and inaccurate indexes of not more than 3 numbers off from the targeted index.

If selectionStart and selectionEnd worked as expected the code below should work.

$("#P85_30DAY").attr("contenteditable","true");
$("#P85_30DAY").css("postition","absolute");
var selStartArray = [];
var selStartArrayMin = [];
var selEndArray = [];
var selEndArrayMax = [];
function ModifySelection () {            
            var textarea = document.getElementById("P85_30DAY");
            if ('selectionStart' in textarea) {                    
                if (textarea.selectionStart != textarea.selectionEnd) { 
                      var selTextStart = textarea.selectionStart;
                      var selTextEnd = textarea.selectionEnd;
                      var P8530DAY = $("#P85_30DAY").val();
                      var len =  P8530DAY.length;
                      var nextSelStartArray = "-1";
                      selStartArray.push(selTextStart);
                      selStartArrayMin.push(selTextStart);
                      selEndArray.push(selTextEnd);
                      selEndArrayMax.push(selTextEnd);
                      selStartArrayMin.sort(function(a, b){return a-b});
                      selEndArrayMax.sort(function(a, b){return b-a});

text = "<span>" + textarea.value.substring (0, selStartArrayMin[0]);  
for (i = 0; i <= len; i++) {                                          
var indexVal = selStartArray.indexOf(i);                              
if (indexVal != -1){                                                  
text += "<span style='color:white;background-color:blue'>" + textarea.value.substring  (selStartArray[indexVal], selEndArray[indexVal]) + "</span>" ;  
for (k = i+1; k < len; k++) {                                         
var indexValB = selStartArray.indexOf(k);                             
if (indexValB != -1){                                                
var nextSelStartArray = textarea.value.substring (selEndArray[indexValB - 1], selStartArray[indexValB]);
}}
if (nextSelStartArray != -1){                                        
text += nextSelStartArray;                                           
nextSelStartArray = "-1";
k = len;                                             
}}}
text += textarea.value.substring (selEndArrayMax[0]) + "</span>";      

                 $("#P85_30DAY").empty();                   
                 $(text).appendTo("#P85_30DAY");                     
                 $("#P85_60DAY").val("Length: " + "\n" + len + "\n" + "SelStart Array: " + "\n" + selStartArray + "\n" + "SelEnd Array: " + "\n" + selEndArray);                
                }
            }                       
        }
//document.getElementById("P85_30DAY").onkeyup = ModifySelection;
document.getElementById("P85_30DAY").onmouseup = ModifySelection;
<!-- language: lang-html -->

    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <textarea name="p_t07" class="textarea" id="P85_30DAY" style="width: 587px; height: 600px; font-size: 130%; position: relative;" contenteditable="true" maxlength="4000" rows="1" cols="80" wrap="virtual"></textarea>

<!-- end snippet -->


<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

    $("#P85_30DAY").attr("contenteditable","true");
$("#P85_30DAY").css("postition","absolute");
var selStartArray = [];
var selStartArrayMin = [];
var selEndArray = [];
var selEndArrayMax = [];
function ModifySelection () {            
            var textarea = document.getElementById("P85_30DAY");
            if ('selectionStart' in textarea) {                    
                if (textarea.selectionStart != textarea.selectionEnd) { 
                      var selTextStart = textarea.selectionStart;
                      var selTextEnd = textarea.selectionEnd;
                      var P8530DAY = $("#P85_30DAY").val();
                      var len =  P8530DAY.length;
                      var nextSelStartArray = "-1";
                      selStartArray.push(selTextStart);
                      selStartArrayMin.push(selTextStart);
                      selEndArray.push(selTextEnd);
                      selEndArrayMax.push(selTextEnd);
                      selStartArrayMin.sort(function(a, b){return a-b});
                      selEndArrayMax.sort(function(a, b){return b-a});

text = "<span>" + textarea.value.substring (0, selStartArrayMin[0]);  
for (i = 0; i <= len; i++) {                                          
var indexVal = selStartArray.indexOf(i);                              
if (indexVal != -1){                                                  
text += "<span style='color:white;background-color:blue'>" + textarea.value.substring  (selStartArray[indexVal], selEndArray[indexVal]) + "</span>" ;  
for (k = i+1; k < len; k++) {                                         
var indexValB = selStartArray.indexOf(k);                             
if (indexValB != -1){                                                
var nextSelStartArray = textarea.value.substring (selEndArray[indexValB - 1], selStartArray[indexValB]);
}}
if (nextSelStartArray != -1){                                        
text += nextSelStartArray;                                           
nextSelStartArray = "-1";
k = len;                                             
}}}
text += textarea.value.substring (selEndArrayMax[0]) + "</span>";      

                 $("#P85_30DAY").empty();                   
                 $(text).appendTo("#P85_30DAY");                     
                 $("#P85_60DAY").val("Length: " + "\n" + len + "\n" + "SelStart Array: " + "\n" + selStartArray + "\n" + "SelEnd Array: " + "\n" + selEndArray);                
                }
            }                       
        }
//document.getElementById("P85_30DAY").onkeyup = ModifySelection;
document.getElementById("P85_30DAY").onmouseup = ModifySelection;    

This is the textarea that I am working with.

    <textarea name="p_t07" class="textarea" id="P85_30DAY" 
    style="width:587px;
    height: 600px; font-size: 130%; position: relative;" 
    contenteditable="true"
    maxlength="4000" rows="1" cols="80" wrap="virtual"></textarea>

When I replace the arrays with the correct selectionStart and selectionEnd values, as below, the code works as expected. I believe the incorrect indexes returned are because of the spans being added. is there an alternative for selectionStart and selectionEnd or a way to target the visible text and not the html?

$("#P85_30DAY").attr("contenteditable","true");
$("#P85_30DAY").css("postition","absolute");
var selStartArray = [1,3,5,7];
var selStartArrayMin = [1,3,5,7];
var selEndArray = [2,4,6,8];
var selEndArrayMax = [2,4,6,8];
function ModifySelection () {            
            var textarea = document.getElementById("P85_30DAY");
            if ('selectionStart' in textarea) {                    
                      var textTest = "01234567";
                      var selTextStart = textarea.selectionStart;
                      var selTextEnd = textarea.selectionEnd;
                      var len =  textTest.length;
                      var nextSelStartArray = "-1";
                      //selStartArray.push(selTextStart);
                      //selStartArrayMin.push(selTextStart);
                      //selEndArray.push(selTextEnd);
                      //selEndArrayMax.push(selTextEnd);
                      selStartArrayMin.sort(function(a, b){return a-b});
                      selEndArrayMax.sort(function(a, b){return b-a});

text = "<span>" + textTest.substring (0, selStartArrayMin[0]);  
for (i = 0; i <= len; i++) {                                          
var indexVal = selStartArray.indexOf(i);                              
if (indexVal != -1){                                                  
text += "<span style='color:white;background-color:blue'>" + textTest.substring  (selStartArray[indexVal], selEndArray[indexVal]) + "</span>" ;  
for (k = i+1; k < len; k++) {                                         
var indexValB = selStartArray.indexOf(k);                             
if (indexValB != -1){                                                
var nextSelStartArray = textTest.substring (selEndArray[indexValB - 1], selStartArray[indexValB]);
}
if (nextSelStartArray != -1){                                        
text += nextSelStartArray;                                           
nextSelStartArray = "-1";
k = len;                                            
}}}}
text += textTest.substring (selEndArrayMax[0]) + "</span>";      

                 $("#P85_30DAY").empty();                   
                 $(text).appendTo("#P85_30DAY");                     
                 $("#P85_60DAY").val("Length: " + "\n" + len + "\n" + "SelStart Array: " + "\n" + selStartArray + "\n" + "SelEnd Array: " + "\n" + selEndArray);                
                }                     
        };
//document.getElementById("P85_30DAY").onkeyup = ModifySelection;
document.getElementById("P85_30DAY").onmouseup = ModifySelection;

This is what the textarea looks like with the correct selectionStart and selectionEnd values.

    <textarea name="p_t07" class="textarea" id="P85_30DAY" style="width: 587px; 
 height: 600px; font-size: 130%; margin-top: -431px; margin-left: -1340px;
 position: relative;" contenteditable="true" maxlength="4000" rows="1" cols="80" 
 wrap="virtual"><span>0<span style="color: white; background-color: 
 blue;">1</span>2<span style="color: white; background-color: 
 blue;">3</span>4<span style="color: white; background-color: 
 blue;">5</span>6<span style="color: white; background-color: blue;">7</span>
 </span></textarea>
How to solve:

Leave a Reply

Your email address will not be published. Required fields are marked *