Categories

HTML Table Coloring Tool using javascript

 In this post we will create a tool for coloring cells of a table. 

<div id="menuitems">
        <h2 >Coloring Table<span id="timer"></span></h2> 
        <button id="colorTable" class="btn btn-outline-dark btn-sm" data-bs-toggle="button" autocomplete="off" onclick="setColorPicker()">
          <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-paint-bucket" viewBox="0 0 16 16">
            <path d="M6.192 2.78c-.458-.677-.927-1.248-1.35-1.643a2.972 2.972 0 0 0-.71-.515c-.217-.104-.56-.205-.882-.02-.367.213-.427.63-.43.896-.003.304.064.664.173 1.044.196.687.556 1.528 1.035 2.402L.752 8.22c-.277.277-.269.656-.218.918.055.283.187.593.36.903.348.627.92 1.361 1.626 2.068.707.707 1.441 1.278 2.068 1.626.31.173.62.305.903.36.262.05.64.059.918-.218l5.615-5.615c.118.257.092.512.05.939-.03.292-.068.665-.073 1.176v.123h.003a1 1 0 0 0 1.993 0H14v-.057a1.01 1.01 0 0 0-.004-.117c-.055-1.25-.7-2.738-1.86-3.494a4.322 4.322 0 0 0-.211-.434c-.349-.626-.92-1.36-1.627-2.067-.707-.707-1.441-1.279-2.068-1.627-.31-.172-.62-.304-.903-.36-.262-.05-.64-.058-.918.219l-.217.216zM4.16 1.867c.381.356.844.922 1.311 1.632l-.704.705c-.382-.727-.66-1.402-.813-1.938a3.283 3.283 0 0 1-.131-.673c.091.061.204.15.337.274zm.394 3.965c.54.852 1.107 1.567 1.607 2.033a.5.5 0 1 0 .682-.732c-.453-.422-1.017-1.136-1.564-2.027l1.088-1.088c.054.12.115.243.183.365.349.627.92 1.361 1.627 2.068.706.707 1.44 1.278 2.068 1.626.122.068.244.13.365.183l-4.861 4.862a.571.571 0 0 1-.068-.01c-.137-.027-.342-.104-.608-.252-.524-.292-1.186-.8-1.846-1.46-.66-.66-1.168-1.32-1.46-1.846-.147-.265-.225-.47-.251-.607a.573.573 0 0 1-.01-.068l3.048-3.047zm2.87-1.935a2.44 2.44 0 0 1-.241-.561c.135.033.324.11.562.241.524.292 1.186.8 1.846 1.46.45.45.83.901 1.118 1.31a3.497 3.497 0 0 0-1.066.091 11.27 11.27 0 0 1-.76-.694c-.66-.66-1.167-1.322-1.458-1.847z"/>
          </svg>&nbsp;Color
        </button>
        
        <div class="colorPicker" style="display:none;" id="colorPickerdiv">
          <label for="colorWell">Select Color:</label>
          <input type="color" value="#ffffff" id="colorPicker" />
        </div>    
      
       
      </div>

With above code we created a button and when that button is clicked a color pallet will open where users can select the color.

After user selects the color. He can color the table cells clicking and dragging over cells .

<div id="tableWrapper"></div>

Our table will reside in tableWrapper div.

Now we are going to write code to create a table 

(function () {

        // Generate Table 
        let row =13;
        let column = 8;
        const tbl = document.createElement("table");
        const tblBody = document.createElement("tbody");

        // creating all cells
        for (let i = 0; i < row; i++) {
          // creates a table row
          const row = document.createElement("tr");
          for (let j = 0; j < column; j++) {
            const cell = document.createElement("td");
            cell.setAttribute('contenteditable','true');
            cell.setAttribute('id',`${i}${j}`);
           
            const cellText = document.createTextNode(`${i}, ${j}`);
            cell.appendChild(cellText);
            row.appendChild(cell);
          }
          tblBody.appendChild(row);
        }
    
        tbl.appendChild(tblBody);  
        document.body.appendChild(tbl);
        tbl.setAttribute("border", "1");
        
      })();

Above code runs in a selft invoking function so when window loads a html table will be automatically created inside tableWrapper div.

