Cannot set dropdown options for second column based on user selected options in first column

Tags: #<Tag:0x00007efc61ca96a8> #<Tag:0x00007efc61ca9568>

Here is the sample react code I am trying to implement, first 2 columns of the table are dropdowns and the dropdown options for second table will depend on options selected in first column.

with below code I am not able to set the options for second column.

import React, { useState, useCallback } from ‘react’;

import ‘handsontable/dist/handsontable.min.css’;

import { HotTable } from ‘@handsontable/react’;

import axios from ‘axios’;

const HandsonTableComponent = () => {

const [tableData, setTableData] = useState([

['', '', '', '', '', ''],

['', '', '','', '', ''],

]);

const optionsForSystems = [

'Substructure',

'Superstructure',

'Mechanical Services',

'Electrical Services',

'Public Health & Hydraulics',

];

const optionsForSubSystem = {

'Mechanical Services': ['Cooling', 'Heating', 'Process', 'Ventilation'],

'Superstructure': ['Floorplate', 'Vertical Structure', 'Roof', 'Stability', 'Stairs'],

'Substructure': ['Basement Frame', 'Ground Slab', 'Foundation', 'Basement Perimeter'],

'Electrical Services': ['Electrical', 'Renewables', 'Lighting', 'Security', 'Vertical Transport'],

'Public Health & Hydraulics': ['Cold Water', 'Hot Water', 'Piped Fire Systems', 'Piped Fuel'],

};

// Function to handle button click event

const handleButtonClick = (row) => {

  const rowData = tableData[row];

  console.log('Button clicked for row:', row, rowData);



  // Example API call using Axios

  axios.post(`${process.env.REACT_APP_APPLICATION_API}/handsontable/submit`, { rowData })

    .then(response => {

      console.log('API response:', response.data);

      const updatedData = tableData.map((row) => [...row]); // Clone the data

      updatedData[row][4] = response.data['response1']

      updatedData[row][5] = response.data['response2']

      setTableData(updatedData);

      // Handle the response here

    })

    .catch(error => {

      console.error('API error:', error);

      // Handle the error here

    });

};

const columns = [

{

  type: 'dropdown',

  source: optionsForSystems,

},

{

  type: 'dropdown',

  source(query, callback) {

         // Adding debug logs to ensure the source function is being called

         console.log("Query:", query);

         console.log("Dropdown source function called for row:", query.row);

         // Ensure that tableData[query.row] exists and has a value in column 0

         const selectedSystem = tableData[query.row]?.[0];

         console.log("Selected system:", selectedSystem);

 

         const options = optionsForSubSystem[selectedSystem] || [];

         console.log("Options for dropdown:", options);

         callback(options)

  }

  // source: (query, process) => {

  //   // Adding debug logs to ensure the source function is being called

  //   console.log("Dropdown source function called for row:", query.row);

  //   // Ensure that tableData[query.row] exists and has a value in column 0

  //   const selectedSystem = tableData[query.row]?.[0];

  //   console.log("Selected system:", selectedSystem);

  //   const options = optionsForSubSystem[selectedSystem] || [];

  //   console.log("Options for dropdown:", options);

  //   // Ensure process is called with valid options (empty array if no match)

  //   process(options);

  // },

},

{

  type: 'text',

},

{

  // Add a column for buttons

  renderer: (instance, td, row, col, prop, value, cellProperties) => {

    const button = document.createElement('button');

    button.innerHTML = 'Submit'; // Set button label

    // Attach the click event listener

    button.addEventListener('click', () => handleButtonClick(row));

    // Clear the td and append the button

    td.innerHTML = '';

    td.appendChild(button);

    return td;

  },

  readOnly: true, // Make the column read-only

}, {

  type: 'text',

},

{

  type: 'text',

},

];

const handleAfterChange = useCallback((changes, source) => {

if (!changes || source === 'loadData') return; // Skip if no changes or during initial load

const updatedData = tableData.map((row) => [...row]); // Clone the data

changes.forEach(([row, col, oldValue, newValue]) => {

  if (col === 0) {

    updatedData[row][1] = ''; // Reset SubSystem when System changes

  }

  updatedData[row][col] = newValue;

});

setTableData(updatedData); // Update the table with the new data

}, [tableData]);

return (

<div>

  <HotTable

    data={tableData}

    columns={columns}

    colHeaders={['System', 'SubSystem', 'Description', 'Action', 'Response 1', 'Response 2']}

    rowHeaders

    width="100%"

    height="300"

    afterChange={handleAfterChange}

    licenseKey="non-commercial-and-evaluation" // Replace with your Handsontable license key

  />

</div>

);

};

export default HandsonTableComponent;

Hi @karthik.kakarlapudi1

Thank you for contacting us. We would need to see the code in a form of a demo, where the issue can be replicated.

In the meantime you can check similar solution that we have in this example: https://jsfiddle.net/handsoncode/h9s7g5k3/

You can also modify it to match your implementation.

Thanks for the response @adrian.szymanski, here is the link to the fiddle
https://jsfiddle.net/kvarma1012/h4k8oj0d/8/

here i am trying to render the functional react component that returns handsontable, in the code below I am trying load dropdown options based on fist column selected option.

{
type: ‘dropdown’,
source(query, callback) {
// Adding debug logs to ensure the source function is being called
console.log(“Query:”, query);
console.log(“Dropdown source function called for row:”, query.row);
// Ensure that tableData[query.row] exists and has a value in column 0
const selectedSystem = tableData[query.row]?.[0];
console.log(“Selected system:”, selectedSystem);
const options = optionsForSubSystem[selectedSystem] || [];
console.log(“Options for dropdown:”, options);
callback(options)
}

I am using version 11, please let me know if I have to update to latest one

Hi @karthik.kakarlapudi1

Can you please check your example? It throws an error and doesn’t run.