skip to Main Content

I am trying to have a field that shows a count of the selected (highlighted) characters. This does not work. Specifically, the line document.getElementById('selectedCountBtn').textContent = "B" + selectedText.length; does not seem to ever get applied.
At first there was a problem with the push of the button deselecting the text, and thus always counting 0. I thought I had eliminated that issue.
I can see that the selectedCharCount variable isn’t ever used for anything. It might be a holdover from a previous implementation of the functionality. I’m not sure, I’m not really good at HTML.

Edit: Is the problem that the updateSelectedCharCount function never gets started?

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Text Field</title>
<style>
  body, html {
    margin: 0;
    height: 100%;
    font-family: Arial, sans-serif;
  }
  #container {
    display: flex;
    height: 100vh; /* Ensure the container fills the entire height of the viewport */
    padding: 10px;
    box-sizing: border-box;
  }
  textarea {
    flex: 1;
    resize: none; /* Disables resizing to ensure it's always 100% height */
    margin-right: 10px;
    box-sizing: border-box;
  }
  #sidebar {
    display: flex;
    flex-direction: column;
    justify-content: space-between; /* Pushes #bottomContainer to the bottom */
    height: calc(100% - 20px); /* Account for padding */
  }
  #bottomContainer {
    <!--position: fixed; /* Fixed positioning relative to the viewport */
    bottom: 10px;    /* Distance from the bottom of the viewport */
    right: 10px;     /* Distance from the right of the viewport */
    display: flex;
    flex-direction: column;
    align-items: flex-end; /* Aligns the children (buttons, input) to the right */-->
  }
  #counters {
    display: flex;
    flex-direction: column;
    align-items: center;
  }
  #charCounter, #wordCounter, .button {
    width: 60px; /* Width adjusted to make all elements similar */
    padding: 5px;
    margin-bottom: 5px; /* Space between elements */
    cursor: pointer;
    text-align: center;
    border: 1px solid #ddd;
    box-shadow: 1px 1px 2px rgba(0,0,0,0.1);
  }
  #filename {
    width: 60px;
    margin-top: 20px; /* Ensures space above the filename input regardless of wordCounter margin */
  }
  .button, #filename {
    margin-bottom: 5px; /* Adds space between input field and buttons */
  }
  #wordCounter {
    margin-bottom: 20px; /* Adds extra space below the wordCounter element and above filename */
  }
}
</style>
<script>
let charCountingEnabled = true;
let wordCountingEnabled = true;
var selectedCharCount = 0; // Variable to keep track of the selected character count

function updateCounters() {
  var textarea = document.getElementById('textArea');
  let text = textarea.value.trim();
  
  if (charCountingEnabled) {
    document.getElementById('charCounter').textContent = text.length;
  }
  
  if (wordCountingEnabled) {
    let words = text.length > 0 ? text.split(/s+/) : [];
    document.getElementById('wordCounter').textContent = words.length;
  }
}

function toggleCharCounter() {
  charCountingEnabled = !charCountingEnabled;
  updateCounters();
}

function toggleWordCounter() {
  wordCountingEnabled = !wordCountingEnabled;
  updateCounters();
}

// Save text to file
function saveToFile() {
  var text = document.getElementById('textArea').value;
  var filename = document.getElementById('filename').value;
  if (!filename) {
    filename = 'snippet';
  }
  filename += '.txt'; // Append .txt to the filename
  var blob = new Blob([text], {type: 'text/plain'});

  // Create an anchor element and trigger a download
  var downloadLink = document.createElement("a");
  downloadLink.href = URL.createObjectURL(blob);
  downloadLink.download = filename;
  document.body.appendChild(downloadLink);
  downloadLink.click();
  document.body.removeChild(downloadLink);
}

function updateSelectedCharCount() {
  var selectedText = '';
  if (window.getSelection) {
    selectedText = window.getSelection().toString();
  } else if (document.selection && document.selection.type != "Control") {
    selectedText = document.selection.createRange().text;
  }
  // Update the button directly here
  document.getElementById('selectedCountBtn').textContent = "B" + selectedText.length;
}

document.addEventListener('selectionchange', function() {
  console.log("Selection changed.");
  var selectedText = '';
  if (window.getSelection) {
    selectedText = window.getSelection().toString();
  }
  var selectedCountBtn = document.getElementById('selectedCountBtn');
  selectedCountBtn.textContent = "A" + selectedText.length;
});

</script>
</head>
<body>
<div id="container">
  <textarea id="textArea" oninput="updateCounters();"></textarea>
  <div id="sidebar">
    <div id="counters">
      <div id="charCounter" onclick="toggleCharCounter()">0</div>
      <div id="wordCounter" onclick="toggleWordCounter()">0</div>
      <div class="button" id="selectedCountBtn">Selected</div>
    </div>
    <div id="bottomContainer">
      <input type="text" id="filename" class="button" placeholder="" />
      <div class="button" onclick="saveToFile()">Save</div>
    </div>
  </div>
</div>
</body>
</html>

Humble thanks to all ideas and suggestions, even if minor.

2

Answers


  1. I don’t see that the function updateSelectedCharCount() is ever called from anywhere else.

    I found this first – How can I get the selected text in a textarea? because I’m in Firefox and your current code did change the text to "A7" if I selected text outside the text area.

    Try with this:

    function updateSelectedCharCount() {
      selectedText = getSel();
      // Update the button directly here
      document.getElementById('selectedCountBtn').textContent = "B" + selectedText.length;
    }
    
    document.addEventListener('selectionchange', function() {
      console.log("Selection changed.");
      var selectedText = getSel();
      var selectedCountBtn = document.getElementById('selectedCountBtn');
      selectedCountBtn.textContent = "A" + selectedText.length;
      updateSelectedCharCount();
    });
    
    function getSel() {
        // Obtain the object reference for the <textarea>
        var txtarea = document.getElementById("textArea");
        // Obtain the index of the first selected character
        var start = txtarea.selectionStart;
        // Obtain the index of the last selected character
        var finish = txtarea.selectionEnd;
        // Obtain the selected text
        var sel = txtarea.value.substring(start, finish);
        return sel;
    }
    

    Do you need a second new button? The addEventListener is already set to update that button to "A" + length. I’ve added the call to updateSelectedCharCount() after that which will update that same button to "B" + length – so you might not need both?

    Login or Signup to reply.
  2. Simply please write code like-:

    const merpButton = document.getElementById('merp');
    
    merpButton.addEventListener('click', function() {
        alert('Hey')
    });
     <button id="merp">Merp</button>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search