Now lets write code for actual coloring functionality.

      let isMouseDown = false;
      let idObj = {};
      let selectedColor ='';

      function setCellColorMouseDown(event){
            isMouseDown= true;
            event.preventDefault();
            console.log('mousedown');
            idObj[event.target.id]= [];
            event.target.style=`background-color: ${selectedColor};`;
      }

      function setCellColorMouseUp(event){
            isMouseDown = false;
            event.preventDefault();
            console.log('mouseup');
            idObj[event.target.id]= [];
            event.target.style=`background-color: ${selectedColor};`;

      }

      function setCellColorMouseOver(event){
        event.preventDefault();
        if(isMouseDown){
            console.log(event.target.id);
            idObj[event.target.id]= [];
            event.target.style=`background-color: ${selectedColor};`;
          }
      }


      function setColorPicker(){

          let displayType =  document.getElementById('colorPickerdiv').style.display;

          if(displayType =='inline'){
            document.getElementById('colorPickerdiv').style.display='none';
            let elm = document.getElementsByTagName('td');
            for (let i = 0; i < elm.length; i++) {             
              elm[i].removeEventListener('mousedown', setCellColorMouseDown);
              elm[i].removeEventListener('mouseup',setCellColorMouseUp );
              elm[i].removeEventListener('mouseover',setCellColorMouseOver);
              elm[i].setAttribute('contenteditable','true');
            }
            document.body.style.cursor = "auto"; 
          }else{

            document.getElementById('colorPickerdiv').style.display='inline';
            let colorPicker = document.getElementById('colorPicker');
            colorPicker.addEventListener('change', function(e) {
              selectedColor = colorPicker.value;
            }, false);

            let elm = document.getElementsByTagName('td');
            for (let i = 0; i < elm.length; i++) {             
              elm[i].addEventListener('mousedown', setCellColorMouseDown);
              elm[i].addEventListener('mouseup',setCellColorMouseUp );
              elm[i].addEventListener('mouseover',setCellColorMouseOver);
              elm[i].setAttribute('contenteditable','false');
            }
            document.body.style.cursor = "cell"; 
           
          }
            
      }

Above code will add functionality to our color button and user will be able to color table now. Now let me give you full source code

