Ways to change the background color of a specific row and an entire table with JavaScript

In my application, I have implemented a feature where clicking on the "Add New Item" button adds rows dynamically using Javascript. Each input field in the dynamically added rows has a unique ID, and this functionality is working smoothly.

When a number from the left table is clicked, it populates dynamically in the corresponding row on the left side. Similarly, when a number from the right table is clicked, it populates in the single input field on the right side (after the plus icon).

Furthermore, hovering over the 1st row causes the background color to change to green, including the matching element on the left table, which functions correctly.

I am currently trying to enhance the logic as follows: a.) Upon clicking the "Add New Item" button, a new row should be added following the format of the 1st row. b.) After selecting any number from the two tables (right and left), their values populate in the rows accordingly. When hovering over these values in the rows, their background colors should immediately change to match the source table's values...

Note: Essentially, I aim to replicate the behavior of the 1st row across all dynamically added rows after the button click event.

For reference, here is the JsFiddle link: Js Fiddle

If you could lend your assistance with this task, I would greatly appreciate it.

Below is the commented Javascript code outlining the steps involved:

// Add row input fields dynamically on button click
// Starting number of inputs
let count = 5;

// Wrapper
const wrapper = document.querySelector("#wrapper");

document.querySelector("#btn").addEventListener("click", () => {
  const container = document.createElement("div");

  for (let i = 0; i < 5; i++) {
    // Increment the count to ensure uniqueness
    count++;

    // Create a new `<input>` element
    const input = document.createElement("input");
    input.type = "text";
    input.name = count;
    input.size = "4";
    input.id = `inp${count}`;

    container.appendChild(input);

    // Optional: add whitespace after each child
    container.append(document.createTextNode(" "));
  }
  wrapper.appendChild(container);
});
// END creating rows dynamically

let currentInput = 1;
let bonusInput = 1;

// Left table click event
$("#table1 td").on("click", function(event) {
  // Get the number associated with the click
  let num = $(this).text();
  // Populate it in the appropriate input field
  $("#inp" + currentInput++).attr("value", num);
});

// Right table click event
$("#table2").on("click", function(event) {
  // Get the number associated with the click
  let bon = event.target.textContent;
  // Populate it in the appropriate input field
  $("#bonus" + bonusInput++).attr("value", bon);
});

// Manipulate background colors of rows based on hover and selected tables
$("input").hover(
  function(event) {
    let parent = $(this).parent();
    $(parent.children()).each(function(index, element) {
      let num = $(element).val();
      if (num) {
        // Change input color on hover
        $(this).css("backgroundColor", "green");
        // Change left table bgcolor on hover
        $("#table1 td").each(function() {
          if ($(this).text() === num) $(this).css("backgroundColor", "green");
        });
      }
    });
  },
  function(event) {
    // Reset input color on hover out
    let parent = $(this).parent();
    $(parent.children()).each(function(index, element) {
      $(element).css("backgroundColor", "white");
    });
    // Reset left table bgcolor on hover out
    $("#table1 td").each(function() {
      $(this).css("backgroundColor", "orange");
    });
  }
);

Answer №1

When utilizing the .hover() method, the event listeners are established and attached to the existing items at the time of creation. Any inputs generated afterwards will be disregarded. It is essential to allocate/enable the hover behavior for them when creating/appending the new inputs.

//Dynamically add row input fields on button click
// Initial number of inputs
let count = 0;

// Wrapper
const wrapper = document.querySelector('#wrapper');

document.querySelector('#btn').addEventListener('click', () => {

  // Increment the count to ensure we have unique inputs
  count++;

  const container = document.createElement('div');
          
  for (let i = 1; i <= 5; i++) {
    let input_index = (count * 5) + i;
    
    // Create new `<input>` element
    const input = document.createElement('input');
    input.type = 'text';
    input.name = input_index;
    input.size = '4';
    input.id = `inp${input_index}`;

    $(input).hover(onInputHoverIn, onInputHoverOut);

    container.appendChild(input);
            
    // Optional: add empty whitespace after each child
    container.append(document.createTextNode(' '));
  }
  
  // Bonus-Input
  container.append(document.createTextNode(' + '));

  let input_index = count + 1;
  // Create new `<input>` element
  const input = document.createElement('input');
  input.type = 'text';
  input.name = `bonus${input_index}`;
  input.size = '4';
  input.style.marginLeft = '20px';
  input.id = `bonus${input_index}`;
  
  $(input).addClass('bonus-input');
  $(input).hover(onInputHoverIn, onInputHoverOut);

  container.appendChild(input);
  
  wrapper.appendChild(container);
});
//END creating rows dynamically

