Subiendo ficheros en Flash (II)
Vamos con el final de la historia. Tengo una noticia buena y una mala.
Primero la mala: Lo que explicamos en el último artículo, aunque funcional, no lo vamos a utilizar. Nunca viene mal tenerlo en cuenta para futuros problemas, pero no es la mejor solución.
Ahora la buena: La solución al problema de la comunicación javascript->Flash es muy sencilla, casi de niños.
La manera escogida es la que utilizan en GlobFX para uno de los ejemplos del NeoSwiff. El ejemplo en concreto, por si alguno de vosotros lo tiene instalado, es el appparam2. A un objeto Flash le podemos pasar desde el código HTML una serie de variables con el parámetro FlashVars tanto desde un EMBED como desde OBJECT:
<param NAME=FlashVars VALUE="foo=Hello%20World&graph=first+line%0Dsecond+line">
.
.
.
<embed src="display.swf" FlashVars="foo=Hello%20World&graph=first+line%0Dsecond+line" ... (other parameters)> </embed>
La posibilidad de cambiar el valor de estos parámetros en tiempo de ejecucíon desde el propio javascript es lo que realmente es útil. Podemos entonces seleccionar nuestro fichero en formulario, y una vez seleccionado el valor del fichero comunicar a la película Flash el valor de la ruta escogida:
<script>
document.write('<OBJECT classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0" WIDTH="750" HEIGHT="536" id="flashLayer" ALIGN="middle" style="z-index:10;" VIEWASTEXT>');
document.write('<param name="movie" value="form.swf" />');
document.write('<param name="quality" value="high" />');
document.write('<param name="bgcolor" value="#ffffff" />');
document.write('<PARAM NAME=wmode VALUE="Opaque">');
document.write('<param name="FlashVars" value="navegador=' + window.navigator.appName + '&rutaFichero=c:/"/>');
document.write('<EMBED src="form.swf" quality="high" bgcolor="#ffffff" src="form.swf" quality=high bgcolor=#999999 wmode="Opaque" flashvars="navegador=' + window.navigator.appName + '&rutaFichero=c:/" WIDTH="750" HEIGHT="536" NAME="flashLayer" ALIGN="middle" TYPE="application/x-shockwave-flash" PLUGINSPAGE="http://www.macromedia.com/go/getflashplayer"></EMBED>');
</script>
<form name="upload" method="post" enctype="multipart/form-data" target="pop" ID="Form1">
<input id="file" type="file" name="fichier" size="1">
</form>
<script>
function init()
{
lWin=(window.navigator.appName=="Microsoft Internet Explorer");
w=document.getElementById("file");
if (window.navigator.platform!="MacPPC") {
if (lWin) w.onchange=browse;
else w.onclick=browse;
w.onfocus=lcChoice;
} else {
w.onclick = lWin ? browseIE : browse;
w.onfocus= lWin ? null : lcChoice;
}
}
function browse() {
if (w.value!="") {
change_myparam(w.value);
}
}
function getFlashObject( name )
{
if( window.document[name] )
return window.document[name];
if( navigator.appName.indexOf("Microsoft Internet") == -1 )
{
if( document.embeds && document.embeds[name] )
return document.embeds[name];
return null;
}
return document.getElementById(name);
}
function change_myparam(rutaFichero)
{
fo= getFlashObject('flashLayer');
if( fo == null )
{
alert("Cannot find Flash html object");
return;
}
fo.SetVariable( 'rutaFichero', rutaFichero );
}
</script>
Desmembrando el código vemos el funcionamiento básico. Tenemos un formulario (Form1), cuando se pulsa su boton Navegar… se abre un cuadro de diálogo que nos permite seleccionar el fichero. Cuando esto se produce se lanza un evento, que varía dependiendo del navegador. En la función init()
ajustamos el evento para que cuando se produzca llame a la funcion browse()
. Esta función se encarga de comunicar el cambio de la variable rutaFichero
a la película Flash. Observese la función getFlashObject()
, que permite acceder al objeto Flash tanto si estamos en Mozilla como en Internet Explorer.
Tras esto, la película Flash detectará un cambio en el valor de la variable y podremos su nuevo valor en nuestro formulario Flash. Para hacer esto seguimos el ejemplo de NeoSwiff mencionado previamente, el appparam2. Así queda el constructor del formulario:
namespace WindowsForm
{
public class FormularioFichero : System.Windows.Forms.Form
{
public FormularioFichero()
{
AppDomain app_domain= AppDomain.CurrentDomain;
app_domain.Parameters.AddHandler( "rutaFichero", new AppParameterHandler(rutaFichero_OnChange));
}
}
}
Cuando el valor de la variable rutaFichero se modifique, la funcion rutaFichero_OnChange
se encargá de hacer aparecer el nuevo valor de nuestra variable en el formulario.
Con esto queda terminada la explicación. Como veis es bastante más elegante que la solución anterior.