javascript - Adding a Radio button of material UI inside row cell in table, - Stack Overflow

My design currently stands like thisI am using Material UI's radio button, i want to make each row

My design currently stands like this

I am using Material UI's radio button, i want to make each row select able just once. When i add a <RadioButton> ponent, i am able to select it but however i am not able to toggle between rows

  transactionRow(member: Object) {
    return (
      <tr id='drawLotteryTabel' style={styles.tr} key={member.uuid}>
        <td className="col-md-2 col-xs-2">{member.user.fullName}</td>
        <td className="col-md-1 col-xs-1">{this.getSubscriptionDropDown(member.subscriptions)}</td>
        <td className="col-md-2 col-xs-2">{CommonConstants.INR_SYMBOL + ' ' + Utils.formatNumberLocalised(member.bidDiscountAmount || 0)}</td>
        <td className="col-md-2 col-xs-2">{CommonConstants.INR_SYMBOL + ' ' + Utils.formatNumberLocalised(member.bidDiscountPercent || 0)}</td>
        <td className="col-md-2 col-xs-2">{CommonConstants.INR_SYMBOL + ' ' + Utils.formatNumberLocalised(member.unpaidAmount || 0)}</td>
        <td
          className="col-md-2 col-xs-2"
        >
          <RadioButtonGroup name="shipSpeed" defaultSelected="not_light" key={member.uuid}>
            <RadioButton
              value="light"
              style={styles.radioButton}
            />
          </RadioButtonGroup></td>
      </tr>

    );
  }

The Above code results in something like this

What should i do so that i get the entire table row as a single entity to select.

My design currently stands like this

I am using Material UI's radio button, i want to make each row select able just once. When i add a <RadioButton> ponent, i am able to select it but however i am not able to toggle between rows

  transactionRow(member: Object) {
    return (
      <tr id='drawLotteryTabel' style={styles.tr} key={member.uuid}>
        <td className="col-md-2 col-xs-2">{member.user.fullName}</td>
        <td className="col-md-1 col-xs-1">{this.getSubscriptionDropDown(member.subscriptions)}</td>
        <td className="col-md-2 col-xs-2">{CommonConstants.INR_SYMBOL + ' ' + Utils.formatNumberLocalised(member.bidDiscountAmount || 0)}</td>
        <td className="col-md-2 col-xs-2">{CommonConstants.INR_SYMBOL + ' ' + Utils.formatNumberLocalised(member.bidDiscountPercent || 0)}</td>
        <td className="col-md-2 col-xs-2">{CommonConstants.INR_SYMBOL + ' ' + Utils.formatNumberLocalised(member.unpaidAmount || 0)}</td>
        <td
          className="col-md-2 col-xs-2"
        >
          <RadioButtonGroup name="shipSpeed" defaultSelected="not_light" key={member.uuid}>
            <RadioButton
              value="light"
              style={styles.radioButton}
            />
          </RadioButtonGroup></td>
      </tr>

    );
  }

The Above code results in something like this

What should i do so that i get the entire table row as a single entity to select.

Share Improve this question asked Aug 29, 2017 at 14:52 Nitish PhanseNitish Phanse 5621 gold badge9 silver badges17 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 4

You'll probably, unfortunately, need to manage the state of your radio buttons manually, as a controlled ponent.

Have the RadioButtonGroup include a call to an onChange function that stores the selected value:

handleChange: (event, value) => {
    this.setState({selectedButtonValue: value});
}

And then push that value to every RadioButtonGroup using the valueSelected property as such;

<RadioButtonGroup name="shipSpeed" defaultSelected="not_light" key={member.uuid}
    onChange={this.handleChange}
    valueSelected={this.state.selectedButtonValue}
>

I assume you are using "Enhanced Table" from material ui. If that's the case

replace

    if (selectedIndex === -1) {
      newSelected = newSelected.concat(selected, name);
    } else if (selectedIndex === 0) {
      newSelected = newSelected.concat(selected.slice(1));
    } else if (selectedIndex === selected.length - 1) {
      newSelected = newSelected.concat(selected.slice(0, -1));
    } else if (selectedIndex > 0) {
      newSelected = newSelected.concat(
        selected.slice(0, selectedIndex),
        selected.slice(selectedIndex + 1),
      );
    }

with

    if (selectedIndex === -1) {
      newSelected = [name];
    }

