skip to Main Content

Further to my previous question, I’m now trying to find out a way to dynamically change the selected value of two dropdown-menus by clicking on a table row/cell, preferably located on another html page.

The code below shows my attempt to get it to work, but it doesn’t show the values of both dropdown-menus simultaneously, instead they get blanked by each other when clicking on any table row.

Apparently, the dropdowns get affected by the columns instead of by the rows.

// Get references to the dropdown and table
const dropdowns = document.getElementById('dropdown') && ('dropdown_2');
const tableRows = document.querySelectorAll('#table td');

// Add a click event listener to each table row
tableRows.forEach(row => {
  row.addEventListener('click', function() {

    // Get the value associated with the clicked row
    const selectedValue = this.getAttribute('value');

    // Set the dropdown's value to the selected value
    dropdown.value = selectedValue;
    dropdown_2.value = selectedValue;
  });
});
<select id="dropdown">
  <option value="option1">Option 1</option>
  <option value="option2">Option 2</option>
  <option value="option3">Option 3</option>
</select>

<select id="dropdown_2">
  <option value="value1">Value 1</option>
  <option value="value2">Value 2</option>
  <option value="value3">Value 3</option>
</select>

<table border="1" cellpadding="1" cellspacing="1" id="table">
  <tr>
    <th value="">Options</th>
    <th value="">Value</th>
  </tr>
  <tr>
    <td value="option1">Option1</td>
    <td value="value1">Value1</td>
  </tr>
  <tr>
    <td value="option2">Option2</td>
    <td value="value2">Value2</td>
  </tr>
  <tr>
    <td value="option3">Option3</td>
    <td value="value3">Value3</td>
  </tr>
</table>

4

