Material-ui: [FlatButton] La entrada de archivo no funciona con el botón.

Creado en 15 may. 2015  ·  27Comentarios  ·  Fuente: mui-org/material-ui

Con este...

<FlatButton primary={true} label="Choose an Image">
  <input type="file" id="imageButton"></input>
</FlatButton>

Termino con un botón que en realidad no representa un campo de entrada de archivo en el dom (al hacer clic en el botón no se abre el cuadro de diálogo del archivo).

Comentario más útil

Si alguien más se encuentra con este problema, descubrí que puede configurar containerElement en RaisedButton para que sea algo más adecuado para tener un elemento de entrada como elemento secundario. Por ejemplo una etiqueta ;-)

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

Todos 27 comentarios

En la versión 0.7.5.

@nschaubeck ¿Te funciona el botón del sitio de documentos?

@ hai-cea Sí, lo hace. Parecía que ni siquiera había un elemento <input> _en_ ​​DOM, como si el elemento del botón no representara a sus hijos.

Yo también tengo este problema. @nschaubeck ¿Alguna vez encontró una solución?

@e-monson En realidad no pude encontrar una solución.

¡esto funciona!
dejar estilos = {
ejemploImagenEntrada: {
cursor: 'puntero',
posición: 'absoluto',
arriba: '0',
abajo: '0',
derecha: '0',
izquierda: '0',
ancho: '100%',
opacidad: '0'
}
}

      <FlatButton label="Choose an Image" primary={true}>
        <input id="imageButton" style={styles.exampleImageInput} type="file"></input>
      </FlatButton>

@nikhildaga Eso solo funciona en Chrome, ya que colocar campos de entrada en botones no forma parte de la especificación W3C.

Una solución diferente es hacer que el botón solo active el evento de clic de un campo de entrada oculto.

handleChange: function(e){
  console.log(e.target.value)
},
_openFileDialog: function(){
  var fileUploadDom = React.findDOMNode(this.refs.fileUpload);
  fileUploadDom.click();
},
render: function() {
  return (
    <FlatButton
      label="Upload file"
      onClick={this._openFileDialog}/>
    <input
      ref="fileUpload"
      type="file" 
      style={{"display" : "none"}}
      onChange={this._handleChange}/>
  );
}

Veo que este problema aún no se ha solucionado correctamente...
La solución propuesta en el documento solo funciona en Chrome como dijo @Wofiel . (sigue siendo el caso en beta 15-0.2)

¿No sería mejor poder establecer como htmlFor en <FlatButton> (o <RaisedButton> ), establecer un Id en el archivo de entrada y eso es todo? No necesitarías activar el clic manualmente...
Intenté envolver el botón en la etiqueta, desafortunadamente, eso no funciona :(

Ahora mismo @Wofiel parece ser la mejor solución.

¿Por qué cerrar esto cuando no hay una solución nativa?

hola @Wofiel , ¿cómo sugieres usar esta técnica sin referencias en un componente sin estado?

@excalliburbd Puedes usar id y Jquery, eso debería funcionar

@Birssan dom manipulación en reaccionar? ¿Está bien?

Por lo general, no lo recomendaría, pero creo que desencadena un evento de clic que debería estar bien en este caso

@Wofiel Como se puede hacer con la version 15 de react?

@Wofiel con esta solución console.log(e.target.value) uno recibe
C:\rutafalsa\nombrearchivoimagen.png
Las mejores soluciones son
e.target.files[0]

Si alguien más se encuentra con este problema, descubrí que puede configurar containerElement en RaisedButton para que sea algo más adecuado para tener un elemento de entrada como elemento secundario. Por ejemplo una etiqueta ;-)

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

@Thomas101 ¡Gracias! Acabo de encontrar este problema y su solución parece funcionar.
Increíble :)

@ Thomas101 Gracias por el consejo. Esto resolvió mi problema también. El actual

Simplemente complementando la respuesta de @ Thomas101 , cuando declaro los componentes como su ejemplo, mi RaisedButton se representa con una entrada de archivo dentro. Para evitar esto, simplemente establezca el estilo de entrada del archivo en display: none . :)

<RaisedButton
  containerElement='label' // <-- Just add me!
  label='My Label'>
    <input type="file" style={{ display: 'none' }} />
</RaisedButton>

@andreluiz bajo qué circunstancias esto no funciona:

<RaisedButton label='My Label'>
    <input type="file" />
</RaisedButton>

No he podido encontrar un problema con el ejemplo del sitio de documentos, ¡pero claramente muchos otros tienen este problema!

¿Se supone que la entrada del archivo no se muestra con el código que proporcionó?

Eso es raro. En mi caso, representa una entrada de archivo dentro del botón material-ui.

@andreyluiz Sí, con el ejemplo del sitio de documentos (http://www.material-ui.com/#/components/raised-button) no hay <input> visibles. ¿Con qué navegador y versión estás probando?

La última versión de Chrome.

Estoy de acuerdo con @andreluiz , el también se muestra, pero con un style={{display: 'none'}} , ¡funciona a las mil maravillas!

tl; dr

<RaisedButton
  containerElement="label"
  icon={<Icons.FileUpload />} // material-ui-icons
  labelColor="white"
  primary
  style={{ minWidth: 40, width: 40 }}>
  <input
    onChange={e => this.upload(e.target.files[0])}
    style={{ display: 'none' }}
    type="file"
  />
</RaisedButton>

La solución anterior ya no parece funcionar. Estoy usando la nueva rama beta v1 y no me funciona lo siguiente

                        <Button dense
                                containerElement="label"
                                label="label">
                            <input
                                onChange={e => this.upload(e.target.files[0])}
                                style={{display: 'none'}}
                                type="file"
                            />
                        </Button>

Me sale el siguiente error en la consola:

Warning: React does not recognize the `containerElement` prop on a DOM element.
If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `containerelement` instead.
If you accidentally passed it from a parent component, remove it from the DOM element.

¿Alguien sabe una solución? De todos modos, ¿no debería admitirse de forma nativa un caso de uso tan común? (de una manera no hacky)

@AdityaAnand1 el siguiente código debería funcionar

<Button
            raised
            component="label" <---- use component instead of containerElement
            color="primary"
            className={buttonClassname}
            disabled={this.state.loading}
            onClick={this.handleButtonClick}
          >
            {'Upload'}
            <FileUpload className={classes.rightIcon} />
            <input
              onChange={e => console.log(e.target.files[0])}
              style={{ display: 'none' }}
              type="file"
            />
</Button>
¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

ryanflorence picture ryanflorence  ·  3Comentarios

iamzhouyi picture iamzhouyi  ·  3Comentarios

chris-hinds picture chris-hinds  ·  3Comentarios

revskill10 picture revskill10  ·  3Comentarios

TimoRuetten picture TimoRuetten  ·  3Comentarios