and replace

The Checkbox ponent with Radio ponent.

change this

<TableCell padding="checkbox">
    <Checkbox
     checked={isItemSelected}
     inputProps={{ 'aria-labelledby': labelId }}
     />
 </TableCell>

to this

<TableCell padding="checkbox">
     <Radio
      checked={isItemSelected}
      inputProps={{ 'aria-labelledby': labelId }}
      />
</TableCell>

You should be able to toggle between the radio buttons as the button only activates when new row is selected and it replaces the old selected state.

I am attaching the implementation of material ui enhanced table with radio button implementation. I did some tweak here and there. You can take a look.

import React from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
import { lighten, makeStyles } from '@material-ui/core/styles';
import Table from '@material-ui/core/Table';
import TableBody from '@material-ui/core/TableBody';
import TableCell from '@material-ui/core/TableCell';
import TableContainer from '@material-ui/core/TableContainer';
import TableHead from '@material-ui/core/TableHead';
import TablePagination from '@material-ui/core/TablePagination';
import TableRow from '@material-ui/core/TableRow';
import TableSortLabel from '@material-ui/core/TableSortLabel';
import Toolbar from '@material-ui/core/Toolbar';
import Typography from '@material-ui/core/Typography';
import Paper from '@material-ui/core/Paper';
import Radio from '@material-ui/core/Radio';
// import IconButton from '@material-ui/core/IconButton';
// import Tooltip from '@material-ui/core/Tooltip';
// import FormControlLabel from '@material-ui/core/FormControlLabel';
// import Switch from '@material-ui/core/Switch';
// import DeleteIcon from '@material-ui/icons/Delete';
// import FilterListIcon from '@material-ui/icons/FilterList';

function createData(name, calories, fat, carbs, protein) {
  return { name, calories, fat, carbs, protein };
}

const rows = [
  createData('Cupcake', 305, 3.7, 67, 4.3),
  createData('Donut', 452, 25.0, 51, 4.9),
  createData('Eclair', 262, 16.0, 24, 6.0),
  createData('Frozen yoghurt', 159, 6.0, 24, 4.0),
  createData('Gingerbread', 356, 16.0, 49, 3.9),
  createData('Honeyb', 408, 3.2, 87, 6.5),
  createData('Ice cream sandwich', 237, 9.0, 37, 4.3),
  createData('Jelly Bean', 375, 0.0, 94, 0.0),
  createData('KitKat', 518, 26.0, 65, 7.0),
  createData('Lollipop', 392, 0.2, 98, 0.0),
  createData('Marshmallow', 318, 0, 81, 2.0),
  createData('Nougat', 360, 19.0, 9, 37.0),
  createData('Oreo', 437, 18.0, 63, 4.0),
];

function descendingComparator(a, b, orderBy) {
  if (b[orderBy] < a[orderBy]) {
    return -1;
  }
  if (b[orderBy] > a[orderBy]) {
    return 1;
  }
  return 0;
}

function getComparator(order, orderBy) {
  return order === 'desc'
    ? (a, b) => descendingComparator(a, b, orderBy)
    : (a, b) => -descendingComparator(a, b, orderBy);
}

function stableSort(array, parator) {
  const stabilizedThis = array.map((el, index) => [el, index]);
  stabilizedThis.sort((a, b) => {
    const order = parator(a[0], b[0]);
    if (order !== 0) return order;
    return a[1] - b[1];
  });
  return stabilizedThis.map((el) => el[0]);
}

const headCells = [
  { id: 'name', numeric: false, disablePadding: true, label: 'Dessert (100g serving)' },
  { id: 'calories', numeric: true, disablePadding: false, label: 'Calories' },
  { id: 'fat', numeric: true, disablePadding: false, label: 'Fat (g)' },
  { id: 'carbs', numeric: true, disablePadding: false, label: 'Carbs (g)' },
  { id: 'protein', numeric: true, disablePadding: false, label: 'Protein (g)' },
];

