Pregunta
¿Cómo subir archivos con Ajax?
Responder esta pregunta por dudin el 2008-11-19
Estoy haciendo una aplicación web usando los frameworks Symfony y Prototype para PHP y Javascript respectivamente. Deseo hacer un uploader usando Ajax. ¿Existe algo ya implementado?
Respuestas
No es posible subir ficheros vía Ajax porque Javascript no tiene acceso a ningunos de los ficheros cuando se envía el formulario, o sea la información GET / POST se recopila a través de Javascript, el cual no tiene ninguna manera de acceder al contenido de los ficheros locales por razones de seguridad.
Sin embargo, puede utilizar AJAX para obtener información de estado en la subida de ficheros.
Pero no se desanime, se pueden subir ficheros a través del clásico formulario HTML dentro de un IFRAME oculto y la experiencia del usuario será excelente.
Supongamos que tenemos un módulo llamado "files" y que en el mismo tenemos una acción "edit" donde se requiere subir imágenes, con la condición de no recargar la página actual ("edit") y que además muestre una miniatura de la imagen subida.
El template editSuccess.php
Sin embargo, puede utilizar AJAX para obtener información de estado en la subida de ficheros.
Pero no se desanime, se pueden subir ficheros a través del clásico formulario HTML dentro de un IFRAME oculto y la experiencia del usuario será excelente.
Supongamos que tenemos un módulo llamado "files" y que en el mismo tenemos una acción "edit" donde se requiere subir imágenes, con la condición de no recargar la página actual ("edit") y que además muestre una miniatura de la imagen subida.
<?php
/* actions.class.php */
class filesActions extends sfActions
{
public function executeEdit()
{
$this->files = array();
}
public function handleErrorEdit()
{
if ($this->getRequestParameter('file'))
{
$this->files = $this->getRequestParameter('file');
} else
{
$this->files = array();
}
return sfView::SUCCESS;
}
public function executeUpload()
{
$this->prepareUpload();
if ($this->getRequest()->hasFiles())
{
$this->file = $this->getRequest()->getFileName('file');
/* Limitar el tamaño a un máximo, usando el plugin sfThumbnail */
$thumbnail = new sfThumbnail(500, 400);
$thumbnail->loadFile($this->getRequest()->getFilePath('file'));
$thumbnail->save(sfConfig::get('sf_upload_dir').'/'.$fileName);
/* Crea una imágenes en miniaturas que se mostrarán para indicar que subió correctamente */
$thumbnail = new sfThumbnail(75, 75);
$thumbnail->loadFile($this->getRequest()->getFilePath('file'));
$thumbnail->save(sfConfig::get('sf_upload_dir').'/th/'.$fileName);
$this->isUploaded =true;
}
}
public function handleErrorUpload()
{
$this->prepareUpload();
return sfView::SUCCESS;
}
protected function prepareUpload()
{
$this->isUploaded = false;
sfConfig::set('sf_web_debug', false);
$this->getResponse()->addJavascript('upload');
$this->setLayout('simple');
}
}
El template editSuccess.php
<?php use_helper('Validation') ?>
<div id="data-form">
<?php echo form_tag('files/edit', 'id=form') ?>
<div id="iframe">
<iframe src="<?php echo url_for('files/upload')?>" frameborder="0" ></iframe>
</div>
<div id="images-uploaded">
<?php foreach ($files as $k => $file): ?>
<?php echo include_partial('thumbnail', array('file' => $file)) ?>
<?php endforeach; ?>
</div>
<div id="submit"><?php echo submit_to(__('Enviar')); ?> </div>
</form>
</div>
Template general de la aplicación simple.php:<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
</head>
<body>
<?php echo $sf_data->getRaw('sf_content') ?></div>
</body>
</html>
Parcial _thumbnail.php:<div class="thumbnail" ><img src="/uploads/th/<?php echo $file?>" alt="<?php echo $file ?>" width="75" />
<?php echo input_hidden_tag('file[]',$file) ?></div>
El template uploadSuccess.php:<?php use_helper('Validation') ?>
<?php if ($sf_request->hasError('file')): ?>
<?php echo javascript_tag("alert('" .$sf_request->getError('file')."');
errorUpload(". $sf_params->get('imgnum').")
")
?>
<?php endif; ?>
<?php if ($isUploaded): ?>
<?php echo include_partial('thumbnail', array('file' => $file)) ?>
<?php echo javascript_tag("uploaded(". $sf_params->get('imgnum')."); ") ?>
<?php else: ?>
<?php echo form_tag('files/upload', 'multipart=true name=iform') ?>
<?php echo input_file_tag('file', 'onChange=upload()') ?>
<?php echo input_hidden_tag('imgnum') ?>
</form>
<?php endif; ?>
El fichero javascript upload.js:/* upload.js */
function upload(){
// Oculta los iframe anteriores
var par = window.parent.document;
var iframes = $A(par.getElementsByTagName('iframe'));
$(iframes.last()).addClassName('hidden');
//Crea un nuevo iframe
var new_iframe = par.createElement('iframe');
new_iframe.src = iframes.last().src;
new_iframe.frameBorder = '0';
par.getElementById('iframe').appendChild(new_iframe);
// Pone una imagen de espera
var images = getByIdParent('images-uploaded');
var html_images = '<img src="/images/icons/loading.gif" border="0" />'
var new_div = par.createElement('div');
new_div.className = 'load';
new_div.innerHTML = html_images;
images.appendChild(new_div);
// Enviar
var imgnum = images.getElementsByTagName('div').length - 1;
document.iform.imgnum.value = imgnum;
setTimeout(function(){document.iform.submit()}, 5000);
}
/**
* Se llama luego que se ha subido el fichero al servidor
* */
function uploaded(id){
var images = getByIdParent('images-uploaded');
var imgdiv = images.getElementsByTagName('div')[id];
imgdiv.innerHTML = $('thumbnail').innerHTML;
}
function errorUpload(id){
var images = getByIdParent('images-uploaded');
images.removeChild(images.getElementsByTagName('div')[id]);
}
function getByIdParent(id)
{
var par = window.parent.document;
return par.getElementById(id);
}
Finalmente un poco de estilo mediante edit.css:iframe {
border-width: 0px;
height: 90px;
width: 300px;
overflow:hidden;
margin-left: 220px;
}
iframe.hidden {
visibility: hidden;
width:0px;
height:0px;
}
#images-uploaded {
width: 390px;
margin: 0 10px;
}
#images-uploaded div {
margin: 0 0 0 10px;
width: 100px;
height: 90px;
border-style: solid;
border-width: 5px;
border-color: #DEDFDE;
float: left;
overflow: hidden;
padding:4px;
}
#images-uploaded div:hover {
border-color: #529EBD;
}
por maikel el 2008-11-21
no me funciona me sale error en clas filesactions alguna rason si me ayudan por favor
por Anónimo el 2009-05-22