let currentInput = 0; 
let bonusInput = 0;

//Left table on click event
$("#table1 td").on('click',function(event){
  if (currentInput >= ((count + 1) * 5)) {
    return;
  }
  currentInput++;
  //gets the number associated with the click
  let num = $(this).text(); 
  //Populate it in 1st row input fields (before plus sign)
  $("#inp" + currentInput).attr("value",num); 
});

//Right table on click event
$("#table2").on('click',function(event){
  if (bonusInput >= (count + 1)) {
    return;
  }
  bonusInput++;
  //gets the number associated with the click
  let bon = event.target.textContent;
  //Populate it in 1st row input fields (after plus sign)
  $("#bonus" + bonusInput).attr("value",bon);
});

//Modify background colors of rows based on corresponding tables they were selected on hover in and out
function onInputHoverIn(event) {
  let parent = $(this).parent();
  $(parent.children()).each(function (index, element) {
    let num = $(element).val();
    let isBonus = $(element).hasClass('bonus-input');
    //console.log(num);
    if (num) {
      //Change input color on hover
      $(this).css("backgroundColor","green");
      if (!isBonus) {
        //Change left table bgcolor on hover
        $("#table1 td").each(function() {
          if ($(this).text() === num) $(this).css("backgroundColor","green");
        });
      } else {
        //Change left table bgcolor on hover
        $("#table2 td").each(function() {
          if ($(this).text() === num) $(this).css("backgroundColor","green");
        });
      }
      }
    });
}
function onInputHoverOut(event) {
    //Change input color on hover out
    let parent = $(this).parent();
    $(parent.children()).each(function (index, element) {
      $(element).css("backgroundColor","white");
    });
    //Change left table bgcolor on hover out
    $("#table1 td, #table2 td").each(function() {
      $(this).css("backgroundColor","orange");
    }); 
};
$("input").hover(onInputHoverIn, onInputHoverOut);
table {
  border-collapse: collapse;
  border: 5px solid black;
  width: 100%;
}
td {
  width: 50%;
  height: 2em;
  border: 1px solid #ccc;
  background-color:orange;
  text-align:center;
  vertical-align:middle;
  font-weight:bold;
  cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<!--Table on the left -->
<div style="width: 140px; float: left;">
  <table id="table1">
     ...
   Add your custom HTML code here
     ...
  </table>
</div>

<!-- Additional code or tables can be included as per requirement -->

<div style="clear: both;">
  <div id="wrapper">
     ...
   Add your dynamic input creation elements here
     ...
  </div>
  <button type="button" id="btn">Add new input group</button>
</div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Which elements should I focus on when utilizing Media Query?

For the width specified in the CSS for various tags within my HTML, do I need to individually list each tag when setting CSS for a Media Query? If so, how can I do this while maintaining the same ratio for full screen? <!DOCTYPE html PUBLIC "-//W3C//DT ...

Guide on setting the href value within a $.each loop in AJAX requests

I am struggling with downloading a file within a thread. The issue I'm facing is that I can't set the file name in the href and download attributes, so when I attempt to download it, it shows no file available. However, I did realize that replaci ...

Can uniform columns be created in separate HTML elements?

Looking to create a uniform list in HTML, where the columns inside each panel line up perfectly. See the desired layout: https://i.sstatic.net/FbbPu.png In this example, Col_1 has a width of "BBBBB", as it is the widest content in that column, ...

Customize numbers in JavaScript with a Unity-inspired design changer

I am currently working on implementing a number input feature that allows users to adjust values by clicking and holding the mouse button while moving the cursor left and right, similar to Unity's editor number adjuster: https://youtu.be/uY9PAcNMu8s?t ...

"Discovering the magic behind leaflet js's method of fetching tiles directly from

If you imagine tiles being stored in a file system similar to the image shown below https://i.sstatic.net/6NryK.png You can take a quick look at this URL Take a look at the code var map = L.map('map').setView([0, 0], 2); L.tileLayer(& ...

A guide on transferring data between Ajax and PHP using Data-tables

I'm currently facing an issue while working with Data-tables. I am trying to pass a value from Ajax to a PHP file. The Ajax section of my code looks like this: <script> $(document).ready(function() { var oTable = $(&ap ...

Challenges in customizing the bootstrap navigation bar links

Having an issue with the bootstrap navbar link displaying on small devices. Here is the template I'm using: https://i.sstatic.net/jSy1b.png The last item is displaying in two lines. ...

What is the best way to find the index of an element with the special class "active"?

I'm having trouble retrieving the index of the active div with the class name active among a collection of divs with the class name slide. Despite trying various selectors, I haven't been successful in getting the desired result. Your assistance ...

Display temporary image if image is not located

I attempted to utilize the onerror attribute to display a placeholder image when the desired image is not found in the folder. The image path is dynamically generated from the backend. The code snippet below shows how I implemented this: <img class=&quo ...

Concern with Isotope's masonry feature

I'm at my wit's end! The container div I'm dealing with is 1170px wide. My goal is to fit in 3 divs within this width. The first div is 275px wide, the second is 580px wide, and the third is also 275px wide. Altogether, these divs should ad ...

Adjust the image size to fit the page according to its height

Having a dilemma here. I have this square image (2048x2048) that I want to set as a background. The tricky part is, I want it to display borders when the page stretches into widescreen mode, but also resize while maintaining its square shape when the page ...

List of components in a column arrangement, with each row resizing its width to fit the contents within

I am looking to create a vertical list where each row adjusts its width to perfectly fit its content, instead of expanding to fill the container as a default div does. The goal is to accomplish this with just one HTML element for each row, without any add ...

Guide to linking a specific event with JQuery event handlers

I have a Javascript function named Howto that is triggered by a button press: function howto(){ $('#elementtoupdate').ajaxSend(function() { //Code to run }); $('#elementtoupdate').ajaxComplete(function() { //Co ...

What is the best way to align an html table to the top of the page?

Can anyone help me with positioning an HTML table at the top of the screen in IE7 without the automatic top border? I am using HTML and CSS for this. I'm currently working on development in VS2008. ...

If you encounter an unrecognized operator in Javascript, make sure to handle this error and return

I have a script that identifies operators in an array and uses them to calculate based on another array. Below is the script: function interpret(...args) { let operators = args[1]; //access the operators array let values = args[2] //numbers except t ...

Move the element outside of the parent container

I am in the process of creating a collapsible sidebar using bootstrap, and I am attempting to have a submenu appear outside of the sidebar when it is toggled to a mini navigation. For example: When the window size is greater than 767 pixels and you click ...

How to Transform JSON Element into a JavaScript Array in AngularJS?

Implementing AngularJS to fetch values in JSON format using $resource call. The model element I require is a Javascript array structured as: [ [1328983200000, 40], [1328983200000, 33], [1328983200000, 25], [1328983200000, 54], [1328983200000, 26], [1328 ...

Flask-WTForms QuerySelectField not displaying properly when rendered with Bootstrap causing <select> HTML tag issue

I am facing an issue while constructing a Flask form that includes a QuerySelectField. Despite having everything in place, Bootstrap is displaying the <select> as if it were a text input field. Upon inspecting the page source, I noticed that the fie ...

Unable to run for loop in vue.js

Hello, I'm a newcomer to using Vue.js and am encountering an issue with executing a simple for loop in my code. Any assistance or guidance would be greatly appreciated. Here is the snippet of my code: var Vue = require('vue'); Vue.use(requi ...

How can I use an array to dynamically populate an option html tag in react?

I am attempting to populate an option in jsx with values from an array called currencyOptions. Despite using this method, the options are remaining blank. The array is passed down to the component as a prop, set using useState, and the data is fetched from ...