Amir
Amir

Reputation: 441

React Material-UI How can I add a checkbox which is separate from table row click

I want to differentiate between a checkbox click and a row click.

For example, I want this behavior, when I click the checkbox, only the checkbox is checked and when I click the row, only the row is selected but the checkbox is not selected. How can I achieve this?

Below is my code

handleClick = (row) => {
var self = this;
var currentlist = self.state.routelist;

let newarray = [...this.state.routelist];

if (newarray[row].isselected === true) {
  newarray[row].isselected = false;
} else if (newarray[row].isselected === false) {
  newarray[row].isselected = true;
}

self.setstate({ routelist: newarray });

if (!isnan(row)) 
{
    var pos = 
    {
      routeid: currentlist[row].routeid,
      isvisible: currentlist[row].isselected
    };

    var param = {
      receiver: "event_map",
      command: "show_route",
      data: pos
    };

    //console.log("show_route: " + param.data.routeid + " visible: " + param.data.isvisible);
    this.msgdispatcher.triggermessagedispatcher(param);

    //zoom to route
    if (currentlist[row].routeid != null ||currentlist[row].routeid != undefined) 
    {
      var param = {
        receiver: "event_map",
        command: "zoom_to_route",
        data: currentlist[row].routeid
      };

      //console.log("zoom_to_route: routeid=" + param.data);
      this.msgdispatcher.triggermessagedispatcher(param);
    }
}
}

And here is the render method

render() {
return (
  <div style={{ padding: "0px" }}>
    <div style={{ padding: "0px" }}>
    <Table  
        onCellClick={this.handleClick}
        height={window.innerHeight}
        multiSelectable={this.state.multiSelectable}
        selectable={this.state.selectable}
      >
        <TableBody 
          displayRowCheckbox={this.state.displayRowCheckbox}
          showRowHover={this.state.showRowHover}
          deselectOnClickaway={this.state.deselectOnClickaway}
          >
          {this.state.routeList.map((row, index) => (
            <TableRow
              key={index}
              style={{ backgroundColor: row.DistressColor }}
              selected={this.state.routeList[index].isSelected}
            >
              <TableRowColumn style={{ padding: "0px" }}>
                <ListItem
                  style={{ height: "80px" }}
                  primaryText={row.Description}
                  secondaryText={
                    <div>
                      <div>
                        {"Direction : " + row.EntryDirection + " > " + row.ExitDirection}
                      </div>
                      <div>{"Distance (meter) : " + row.Distance}</div>
                    </div>
                  }
                  secondaryTextLines={5}
                />
              </TableRowColumn>
            </TableRow>
          ))}
        </TableBody>
      </Table>
      <hr />
    </div>
  </div>
);
}

Upvotes: 3

Views: 3538

Answers (1)

keikai
keikai

Reputation: 15146

Method_#1

You can use the child component of ListItem: ListItemSecondaryAction

It provides the additional action element where you can use to place your buttons, which would not be affected by the main ListItem click event.

You can pass that as props named children to ListItem, but notice:

If a ListItemSecondaryAction is used it must be the last child.


Refer:


Sample source:

<ListItem alignItems="flex-start" className={classes.listUnit} key={book.isbn}>
  <ListItemAvatar>
    <Avatar alt="Remy Sharp" src={url} />
  </ListItemAvatar>
  <ListItemText
    primary={book.title}
    secondary={
      <>...</>
    }
  />
  <ListItemSecondaryAction>
    <Tooltip title="Add to order" aria-label="add">
      <IconButton edge="end" aria-label="comments">
        <AddIcon />
      </IconButton>
    </Tooltip>
  </ListItemSecondaryAction>
</ListItem>;

Method_#2

If you don't want to use Material-UI internal solution.

You can simply add some customized processes in your parent event handler callback.

Use stopPropagation() to prevent child event, then add a separate click event on child would work.

The stopPropagation() method of the Event interface prevents further propagation of the current event in the capturing and bubbling phases.

event.stopPropagation();

Upvotes: 1

Related Questions