function EnhancedTableHead(props) {
  const { classes, order, orderBy, onRequestSort } = props;
  const createSortHandler = (property) => (event) => {
    onRequestSort(event, property);
  };

  return (
    <TableHead>
      <TableRow>
        <TableCell padding="checkbox">
        </TableCell>
        {headCells.map((headCell) => (
          <TableCell
            key={headCell.id}
            align={headCell.numeric ? 'right' : 'left'}
            padding={headCell.disablePadding ? 'none' : 'default'}
            sortDirection={orderBy === headCell.id ? order : false}
          >
            <TableSortLabel
              active={orderBy === headCell.id}
              direction={orderBy === headCell.id ? order : 'asc'}
              onClick={createSortHandler(headCell.id)}
            >
              {headCell.label}
              {orderBy === headCell.id ? (
                <span className={classes.visuallyHidden}>
                  {order === 'desc' ? 'sorted descending' : 'sorted ascending'}
                </span>
              ) : null}
            </TableSortLabel>
          </TableCell>
        ))}
      </TableRow>
    </TableHead>
  );
}

EnhancedTableHead.propTypes = {
  classes: PropTypes.object.isRequired,
  onRequestSort: PropTypes.func.isRequired,
  onSelectAllClick: PropTypes.func.isRequired,
  order: PropTypes.oneOf(['asc', 'desc']).isRequired,
  orderBy: PropTypes.string.isRequired,
  rowCount: PropTypes.number.isRequired,
};

const useToolbarStyles = makeStyles((theme) => ({
  root: {
    paddingLeft: theme.spacing(2),
    paddingRight: theme.spacing(1),
  },
  highlight:
    theme.palette.type === 'light'
      ? {
          color: theme.palette.secondary.main,
          backgroundColor: lighten(theme.palette.secondary.light, 0.85),
        }
      : {
          color: theme.palette.text.primary,
          backgroundColor: theme.palette.secondary.dark,
        },
  title: {
    flex: '1 1 100%',
  },
}));

const EnhancedTableToolbar = (props) => {
  const classes = useToolbarStyles();
  const { numSelected } = props;

  return (
    <Toolbar
      className={clsx(classes.root, {
        [classes.highlight]: numSelected.length > 0,
      })}
    >
      {numSelected.length > 0 ? (
        <Typography className={classes.title} color="inherit" variant="subtitle1" ponent="div">
          {numSelected}
        </Typography>
      ) : (
        <Typography className={classes.title} variant="h6" id="tableTitle" ponent="div">
          Nutrition
        </Typography>
      )}

      {/* {numSelected.length > 0 ? (
        <Tooltip title="Delete">
          <IconButton aria-label="delete">
            <DeleteIcon />
          </IconButton>
        </Tooltip>
      ) : (
        <Tooltip title="Filter list">
          <IconButton aria-label="filter list">
            <FilterListIcon />
          </IconButton>
        </Tooltip>
      )} */}
    </Toolbar>
  );
};

EnhancedTableToolbar.propTypes = {
  numSelected: PropTypes.string.isRequired,
};

const useStyles = makeStyles((theme) => ({
  root: {
    width: '100%',
  },
  paper: {
    width: '100%',
    marginBottom: theme.spacing(2),
  },
  table: {
    minWidth: 750,
  },
  visuallyHidden: {
    border: 0,
    clip: 'rect(0 0 0 0)',
    height: 1,
    margin: -1,
    overflow: 'hidden',
    padding: 0,
    position: 'absolute',
    top: 20,
    width: 1,
  },
}));

