Material-ui: [Docs] The RaisedButton example for a file-type input does not always work on click

Created on 14 Mar 2016  路  13Comments  路  Source: mui-org/material-ui

Main Issue: The label is blocking the triggering of the input

Go to the docs for the RaisedButton here, and try clicking the "Choose an Image" button under _Complex Examples_. If you click right on the label text, nothing happens. However, if you click near the edges of the button, it works as expected.

If anyone was actually trying to copy this example to make their own file input button, they might be confused. The way I have chosen to fix this is to pass in labelStyle={{pointerEvents: 'none'}} into the RaisedButton component so that the user's clicks register _through_ the button label itself. Any better suggestions are welcomed.

Sub-Issue: Lack of delay to allow user to see feedback ripple

Another sub-issue I wanted to talk about was about granting a 200ms delay for this button. This might be a little out of scope, but if you look at the menu component, you'll see that there is a delay added in so that the user can see the ripple effect play out for a bit before actually triggering the action that they want. Would be good to have it for this component as well.

bug 馃悰

Most helpful comment

FYI here is a workaround that works with MUI>1.0.0

            <input
              id="file"
              type="file"
              onChange={this.handleReadImportedFile}
              style={{
                width: 0,
                height: 0,
                opacity: 0,
                overflow: 'hidden',
                position: 'absolute',
                zIndex: 1,
              }}
            />
            <Button component="label" htmlFor="file">
              Choose a file
            </Button>

All 13 comments

The main issue also happened in IE11, Nothing happens except clicking near the left top corner.
It might no a doc issue, but RaisedButton cant support it very well.

@yinickzhou You can add z-index on file input and set it higher such as 100

I prefer the Codrops way of styling file inputs: http://tympanus.net/codrops/2015/09/15/styling-customizing-file-inputs-smart-way/

That being said, it is slightly more verbose than the current implementation. Would this be a little much for the Material-UI docs?

Here's how I do it personally for a project I'm currently working on:

  1. First hide the input element:

stylus .input-file width 0.1px height 0.1px opacity 0 overflow hidden position absolute z-index -1

  1. Now write the markup:

jsx <div> <input type="file" name="file" id="file" className="input-file" onChange={this.handleFileChange.bind(this)} /> <label htmlFor="file" ref={x => this._inputLabel = x}> <RaisedButton label="Choose a File" onTouchTap={this.handleChooseFileClick.bind(this)}/> </label> </div>

  1. Write the handler to click the label for me:

jsx handleChooseFileClick() { setTimeout(() => { this._inputLabel.click(); }, 200); }

Note 1: The CSS is in Stylus (a minimalistic CSS pre-processor).
Note 2: I added a 200 millisecond delay so the user can see the ripple on the button.

On second thought, this is kind of overkill for the Material-UI documentation. I propose we use a different example instead. After all, we are only showcasing the button component, we are not trying to write a tutorial for the various ways to utilize it fully and make it compatible across as many browsers as possible.

@adrianmc I like that setup you've done

@adrianmc You can have a look at the alpha release. The issue was more or less solved (not perfect).
If you want to improve it, that's welcomed :+1:.

@oliviertassinari That new one looks like it works as expected when clicked! The only issue seems to be the lack of a proper cursor when hovering over the top left corner where the shadow element resides.

Unfortunately, I haven't been able to come up with way to make it behave "perfectly" while keeping the code concise. My example above performs "perfectly" but is obviously far from ideal since it requires a separate click handler. Perhaps I'll just leave it for someone else to figure out.

@adrianmc, @oliviertassinari - are you happy to close this in that case?

@oliviertassinari : Can this be closed?

@tintin1343 - two thumbs up says yes. 馃槃

Maybe a more concise way of doing it is setting the containerElement prop on the RaisedButton to be something more suited to having an input element as a child

<RaisedButton
  containerElement='label' // <-- Just add me!
  label='My Label'>
    <input type="file" />
</RaisedButton>

@Thomas101 right, sementicaly speaking, that looks better.
Do you want to submit a PR? (https://github.com/callemall/material-ui/blob/master/docs/src/app/components/pages/components/RaisedButton/ExampleComplex.js#L24)

FYI here is a workaround that works with MUI>1.0.0

            <input
              id="file"
              type="file"
              onChange={this.handleReadImportedFile}
              style={{
                width: 0,
                height: 0,
                opacity: 0,
                overflow: 'hidden',
                position: 'absolute',
                zIndex: 1,
              }}
            />
            <Button component="label" htmlFor="file">
              Choose a file
            </Button>
Was this page helpful?
0 / 5 - 0 ratings

Related issues

sys13 picture sys13  路  3Comments

pola88 picture pola88  路  3Comments

mb-copart picture mb-copart  路  3Comments

newoga picture newoga  路  3Comments

anthony-dandrea picture anthony-dandrea  路  3Comments