Answers


  1. You are setting the value of both dropdowns to selectedValue which is present in either dropdown or dropdown2 but not both. You need to check if the options are present in the dropdown before setting its value.

    A simple check will do this:

    if (dropdown.querySelector('[value="' + selectedValue + '"]'))
    dropdown.value = selectedValue;
    else
    dropdown_2.value = selectedValue;
    
    Login or Signup to reply.
  2. The following doesn’t do what you expect:

    const dropdowns = document.getElementById('dropdown')&&('dropdown_2');
    

    It sets the value of dropdowns to the string "dropdown_2". But that doesn’t matter because dropdowns isn’t used for anything anyway. If you want a list of elements whose ID starts with "dropdown" then:

    const dropdowns = document.querySelectorAll('[id^=dropdown]')
    

    will do.

    Then there is:

    const tableRows = document.querySelectorAll('#table td');
    

    This selects td elements, not rows. So use:

    const tableRows = document.querySelectorAll('#table tr');
    

    But now:

    this.getAttribute('value')
    

    won’t work because this references the row, and the value attribute is on the cells. So get the value of the cells using the row’s cells collection.

    e.g.

    <select id="dropdown">
      <option value="option1">Option 1</option>
      <option value="option2">Option 2</option>
      <option value="option3">Option 3</option>
    </select>
    
    <select id="dropdown_2">
      <option value="value1">Value 1</option>
      <option value="value2">Value 2</option>
      <option value="value3">Value 3</option>
    </select>
    
    <table border="1" cellpadding="1" cellspacing="1" id="table">
      <tr>
        <th value="">Options</th>
        <th value="">Value</th>
      </tr>
      <tr>
        <td value="option1">Option1</td>
        <td value="value1">Value1</td>
      </tr>
      <tr>
        <td value="option2">Option2</td>
        <td value="value2">Value2</td>
      </tr>
      <tr>
        <td value="option3">Option3</td>
        <td value="value3">Value3</td>
      </tr>
    </table>
    
    <script>
      // Get references to the dropdown and table
      const dropdowns = document.querySelectorAll('[id^=dropdown]')
      const tableRows = document.querySelectorAll('#table tr');
    
      // Add a click event listener to each table row
      tableRows.forEach(row => {
        row.addEventListener('click', function() {
    
          // Get the cells associated with the clicked row
          let cells = this.cells;
    
          // Set the dropdown values to the selected values
          dropdown.value = cells[0].getAttribute('value');
          dropdown_2.value = cells[1].getAttribute('value');
        });
      });
    </script>

    BTW, using non–standard attributes to store data is not a good idea, it’s why data– attributes were invented.

    Login or Signup to reply.
  3. I would change your selector to work off #table tr instead of #table td. Then you you can set the dropdown values respectively based off the value attribute of the appropriate positioned cell ():

    // Get references to the dropdown and table
    const dropdowns = document.getElementById('dropdown') && ('dropdown_2');
    const tableRows = document.querySelectorAll('#table tr');
    
    // Add a click event listener to each table row
    tableRows.forEach(row => {
      row.addEventListener('click', function() {
    
        // Get the value associated with the clicked row
        //const selectedValue = this.getAttribute('value');
    
        var cells = row.getElementsByTagName("td");
        // Set the dropdown's value to the selected value
        dropdown.value = cells[0].getAttribute("value");
        dropdown_2.value = cells[1].getAttribute("value");
      });
    });
    <select id="dropdown">
      <option value="option1">Option 1</option>
      <option value="option2">Option 2</option>
      <option value="option3">Option 3</option>
    </select>
    
    <select id="dropdown_2">
      <option value="value1">Value 1</option>
      <option value="value2">Value 2</option>
      <option value="value3">Value 3</option>
    </select>
    
    <table border="1" cellpadding="1" cellspacing="1" id="table">
      <tr>
        <th value="">Options</th>
        <th value="">Value</th>
      </tr>
      <tr>
        <td value="option1">Option1</td>
        <td value="value1">Value1</td>
      </tr>
      <tr>
        <td value="option2">Option2</td>
        <td value="value2">Value2</td>
      </tr>
      <tr>
        <td value="option3">Option3</td>
        <td value="value3">Value3</td>
      </tr>
    </table>
    Login or Signup to reply.
  4. First, let’s see how it can be made to work

    // Get references to the dropdown and table
    const [drodown, dropdown_2] = [...document.querySelectorAll('#dropdown, #dropdown_2')];
    const tableRows = document.querySelectorAll('#table tr');
    
    // Add a click event listener to each table row
    tableRows.forEach(row => {
      row.addEventListener('click', function() {
    
        // Get the value associated with the clicked row
        const [option, value] = [...this.querySelectorAll('td')].map(item => item.getAttribute("value"));
    
        // Set the dropdown's value to the selected value
        dropdown.value = option;
        dropdown_2.value = value;
      });
    });
    <select id="dropdown">
      <option value="option1">Option 1</option>
      <option value="option2">Option 2</option>
      <option value="option3">Option 3</option>
    </select>
    
    <select id="dropdown_2">
      <option value="value1">Value 1</option>
      <option value="value2">Value 2</option>
      <option value="value3">Value 3</option>
    </select>
    
    <table border="1" cellpadding="1" cellspacing="1" id="table">
      <tr>
        <th value="">Options</th>
        <th value="">Value</th>
      </tr>
      <tr>
        <td value="option1">Option1</td>
        <td value="value1">Value1</td>
      </tr>
      <tr>
        <td value="option2">Option2</td>
        <td value="value2">Value2</td>
      </tr>
      <tr>
        <td value="option3">Option3</td>
        <td value="value3">Value3</td>
      </tr>
    </table>

    Explanation:

    • your const dropdowns = document.getElementById('dropdown') && ('dropdown_2'); was attempting to get the element whose id is dropdown and, if not found, then evaluated to the dropdown string, instead of getting the dropdowns, as you intended
    • I fixed the error above by querying for "#dropdown, #dropdown_2"instead and destructuring the result into similarly named attributes
    • I changed tableRows to actually represent tr elements rather than td elements inside your table
    • therefore the click listener was assigned to the tr instead of some td
    • inside the click listener, I search for td elements, convert the array-like-object I received in the answer into an array via [...this.querySelectorAll('td')] and then map the items to their value attribute, destructuring the result into variables named option and value, respectively
    • later on I assign these values to the respective dropdowns’ value

    Now, you had some other criteria mentioned in your question as well and that might be important to you. You said that you prefer the dropdowns and the table to be on different HTML pages. If this is indeed a desire you want to accomplish, then you will need to either message between pages, use window.open or communicate between an iframe and the page that contains it if your are on the same origin.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search