繁体   English   中英

在表格的行单元格内添加材质 UI 的单选按钮,

[英]Adding a Radio button of material UI inside row cell in table,

我的设计目前是这样的餐桌设计

我正在使用 Material UI 的单选按钮,我想让每一行只能选择一次。 当我添加一个<RadioButton>组件时,我可以选择它,但是我无法在行之间切换

  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>

    );
  }

上面的代码结果是这样的结果

我应该怎么做才能将整个表格行作为单个实体进行选择。

不幸的是,您可能需要手动管理单选按钮的状态,作为受控组件。

RadioButtonGroup包含对存储所选值的onChange函数的调用:

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

然后使用valueSelected属性将该值推送到每个 RadioButtonGroup ;

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

我假设您正在使用材料 ui 中的“增强型表格”。 如果是这样的话

替换

 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), ); }

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

并替换

带有 Radio 组件的 Checkbox 组件。

改变这个

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

对此

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

您应该能够在单选按钮之间切换,因为该按钮仅在选择新行并替换旧的选定状态时才会激活。

我正在附上带有单选按钮实现的材料 ui 增强表的实现。 我在这里和那里做了一些调整。 你可以看看。

 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('Honeycomb', 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, comparator) { const stabilizedThis = array.map((el, index) => [el, index]); stabilizedThis.sort((a, b) => { const order = comparator(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" component="div"> {numSelected} </Typography> ) : ( <Typography className={classes.title} variant="h6" id="tableTitle" component="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 component="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]} component="div" count={rows.length} rowsPerPage={rowsPerPage} page={page} onChangePage={handleChangePage} onChangeRowsPerPage={handleChangeRowsPerPage} /> </Paper> {/* <FormControlLabel control={<Switch checked={dense} onChange={handleChangeDense} />} label="Dense padding" /> */} </div> ); }

我在表格的单元格内使用单选按钮组件时遇到了同样的问题,这两个组件都来自 MaterialUi。 我是这样解决的:

这是我的 handleChange 函数,用于选择我用于我的应用程序的 Row.id 的值


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

在我的 Table 组件中,我只使用了没有“RadioButtonGoup”组件的“Radio”组件。 并在“Radio”组件的“checked”道具中使用一个条件来显示它是否被选中。


<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 component="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>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM