Material-ui: Question: Is there a way to keep the snackbar on the page?

Created on 6 Jan 2016  路  13Comments  路  Source: mui-org/material-ui

If a user clicks anywhere on the page (not the snackbar), this currently closes the snackbar. Is there a way to prevent this?

Thanks! (Great project btw!)

question

Most helpful comment

Alright, this is the solution:

import React from 'react';
import Snackbar from 'material-ui/lib/snackbar';
import TextField from 'material-ui/lib/text-field';
import RaisedButton from 'material-ui/lib/raised-button';

export default class SnackbarExampleSimple extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      autoHideDuration: 0,
      message: 'Event added to your calendar',
      open: false,
    };
  }

  handleTouchTap = () => {
    this.setState({
      open: true,
    });
  }

  handleActionTouchTap = () => {
    alert('We removed the event from your calendar.');
  }

  handleChangeDuration = (event) => {
    const value = event.target.value;
    this.setState({
      autoHideDuration: value.length > 0 ? parseInt(value) : 0,
    });
  }

  handleRequestClose = (reason) => {
   if (reason !== 'clickaway') {
      this.setState({
        open: false,
      });
    }
  }

  render() {
    return (
      <div>
        <RaisedButton
          onTouchTap={this.handleTouchTap}
          label="Add to my calendar"
        />
        <br />
        <TextField
          floatingLabelText="Auto Hide Duration in ms"
          value={this.state.autoHideDuration}
          onChange={this.handleChangeDuration}
        />
        <Snackbar
          open={this.state.open}
          message={this.state.message}
          action="undo"
          autoHideDuration={this.state.autoHideDuration}
          onActionTouchTap={this.handleActionTouchTap}
          onRequestClose={this.handleRequestClose}
        />
      </div>
    );
  }
}

export default SnackbarExampleSimple;

All 13 comments

The snackbar is controlled by the open property in the latest release. So yes, and that's straigthforward.

@DavidLGoldberg I don't think you can use autoHideDuration, but not have it close when you click outside the Snackbar. If that's the issue, you would need to create your own timer to control open.

Hmm, ok interesting. Not _that_ crucial at the moment for me. Thanks!

I don't think you can use autoHideDuration

Yes, you can. onRequestClose is called with an additional parameter: reason.
It can be:

  • timeout (autoHideDuration)
  • or clickaway

Ah, I tried to do the onRequestClose, didn't look deep enough thanks!

Would some kind of preventDefault()? or return false be the trick here? Not exactly sure how to use it. (I'm a react n00b unfortunately)

Alright, this is the solution:

import React from 'react';
import Snackbar from 'material-ui/lib/snackbar';
import TextField from 'material-ui/lib/text-field';
import RaisedButton from 'material-ui/lib/raised-button';

export default class SnackbarExampleSimple extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      autoHideDuration: 0,
      message: 'Event added to your calendar',
      open: false,
    };
  }

  handleTouchTap = () => {
    this.setState({
      open: true,
    });
  }

  handleActionTouchTap = () => {
    alert('We removed the event from your calendar.');
  }

  handleChangeDuration = (event) => {
    const value = event.target.value;
    this.setState({
      autoHideDuration: value.length > 0 ? parseInt(value) : 0,
    });
  }

  handleRequestClose = (reason) => {
   if (reason !== 'clickaway') {
      this.setState({
        open: false,
      });
    }
  }

  render() {
    return (
      <div>
        <RaisedButton
          onTouchTap={this.handleTouchTap}
          label="Add to my calendar"
        />
        <br />
        <TextField
          floatingLabelText="Auto Hide Duration in ms"
          value={this.state.autoHideDuration}
          onChange={this.handleChangeDuration}
        />
        <Snackbar
          open={this.state.open}
          message={this.state.message}
          action="undo"
          autoHideDuration={this.state.autoHideDuration}
          onActionTouchTap={this.handleActionTouchTap}
          onRequestClose={this.handleRequestClose}
        />
      </div>
    );
  }
}

export default SnackbarExampleSimple;

Yes, you can. onRequestClose is called with an additional parameter: reason.

Oh, that's good to know. That needs to be documented...

Thanks so much for the lightning fast help guys :+1:

That needs to be documented...

I agree, let's wait https://github.com/callemall/material-ui/issues/2417 to be resolved before closing this issue.

I've updated the docs in #2813, which can always be used as the text for #2417 if that gets resolved.

I couldn't get this working with onRequestClose.
Instead I used ClickAwayListenerProps as so:

<MuiSnackbar
  // ...
  ClickAwayListenerProps={{ onClickAway: () => null }}
 >

Here are the docs for ClickAwayListnerProps for reference.

I couldn't get this working with onRequestClose.

I believe this is just onClose now. From the docs:

_function(event: object, reason: string) => void
event: The event source of the callback.
reason: Can be: "timeout" (autoHideDuration expired), "clickaway"._

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sys13 picture sys13  路  3Comments

rbozan picture rbozan  路  3Comments

ryanflorence picture ryanflorence  路  3Comments

zabojad picture zabojad  路  3Comments

ericraffin picture ericraffin  路  3Comments