How to handle speed dial actions using material ui?

6.2k views Asked by At

I have three actions supporting my SpeedDialAction, however when I try to log the event of the individual actions onClick, I get undefined.

I have tried using different functions as actions, also tried arrow function syntax in the method call

onClick={e => action.action(e)}

and

onClick={action.action}

The actions:

const actions = [
    { icon: <Add />, name: 'Product', action: handleDialogOpen },
    { icon: <Add />, name: 'Addon', action: handleDialogOpen },
    { icon: <Label />, name: 'Tag', action: handleDialogOpen }
  ]

The SpeedDial:

<SpeedDial
          ariaLabel='SpeedDial example'
          className={classes.speedDial}
          icon={<SpeedDialIcon />}
          onBlur={handleClose}
          onClick={handleClick}
          onClose={handleClose}
          onFocus={handleOpen}
          onMouseEnter={handleOpen}
          onMouseLeave={handleClose}
          open={open}
        >
          {actions.map(action => (
            <SpeedDialAction
              tooltipOpen
              key={action.name}
              icon={action.icon}
              tooltipTitle={action.name}
              onClick={action.action}
            />
          ))}
        </SpeedDial>

handleDialogOpen simply tries to log the event

I expect the output being an event object, not undefined.

3

There are 3 answers

1
Neo On

You can define an extra object item in actions array.

const actions = [
    { icon: <Add />, name: 'Product', action: handleDialogOpen, operation: 'product'},
    { icon: <Label />, name: 'Tag', action: handleDialogOpen , operation: 'tag' }
  ]

Now you need to call a handler function and pass the operation value as a parameter:

//handler function
 function handleClick (e,operation){
   e.preventDefault();
   if(operation=="product"){
     // do something 
   }else if(operation=="tag"){
     //do something else
   }
   setOpen(!open);// to close the speed dial, remove this line if not needed.
 };
<SpeedDial
          ariaLabel='SpeedDial example'
          className={classes.speedDial}
          icon={<SpeedDialIcon />}
          onBlur={handleClose}
          onClick={handleClick}
          onClose={handleClose}
          onFocus={handleOpen}
          onMouseEnter={handleOpen}
          onMouseLeave={handleClose}
          open={open}
        >
          {actions.map(action => (
            <SpeedDialAction
              tooltipOpen
              key={action.name}
              icon={action.icon}
              tooltipTitle={action.name}
              onClick={(e) => {
                      handleClick(e.action.operation)
                 }}
            />
          ))}
        </SpeedDial>
1
Juan Pablo On

Here is a working code on Typescript based on Material UI 5.13.14 https://mui.com/material-ui/react-speed-dial/

Optional: Define menuOptions

enum menuOptions {
  'MENU',
  'COMPARE',
  'SHARE',
}

Define your actions. Make shure to add the operation field.

const actions = [
  { icon: <List />, name: 'Menú', operation: menuOptions.MENU },
  { icon: <Compare />, name: 'Comparar', operation: menuOptions.COMPARE },
  { icon: <Share />, name: 'Compartir', operation: menuOptions.SHARE },
]

Now create the SpeedDial component. Make sure to add onClick={(e) => { handleClick(e, action.operation) }} in SpeedDialAction

  return (
    <>
      <SpeedDial
        ariaLabel="Menu"
        sx={{
          position: 'fixed',
          bottom: 20,
          right: 20,
        }}
        onClick={handleOpen}
        open={open}
        icon={<SpeedDialIcon />}
        direction="up"
      >
        {actions.map((action) => (
          <SpeedDialAction
            key={action.name}
            icon={action.icon}
            tooltipTitle={action.name}
            onClick={(e) => {
              handleClick(e, action.operation)
            }}
          />
        ))}
      </SpeedDial>
    </>
  )
}
0
José Rafael Moro Galindo On

Also you may do this. Set your handler that closes your modal. And in the onClick, set an anonymous activating the action function and closing the modal. :

const handleClose = () => setOpen(false);


<SpeedDial
      ariaLabel='SpeedDial example'
      className={classes.speedDial}
      icon={<SpeedDialIcon />}
      onBlur={handleClose}
      onClick={handleClick}
      onClose={handleClose}
      onFocus={handleOpen}
      onMouseEnter={handleOpen}
      onMouseLeave={handleClose}
      open={open}
    >
      {actions.map(action => (
        <SpeedDialAction
          tooltipOpen
          key={action.name}
          icon={action.icon}
          tooltipTitle={action.name}
          onClick={() => {
            action.action()
            handleClose()  }}
        />
      ))}
    </SpeedDial>