export default function EnhancedTableWithRadio() {
  const classes = useStyles();
  const [order, setOrder] = React.useState('asc');
  const [orderBy, setOrderBy] = React.useState('calories');
  const [selected, setSelected] = React.useState('');
  const [page, setPage] = React.useState(0);
  // const [dense, setDense] = React.useState(false);
  const [rowsPerPage, setRowsPerPage] = React.useState(5);

  const handleRequestSort = (event, property) => {
    const isAsc = orderBy === property && order === 'asc';
    setOrder(isAsc ? 'desc' : 'asc');
    setOrderBy(property);
  };


  const handleClick = (event, name) => {
    let newSelected = selected;

    if (name !== selected) {
      newSelected = name;
    }
    setSelected(newSelected);
  };

  const handleChangePage = (event, newPage) => {
    setPage(newPage);
  };

  const handleChangeRowsPerPage = (event) => {
    setRowsPerPage(parseInt(event.target.value, 10));
    setPage(0);
  };

  // const handleChangeDense = (event) => {
  //   setDense(event.target.checked);
  // };

  const isSelected = (name) => selected.indexOf(name) !== -1;

  const emptyRows = rowsPerPage - Math.min(rowsPerPage, rows.length - page * rowsPerPage);

  return (
    <div className={classes.root}>
      <Paper className={classes.paper}>
      <EnhancedTableToolbar numSelected={selected} />
        <TableContainer>
          <Table
            className={classes.table}
            aria-labelledby="tableTitle"
            // size={dense ? 'small' : 'medium'}
            size = "medium"
            aria-label="enhanced table"
          >
            <EnhancedTableHead
              classes={classes}
              order={order}
              orderBy={orderBy}
              onRequestSort={handleRequestSort}
              rowCount={rows.length}
            />
            <TableBody>
              {stableSort(rows, getComparator(order, orderBy))
                .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
                .map((row, index) => {
                  const isItemSelected = isSelected(row.name);
                  const labelId = `enhanced-table-checkbox-${index}`;

                  return (
                    <TableRow
                      hover
                      onClick={(event) => handleClick(event, row.name)}
                      role="checkbox"
                      aria-checked={isItemSelected}
                      tabIndex={-1}
                      key={row.name}
                      selected={isItemSelected}
                    >
                      <TableCell padding="checkbox">
                        <Radio
                          checked={isItemSelected}
                          inputProps={{ 'aria-labelledby': labelId }}
                        />
                      </TableCell>
                      <TableCell ponent="th" id={labelId} scope="row" padding="none">
                        {row.name}
                      </TableCell>
                      <TableCell align="right">{row.calories}</TableCell>
                      <TableCell align="right">{row.fat}</TableCell>
                      <TableCell align="right">{row.carbs}</TableCell>
                      <TableCell align="right">{row.protein}</TableCell>
                    </TableRow>
                  );
                })}
              {emptyRows > 0 && (
                <TableRow style={{ height: 53 * emptyRows }}>
                {/* <TableRow style={{ height: (dense ? 33 : 53) * emptyRows }}> */}
                
                  <TableCell colSpan={6} />
                </TableRow>
              )}
            </TableBody>
          </Table>
        </TableContainer>
        <TablePagination
          rowsPerPageOptions={[5, 10]}
          ponent="div"
          count={rows.length}
          rowsPerPage={rowsPerPage}
          page={page}
          onChangePage={handleChangePage}
          onChangeRowsPerPage={handleChangeRowsPerPage}
        />
      </Paper>
      {/* <FormControlLabel
        control={<Switch checked={dense} onChange={handleChangeDense} />}
        label="Dense padding"
      /> */}
    </div>
  );
}

I had the same problem using a Radio button ponent inside a cell from a Table, both ponents from MaterialUi. I resolve like this:

This is my handleChange function to select de value of the Row.id that i use for my app


handleChange(field, event) {
        this.setState({[field] : event.target.value});
    }

And in my Table ponent i just use the "Radio" ponent without a "RadioButtonGoup" ponent. And use a condition in the "checked" prop of the "Radio" ponent to show it as checked or not.


<Table aria-label="simple table">
   <TableHead>
      <TableRow>
         <TableCell align="center">Selecciona</TableCell>
         <TableCell>Brand</TableCell>
         <TableCell align="center">Tarjetahabiente</TableCell>
         <TableCell align="center">Terminación</TableCell>
         <TableCell align="center">Expira</TableCell>
         <TableCell align="center">Eliminar</TableCell>
      </TableRow>
   </TableHead>
   <TableBody>
      {rows.map(row => (
      <TableRow key={row.id}>
         <TableCell ponent="th" scope="row">
            <Radio
               value={row.id}
               defaultSelected={false}
               checked={row.id != this.state.paymentSourceId ? false : true}
               onChange={this.handleChange.bind(this, 'paymentSourceId')}
            />
         </TableCell>
         <TableCell align="center">{row.brand}</TableCell>
         <TableCell align="center">{row.name}</TableCell>
         <TableCell align="center">{row.last4}</TableCell>
         <TableCell align="center">{row.exp_month}/{row.exp_year}</TableCell>
         <TableCell align="center">
             <IconButton 
                 aria-label="delete" 
                 color="primary" 
                 onClick={()=>this.handleDelete(this.state.paymentSourceId)}>
                   <DeleteIcon />
              </IconButton>
         </TableCell>
      </TableRow>
      ))}
   </TableBody>
</Table>

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1741709590a4361955.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信