<!doctype html>
<html lang="en">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- Bootstrap CSS -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
    <title>Table</title>

    <style>

      table {
        border: 1px solid #ccc;
        border-collapse: collapse;
        margin: 14px;
        padding: 0;
        width: 98%;
        table-layout: fixed;
      }
      
      th, td {
          border: 0.5px solid black;
          border-collapse: collapse;
          text-align: left;
          padding: 8px;
      }

      td:hover{
        background: #a7ffe0; 
      }

      .menuitems{
        display: inline;
      }

      .colorPicker{
        display: inline-block;
        padding: 0.25rem 0.5rem;
        font-size: .875rem;
        border-radius: 0.2rem;
        color: #212529;
        border-color: #212529;
        border:1px solid transparent;
      }

      .bold-span {font-weight: bold;}
      .italics-span { font-style: italic;}
      .underline-span {text-decoration: underline;}
      .strikethrough-span {text-decoration: line-through;}

      

      </style>
  </head>
  <body>
    <div class="container-fluid">
      <div id="menuitems">
        <h2 >Coloring Table<span id="timer"></span></h2> 
        <button id="colorTable" class="btn btn-outline-dark btn-sm" data-bs-toggle="button" autocomplete="off" onclick="setColorPicker()">
          <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-paint-bucket" viewBox="0 0 16 16">
            <path d="M6.192 2.78c-.458-.677-.927-1.248-1.35-1.643a2.972 2.972 0 0 0-.71-.515c-.217-.104-.56-.205-.882-.02-.367.213-.427.63-.43.896-.003.304.064.664.173 1.044.196.687.556 1.528 1.035 2.402L.752 8.22c-.277.277-.269.656-.218.918.055.283.187.593.36.903.348.627.92 1.361 1.626 2.068.707.707 1.441 1.278 2.068 1.626.31.173.62.305.903.36.262.05.64.059.918-.218l5.615-5.615c.118.257.092.512.05.939-.03.292-.068.665-.073 1.176v.123h.003a1 1 0 0 0 1.993 0H14v-.057a1.01 1.01 0 0 0-.004-.117c-.055-1.25-.7-2.738-1.86-3.494a4.322 4.322 0 0 0-.211-.434c-.349-.626-.92-1.36-1.627-2.067-.707-.707-1.441-1.279-2.068-1.627-.31-.172-.62-.304-.903-.36-.262-.05-.64-.058-.918.219l-.217.216zM4.16 1.867c.381.356.844.922 1.311 1.632l-.704.705c-.382-.727-.66-1.402-.813-1.938a3.283 3.283 0 0 1-.131-.673c.091.061.204.15.337.274zm.394 3.965c.54.852 1.107 1.567 1.607 2.033a.5.5 0 1 0 .682-.732c-.453-.422-1.017-1.136-1.564-2.027l1.088-1.088c.054.12.115.243.183.365.349.627.92 1.361 1.627 2.068.706.707 1.44 1.278 2.068 1.626.122.068.244.13.365.183l-4.861 4.862a.571.571 0 0 1-.068-.01c-.137-.027-.342-.104-.608-.252-.524-.292-1.186-.8-1.846-1.46-.66-.66-1.168-1.32-1.46-1.846-.147-.265-.225-.47-.251-.607a.573.573 0 0 1-.01-.068l3.048-3.047zm2.87-1.935a2.44 2.44 0 0 1-.241-.561c.135.033.324.11.562.241.524.292 1.186.8 1.846 1.46.45.45.83.901 1.118 1.31a3.497 3.497 0 0 0-1.066.091 11.27 11.27 0 0 1-.76-.694c-.66-.66-1.167-1.322-1.458-1.847z"/>
          </svg>&nbsp;Color
        </button>
        
        <div class="colorPicker" style="display:none;" id="colorPickerdiv">
          <label for="colorWell">Select Color:</label>
          <input type="color" value="#ffffff" id="colorPicker" />
        </div>    
      
       
      </div>
      <div id="tableWrapper"></div>
        
      </div>
   
    <script>
      
      let isMouseDown = false;
      let idObj = {};
      let selectedColor ='';

      function setCellColorMouseDown(event){
            isMouseDown= true;
            event.preventDefault();
            console.log('mousedown');
            idObj[event.target.id]= [];
            event.target.style=`background-color: ${selectedColor};`;
      }

      function setCellColorMouseUp(event){
            isMouseDown = false;
            event.preventDefault();
            console.log('mouseup');
            idObj[event.target.id]= [];
            event.target.style=`background-color: ${selectedColor};`;

      }

      function setCellColorMouseOver(event){
        event.preventDefault();
        if(isMouseDown){
            console.log(event.target.id);
            idObj[event.target.id]= [];
            event.target.style=`background-color: ${selectedColor};`;
          }
      }


      function setColorPicker(){

          let displayType =  document.getElementById('colorPickerdiv').style.display;

          if(displayType =='inline'){
            document.getElementById('colorPickerdiv').style.display='none';
            let elm = document.getElementsByTagName('td');
            for (let i = 0; i < elm.length; i++) {             
              elm[i].removeEventListener('mousedown', setCellColorMouseDown);
              elm[i].removeEventListener('mouseup',setCellColorMouseUp );
              elm[i].removeEventListener('mouseover',setCellColorMouseOver);
              elm[i].setAttribute('contenteditable','true');
            }
            document.body.style.cursor = "auto"; 
          }else{

            document.getElementById('colorPickerdiv').style.display='inline';
            let colorPicker = document.getElementById('colorPicker');
            colorPicker.addEventListener('change', function(e) {
              selectedColor = colorPicker.value;
            }, false);

            let elm = document.getElementsByTagName('td');
            for (let i = 0; i < elm.length; i++) {             
              elm[i].addEventListener('mousedown', setCellColorMouseDown);
              elm[i].addEventListener('mouseup',setCellColorMouseUp );
              elm[i].addEventListener('mouseover',setCellColorMouseOver);
              elm[i].setAttribute('contenteditable','false');
            }
            document.body.style.cursor = "cell"; 
           
          }
            
      }

      (function () {

        // Generate Table 
        let row =13;
        let column = 8;
        const tbl = document.createElement("table");
        const tblBody = document.createElement("tbody");

        // creating all cells
        for (let i = 0; i < row; i++) {
          // creates a table row
          const row = document.createElement("tr");
          for (let j = 0; j < column; j++) {
            const cell = document.createElement("td");
            cell.setAttribute('contenteditable','true');
            cell.setAttribute('id',`${i}${j}`);
           
            const cellText = document.createTextNode(`${i}, ${j}`);
            cell.appendChild(cellText);
            row.appendChild(cell);
          }
          tblBody.appendChild(row);
        }
    
        tbl.appendChild(tblBody);  
        document.body.appendChild(tbl);
        tbl.setAttribute("border", "1");
        
      })();

     
    </script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>   
  </body>
</html>

Here is the screenshot

adbanner