| Dando estilos a un input type file |
¿Cúantas veces has hecho un formulario preciosamente "stylado" pero te le ha jodido un input del tipo file? Yo en una ocasión me encontré con ese problema, y aunque no hay forma xhtml válida de dar estilo a un input de tipo file, si que hay formas, no estándares de simularlo, eso es lo que quiero explicar hoy. Supongamos que tenemos este formulario: ![]() Esta fue una de las primeras versiones de mi web, jugando con estilos vacíos hará un año o así. Queda feo, a pesar de ser estilos muy simples los usados, como empieces a meter sombras o "efectos" bonitos a base de imágenes te quedará un formulario horrendo al tener un input file. Veamos los pasos para solucionarlo de modo casero: Primero, meter el input file en una capa invisible, pero no por la propiedad hidden, sino por la opacidad en los estilos: <div class="caparchivo"> <input type="file" id="archivo" name="Archivo" class="archivo" /> </div> Ahora veamos el estilo "archvo": input.archivo { position: relative; text-align: left; -moz-opacity:0; filter:alpha(opacity: 0); opacity: 0; z-index: 2; } Bueno, ya tenemos nuestra capa "invisible", ahora proseguiremos. Crearemos otra capa, donde meteremos un input text normalito que si cogerá nuestros estilos: <div class="archivofalso"> <input id="nuevoarchivo" /> </div> Ahora veremos el estilo "archivofalso": { position: relative; text-align: left; -moz-opacity:0; filter:alpha(opacity: 0); opacity: 0; z-index: 2; } Con esto, estará "encima" de nuestro input file, a pesar de este ser invisible, de este modo podremos escribir en nuestro input text. Ahora el botón, podemos usar un botón, pero aconsejo una imagen y javascript: <div class="examinar"> <img src="imagenes/examinar_normal.jpg" id="examinar" /> </div> Veamos el estilo "examinar": div.examinar { position: relative; top: 0px; left: 0px; z-index: 1; } Bien, esta imagen, realmente aparecerá debajo del botón de Examinar, solo que este al ser "transparente" dejara ver la imagen, al pulsar la imagen, realmente pulsamos el botón "Examinar..." del input file, solo que al ser transparente parece que pulsemos la imagen. Con esto básicamente está todo arreglado, mejoras: 1.- Meter en una tabla de una fila y dos columnas, en la primera columna, la capa "archivofalso" con su input y en la segunda la capa "examinar" con su imagen/botón, ponerles un valign="top" o algo similar para que no descuadren. 2.- Comportamientos, queremos que al seleccionar un archivo se modifique en el cuadro de texto falso: onChange= "getElementById('nuevoarchivo').value=getElementById('archivo').value;" Con eso conseguiremos que el usuario vea la ruta en el cuadro. Nuestro archivo subir.php o el que tenga el código encargado de subir el archivo no hará falta modificarle, ya que realmente cogerá el archivo del input file de siempre, lo que hacemos es para que quede bonito. 3.- Que parezca que pulso la imagen: Es fácil: Pondremos los dos comportamientos siguientes en el input file: onMouseDown = "if(event.button==0){getElementById('examinar').src='imagenes/examinar_sobre.jpg'};" onMouseUp = "if(event.button==0){getElementById('examinar').src='imagenes/examinar_normal.jpg'};" Controlarán que se pulse el botón derecho o se suelte para cambiar la imagen. En mi ejemplo, el comportamiento de la imagen es como el de un botón, se hunde de la misma manera que los botones de mi css. 4.- Queremos que si cambiamos la ruta o la escribimos nosotros manualmente, cambie también en el input file, luego haremos lo mismo que en 2 pero a la inversa: onChange = "getElementById('archivo').value=getElementById('nuevoarchivo').value;" 5.- Ocurren problemas, puesto que en ocasiones, si la ruta la copiamos y pegamos y después damos a enviar, no hará el onchange correctamente, esto se soluciona poninedo un onclick en el submit: onClick = "getElementById('archivo').value=getElementById('nuevoarchivo').value;" Bien, el resultado es el siguiente: ![]() Si la capa de examinar no fuese transparente veríamos esto: ![]() Si la imagen del "botón" examinar fuese más grande, veríamos que está detrás: ![]() Ya apreciamos que está de la forma: Cuadro de texto falso. Input type file. Imagen o botón falso de examinar. Colocado de tal manera que de el pego. El código que tengo yo, enlazando todo lo anterior sería: <br /> <div class="caparchivo"> <input type="file" id="archivo" name="Archivo" class="archivo" onChange= "getElementById('nuevoarchivo').value=getElementById('archivo').value;" onMouseDown = "if(event.button==0){getElementById('examinar').src='imagenes/examinar_sobre.jpg'};" onMouseUp = "if(event.button==0){getElementById('examinar').src='imagenes/examinar_normal.jpg'};" /> </div> <table cellpadding="0" cellspacing="0"><tr><td valign="top"> <div class="archivofalso"> <input id="nuevoarchivo" onChange = "getElementById('archivo').value=getElementById('nuevoarchivo').value;" /> </div> </td><td valign="top"> <div class="examinar"> <img src="imagenes/examinar_normal.jpg" id="examinar" /> </div> </td></tr></table> <input type="submit" name="Submit" value="Insertar imagen!" onClick = "getElementById('archivo').value=getElementById('nuevoarchivo').value;" /> Eso sería todo, bastaría con ir jugando con las posiciones y demás para obtener un resultado. Finalmente, lo mejor es hacer una función, en mi caso hice una en su día en PHP para que dándole un par de parámetros me creara directamente el input con la imagen y demás (realmente mi imagen era simple así que es fácil crearla con las librerías GD) pero por un problema en el disco duro perdí todo mi trabajo y es que, como informático que soy se me cumple la ley de murphy referente a los backups ;) Un saludo y que os sirva a alguien. |
Posteada por Wallack Archivado en: Tutoriales, Informática, Diseño web |