How to make a table where the cells are inputs in React with Material UI

Asked

Viewed 838 times

0

I need to create a table with Material UI that will actually be a matrix, the size of this matrix will be dynamic and precise that the cells in the table are inputs to be completed and inputs will create the truth matrix that will be passed to the server and saved in the database.

I managed to generate the table with the inputs and everything else, but I don’t know how to manage state of the inputs to get the values that will be saved, until then the table code is like this:

import React, { useContext, useState } from 'react'
import {
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
TableRow,
TextField,
Grid,
Button,
Paper
} from '@material-ui/core'

import { ProjetoContext } from 'contexts/projetos'

const TabelaPonderacao = () => {
  const { projetoAtual } = useContext(ProjetoContext)
  const [matriz, setMatriz] = useState([[]])

  console.log(matriz)

  const handleClickLimpar = () => {
    console.log('Limpou')
  }

  const handleClickSalvar = () => {
    console.log(matriz)
  }

return (
 <>
  <Grid container spacing={4}>
    <Grid item>
      <TableContainer component={Paper}>
        <Table aria-label='simple table'>
          <TableHead>

            <TableRow>
              <TableCell>Poderação dos Critérios</TableCell>
              {projetoAtual.criterios.map((criterio) => (
                <TableCell key={criterio.id}>{criterio.nome}</TableCell>
              ))}
            </TableRow>
          </TableHead>
          <TableBody>
            {projetoAtual.criterios.map((criterio) => (
              <TableRow key={criterio.id}>
                <TableCell>{criterio.nome}</TableCell>
                {projetoAtual.criterios.map((c) => (
                  <TableCell key={c.id}>
                    <TextField
                      id='outlined-basic'
                      variant='outlined'
                      onChange={(e) => {
                        const val = e.target.value
                        setMatriz(prevState => {
                          console.log(prevState)
                          return [...prevState, prevState[0].concat(val)]
                        })
                      }}
                    />
                  </TableCell>
                ))}
              </TableRow>
            ))}
          </TableBody>
        </Table>
      </TableContainer>
    </Grid>

    <Grid container spacing={2} justify='flex-end'>
      <Grid item>
        <Button variant='outlined' onClick={handleClickLimpar}>
          Limpar
        </Button>
      </Grid>

      <Grid item>
        <Button variant='outlined' onClick={handleClickSalvar} color='primary'>
          Salvar
        </Button>
      </Grid>
    </Grid>
  </Grid>
 </>
 )
}

export default TabelaPonderacao

Example:

Tabela com inputs gerados automaticamente

The state of inputs should return me an array with these values:

[[1,3,5,3], [1/3,1,5,7], [1/5,1/5,1,5], [1/3,1/7,1/5,1]]

and by clicking save I will make the persistence logic.

  • is not in the array criterios?

  • didn’t get it? What I need is to generate a matrix through the state, and do a setState on inputs, only I don’t know how to do this

  • For example, if I were to generate an array, I would only need to do a prevState.Concat() passing the input value, only what I want is to generate an array and I don’t know how to do it.

  • Friend if you want to update the data of an enumeration of values, like this has 3 inputs and consequently 3 states and you need to update? is about that? something else criterios.map is consequently a array? but in that code has not declared him... where he is?

  • Well, I added the full code. What I want is from an array of objects, generate inputs that received numbers and with these numbers assemble an array. What I’m failing to do is manage the state of inputs that I’m dynamically creating. I don’t know how to do that. I hope now I’ve made my problem clear, if you don’t just ask me to answer,.

  • So I put an example of how to manage objects inside a array

  • Explain this matrix better and it has to be like this, a matrix, what is your idea?

  • In the case on the server side I will use this matrix to do some calculations, so I need the input data to be recorded as follows: [[1, 3, 4], [2, 1, 4], [7, 3, 1]], so what I want to do is render the matrix with the inputs so that the user can fill in and that the result of what the user fills in is in the matrix format. I don’t know if it’s clear, anything you can ask. Thank you so much for helping me

  • I added the final rendering result to the question, along with the explanation of the previous comment should be clearer what I want to do.

Show 4 more comments

1 answer

1


If updating a array of values where the input(s) will have the initial state, is more or less like this (independent of Framework Css using), example:

function App() { 
  const [items, setItems] = React.useState([
    {name: "name 1"},
    {name: "name 2"},
    {name: "name 3"},
  ]);    
  function changeItems(e, index) {        
    let it = [...items];    
    it[index].name = e.target.value;
    setItems(it);
  }
  return (
    <div>
      {items.map((item, index) =>
        (<div>
          <input 
            value={item.name} 
            key={index} 
            onChange={e => changeItems(e, index)} 
          />
         </div>
        )
      )}
      <pre>{JSON.stringify(items, null, 2)}</pre>
    </div>
  )
 }
 ReactDOM.render( <App/> , document.getElementById('root'));
<link href="https://cdnjs.cloudflare.com/ajax/libs/material-design-iconic-font/2.2.0/css/material-design-iconic-font.min.css" rel="stylesheet"/>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.9.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.9.0/umd/react-dom.production.min.js"></script>
<div id="root"></div>

whereas the array of items with your objects will be updated and with the new values in items can be used for any purpose.

Continuing the troubleshooting, it has been reported that the data needs to be a array of array where each row is an item from array:

function App() { 
  const [items, setItems] = React.useState([
   ["0", "0", "0", "0"],
   ["1", "1", "1", "1"],
  ]);    
  function handleChange(e, position, line) {
    let it = [...items];
    it[line][position] = e.target.value;
    setItems(it);
  }
  return (
    <div>
      {items.map((array, line) => (<p>{ 
        array.map((a, position) => (
          <input 
            onChange={e => handleChange(e, position, line )}
            value={a} 
            style={{width:45, margin:3}} 
          />
        ))}
       </p>))}
      <pre>{JSON.stringify(items, null, 2)}</pre>
    </div>
  )
 }
 ReactDOM.render( <App/> , document.getElementById('root'));
<link href="https://cdnjs.cloudflare.com/ajax/libs/material-design-iconic-font/2.2.0/css/material-design-iconic-font.min.css" rel="stylesheet"/>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.9.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.9.0/umd/react-dom.production.min.js"></script>
<div id="root"></div>

in the example followed the logic of loading each line the data inside the input and the next line is next array and so on. In the change function the event that contains the information and the row and column that will happen the changes copies the array immutable (cannot be changed directly) and sent a new value to the new array.

  • Using array and objects I know how to do, what I’m not getting is to use with an array, as it is in the code, I want to generate an array from the data that comes from the inputs, but the way I Gero the inputs is from a list, so I’m not sure how to manage the state of inputs. I hope it’s been made clear rsrsrs, any questions may ask

  • @Jelsnow as this Matrix should look, exemplify why a Matrix like this might not be necessary. Give me examples in your edition.

  • I added an example to the question, I hope it’s clear what I’m trying to do, thanks for the help.

  • @Jelsnow was edited. Also pay attention to the array of array needs to contain some kind of value for this to work.

  • That’s exactly what I wasn’t able to do, thank you very much, I will adapt and put in my code, thank you very much.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.