Search code examples
javascripthtmldropdownbox

Making changes in HTML Table using Dropdown List


I want to show changes made to the value in any cell in a one row table from a drop down list to be in red. Each cell has an associated dropdown. However if the same value in the dropdown and the cell is clicked the value in the cell shouldn’t change color. I thought I could keep a cloned copy of the original Table cell data in a separate function - then compare any changes if they are made. However this information is deleted each time in the function shown here as a user goes from cell to cell. The table consists of a series of cells - one cell is included here.

// Attach listeners
window.onload = function() {
  var cellData = document.querySelectorAll('.dropdown-content p').forEach(
    node => node.addEventListener('click', displayCellData, false)
  );
}

function displayCellData(evt) {
  // to display the previous cell data
  evt.stopPropagation();
  var cell = this.closest('td');
  var origCellVal = [];
  // Array of original cell values  
  var previous = cell.previousElementSibling.innerHTML;
  console.log(previous);
  var cellVal = $(evt.target).text();
  origCellVal[cell.cellIndex] = previous;
  document.getElementById("displayArray").innerHTML = origCellVal;
  if (cellVal != previous) {
    previous = cellVal;
    // only change the text color if cellVal changed
    cell.previousElementSibling.innerHTML = "<span class='color-red'>" +
      cellVal + "</span>";
    if (previous = origCellVal[cell.cellIndex]) {
      cellVal.innerHTML = "<span class='color-black'>" + cellVal +
        "</span>";
    }
  }
}
table#t00, th,td {
border: 1px solid red;
width:80%;
margin-left:15%; 
margin-right:15%;
}
table#t01 {
table-layout: fixed;
  width: 100%; 
  background-color: #f1f1c1;
  height: 50px;
  text-align: center;
  font-size: large;
}
table#t02 {
table-layout: fixed;
  width: 100%; 
  background-color: #f1f1c1;
  height: 50px;
  text-align: center;
  font-size: large;
}
.equal-width td { 
width: 5%; 
}

.dropbtn {
  background-color: #4CAF50;
  color: white;
  padding: 5px;
  font-size: 16px;
  border: none;
  cursor: pointer;
}

.dropdown {
  position: relative;
  display: inline-block;
}

.dropdown-content {
  display: none;
  position: absolute;
  background-color: #f9f9f9;
  min-width: 100px;
  box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.8);
  z-index: 1;
}

.dropdown-content a {
  color: black;
  padding: 12px 16px;
  text-decoration: none;
  display: block;
}

.dropdown-content a:hover {background-color: #f1f1f1}

.dropdown:hover .dropdown-content {
  display: block;
}

.dropdown:hover .dropbtn {
  background-color: #3e8e41;
}

.color-red{
    color: #F00;
}

.color-black{
    color: #000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p id="displayArray"></p>
<table>
  <tr>
    <td>Closed</td>
    <td>
      <div class="dropdown">
        <button class="dropbtn">Change?</button>
        <div class="dropdown-content">
          <p>OPEN</p>
          <p>Closed</p>
        </div>
      </div>
    </td>
    </td>
    . .

  </tr>
</table>


Solution

  • You're creating a new, empty origCellValue array every time you call displayCellData(), so it doesn't hold the values from previous calls.

    However, rather than using a separate array, I suggest you save the information in the DOM itself. You can use a dataset attribute on the element to save the information.

    And rather than inserting new HTML with <span> elements, you can simply change the class list of the <td> itself.

    cellVal.innerHTML is just wrong. cellVal is a string, not a DOM element.

    // Attach listeners
    window.onload = function() {
      var cellData = document.querySelectorAll('.dropdown-content p').forEach(
        node => node.addEventListener('click', displayCellData, false)
      );
    }
    
    function displayCellData(evt) {
      // to display the previous cell data
      evt.stopPropagation();
      var cell = this.closest('td');
      var prev = cell.previousElementSibling;
      if (!prev.dataset.origVal) {
        prev.dataset.origVal = prev.innerText;
      }
      var origVal = prev.dataset.origVal;
      if (evt.target.textContent == origVal) {
        prev.classList.remove("color-red");
        prev.classList.add("color-black");
      } else {
        prev.classList.remove("color-black");
        prev.classList.add("color-red");
      }
      prev.textContent = evt.target.textContent;
    }
    table#t00,
    th,
    td {
      border: 1px solid red;
      width: 80%;
      margin-left: 15%;
      margin-right: 15%;
    }
    
    table#t01 {
      table-layout: fixed;
      width: 100%;
      background-color: #f1f1c1;
      height: 50px;
      text-align: center;
      font-size: large;
    }
    
    table#t02 {
      table-layout: fixed;
      width: 100%;
      background-color: #f1f1c1;
      height: 50px;
      text-align: center;
      font-size: large;
    }
    
    .equal-width td {
      width: 5%;
    }
    
    .dropbtn {
      background-color: #4CAF50;
      color: white;
      padding: 5px;
      font-size: 16px;
      border: none;
      cursor: pointer;
    }
    
    .dropdown {
      position: relative;
      display: inline-block;
    }
    
    .dropdown-content {
      display: none;
      position: absolute;
      background-color: #f9f9f9;
      min-width: 100px;
      box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.8);
      z-index: 1;
    }
    
    .dropdown-content a {
      color: black;
      padding: 12px 16px;
      text-decoration: none;
      display: block;
    }
    
    .dropdown-content a:hover {
      background-color: #f1f1f1
    }
    
    .dropdown:hover .dropdown-content {
      display: block;
    }
    
    .dropdown:hover .dropbtn {
      background-color: #3e8e41;
    }
    
    .color-red {
      color: #F00;
    }
    
    .color-black {
      color: #000;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <p id="displayArray"></p>
    <table>
      <tr>
        <td>Closed</td>
        <td>
          <div class="dropdown">
            <button class="dropbtn">Change?</button>
            <div class="dropdown-content">
              <p>OPEN</p>
              <p>Closed</p>
            </div>
          </div>
        </td>
        </td>
        . .
    
      </tr>
    </table>