Uploadify: Upload file con barra di avanzamento in jQuery/Flash

Cercando tra mille soluzioni javascript, flash e chi più ne ha più ne metta, ho trovato questo script che risolve il problema. Prima però bisogna decodificare il funzionamento!
Dopo aver perso un paio di giorni per capire come passare un valore da una pagina all’altra, ho trovato la soluzione. Ma partiamo dall’inizio.

I file si trovano nel sito principale: http://www.uploadify.com/

Scaricateli e seguite la documentazione per capire un pò il funzionamento, direi abbastanza semplice.
Il difficile arriva nei settaggi e nelle esigenze tecniche. Chi ne capisce poco di javascript rimarrà abbastanza spiazzato (parlo per esperienza) e dovrà inventarsi, letteralmente, un sistema su misura.

Iniziamo:
Si aggiungono i link a script e css nella pagina dove si vuole aggiungere il file

<link href="_tools/uploadify/css/uploadify.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="_tools/uploadify/scripts/jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="_tools/uploadify/scripts/swfobject.js"></script>
<script type="text/javascript" src="_tools/uploadify/scripts/jquery.uploadify.v2.1.0.min.js"></script>

Ho inserito il tutto nella cartella _tools/uploadify per avere il tutto più ordinato possibile.
Dopodiché bisogna creare l’istanza che permetterà di utilizzare le potenzialità di questo strumento scritto in jQuery:

<script type="text/javascript">
$(document).ready(function() {
$("#uploadify").uploadify({
'uploader'       : '_tools/uploadify/scripts/uploadify.swf',
'script'         : '_tools/uploadify/scripts/uploadify.php',
'cancelImg'      : '_tools/uploadify/cancel.png',
'folder'         : 'public/',
'queueID'        : 'fileQueue',
'sizeLimit'         : '10248000',
'buttonText'     : 'CARICA',
'auto'           : true,
'multi'          : false
});
});
</script>

Cosa abbiamo fatto? Qui ci vorrà un paio di minuti a capire il tutto e vedere cosa manca.
Con uploader diciamo dove prendere il pulsante in flash;
con script diciamo dove prendere il file php che sposterà fisicamente il file appena caricato;
con cancelImg diciamo dove prendere l’immagine X per annullare il caricamento del file;
folder è la cartella dove verranno caricati i file;
queueID saltiamolo;
sizeLimit è la dimensione massima per ogni file;
buttonText è il testo che verrà scritto dentro al nostro pulsante in flash;
auto indica il caricamento automatico alla selezione del file (se settato su true);
multi indica la possibilità di caricare più file.

Inserito tutto ciò tra i tag <head>..codice..</head>, manca solo il pulsante e il box dove comparirà la barra di caricamento:

<div id="fileQueue" style="color:#000"></div>
<input type="file" name="uploadify" id="uploadify" />

Fatto.

Ma se volessi salvare i file anche in un database? Come recupero il nome del file? E se volessi restringere le estensioni dei file solo a jpg e avi (ad esempio) ? E poi, posso rendere i vari settaggi dinamici? Perché vorrei avere la possibilità con php di cambiare ad esempio la cartella di upload in base al tipo di utente.
Queste sono le domande che mi sono posto e al quale ho dovuto dare risposta, in parte, da solo.

Per aggiungere un filtro al tipo di file da caricare, è semplice: basta aggiungere i settaggi fileDesc e fileExt sotto, ad esempio, queueID, inserendo nel primo quello che verrà scritto nel campo sotto i file (è presente in Internet Explorer) mentre nel secondo le estensioni dei file accettati. La struttura dovrà essere: '*.jpg;*.avi;' e via discorrendo con le estensioni che volete.

Volete rendere dinamico il tutto in base al tipo di utente o quello che vi è utile? Semplice come programmare in PHP! Create una variabile con il nome della cartella (potete farlo per ogni campo) e aggiungerla al posto della cartella attuale, in questo caso public:

'folder'         : '<?=$nomecartella?>/<?=$idutente?>',

e il gioco è fatto. Ho provato anche con le estensioni dei file e funziona. In base al tipo di materiale da caricare, foto, video o documenti, ho creato una semplice condizione:

<?
if($cosa=="foto"){
$tipofile="*.jpg;*.png;*.gif;";
}elseif($cosa=="video"){
$tipofile="*.mp4;*.mov;*.avi;*.flv;";
}
?>

e poi aggiunto il tutto in fileDesc e fileExt:

'fileDesc'         : '<?=$tipofile?>',
'fileExt'         : '<?=$tipofile?>',

E anche questa è fatta.

Eccoci al punto caldo: recuperare il nome del file.
Di sicuro ci sarà chi ci è riuscito dopo 5 minuti scarsi. Io non sono tra quelli. Ma il risultato mi sembra ottimo.

C’è un evento che si può aggiungere alla lista sopra citata, ed è un “onComplete“. Mi sono incaponito nell’usare onAllComplete e infatti non riuscivo a recuperare nulla (attenti anche voi!).
Tale evento contiene un array di valori che recupera dal caricamento del file: event, ID, fileObj, response, data .
Tale array contiene anche il nome del file! Per la precisione fileObj.name (name è una chiave dell’array associativo fileObj, che contiene appunto il nome del file). Sul sito, nella documentazione alla voce onComplete, troverete anche gli altri valori passati in fileObj, richiamabili con fileObj.cosavuoisapere :

  • [name] – Il nome del file caricato
  • [filePath] – La cartella dove è inserito il file
  • [size] – La dimensione in bytes del file
  • [creationDate] – La data di creazione del file
  • [modificationDate] – La data di modifica del file
  • [type] – L’estensione del file con il punto all’inizio (es: .jpg)

Ma come passarlo a PHP? Visto che la pagina non si ricarica e non c’è modo di passarlo in modo asincrono a PHP, mi sono dovuto ingegnare, ed ecco la soluzione!
Creiamo un semplice form con un campo nascosto all’interno (anche di più se volete passare variabili importanti come il tipo di file, video o foto, per inserirlo successivamente in due cartelle differenti):

<form action="salva.php" id="formfile" method="post">
<input type="hidden" name="nomefile" value="" id="nomefile" />
<input type="hidden" name="tipo" value="<?=$tipo?>" />
</form>

Rimandiamo il tutto alla pagina salva.php che creeremo come una normale pagina di salvataggio dati nel database. E il nome del nostro file? Quello lo passiamo a questo form dall’evento onComplete.
Spiego il concetto poi metto il codice: dobbiamo recuperare tramite fileObj il nome del file, lo inseriamo come valore dentro il nostro campo nascosto del form (la sostituzione con jQuery è semplicissima) e poi, sempre tramite jQuery, inviamo il form. Semplice il risultato ma tribulato nella creazione.

'onComplete'     : function(event, ID, fileObj, response, data) {
$('#nomefile').val(fileObj.name);

/* in caso di file multipli utilizzare quanto segue:
$('#nomefile').val(+fileObj.name+';');
dove i valori vengono concatenati e separati da un punto e virgola */

$('#formfile').submit();
},

Inserito questo codice sotto un evento qualsiasi (io l’ho messo sotto buttonText e attenti che se ci sono altri eventi dopo di mettere la virgola alla fine!!) tutto funzionerà come per magia.
Con #nomefile, prendiamo il campo nascosto con id nomefile (che se notate ha come valore “”), selezioniamo l’attributo val(), quindi il value=””, e lo sostituiamo con il valore di fileObj, che è il nome del nostro file. Ora abbiamo il nome del file in un form.
Per completare l’automazione dell’upload (se volete cliccare su “Salva” allora basterà aggiungere un input type="submit" al form e ingorare la riga successiva), invieremo in automatico il form con id formfile alla pagina salva.php (è l’azione del form, nulla di strano o complicato) tramite l’evento .submit() di jQuery.

Il gioco è fatto!
Lungo l’articolo ma non era semplicissimo spiegarlo in poco e farvelo capire bene bene. Buon divertimento!

Annunci
  1. #1 di Peppiniell0 il 25/11/2010 - 14:57

    io per il nome ho risolto piu semplicemente con

    ‘onComplete’ : function(event, ID, fileObj, response, data) {
    document.getElementById(“file”).value+=fileObj.name +’;’;
    }

    e con una textarea

    dove mi vado a mettere i nomi dei file multipli separati da un ; per poi salvarli nel database

    • #2 di portapipe il 25/11/2010 - 15:25

      Il mio esempio in effetti parla solo di file singoli. Per i multipli non ho ancora affrontato il problema. L’hai fatto tu! L’ho già implementato sotto forma di jQuery. Se hai ancora il progetto aperto prova a usare: $(‘#nomefile’).val(+fileObj.name+’;’);
      Giusto per capire se funziona correttamente. Fammi sapere!

      • #3 di Gabriele Malaspina il 27/02/2011 - 19:42

        Questa soluzione per gli upload multipli sembra non funzionare, mi restituisce “NaN”…
        La soluzione di Peppiniell0 funziona alla grande.

        Grazie mille per questa guida, l’ho trovata chiara nonostante la mia ignoranza, ma sopratutto utilissima! 🙂

      • #4 di portapipe il 27/02/2011 - 23:23

        Grazie 🙂
        Dici che quella inserita nell’articolo non funziona correttamente?

      • #5 di Gabriele Malaspina il 27/02/2011 - 23:54

        si si, precisamente:
        $(‘#nomefile’).val(+fileObj.name+’;’);

        Sembra non funzionare, mi riempe il campo con “NaN”.

  2. #6 di puntoesclamativo il 03/12/2010 - 12:02

    Io l’inserimento dei dati nel DB l’ho risolto così


    if (!empty($_FILES)) {
    $tempFile = $_FILES['Filedata']['tmp_name'];
    $targetPath = $_SERVER['DOCUMENT_ROOT'] . $_REQUEST['folder'] . '/';
    $targetFile = str_replace('//','/',$targetPath) . $_FILES['Filedata']['name'];

    // modifica per individuare id della gallery
    $IdGallery = $_REQUEST['galleryId'];
    // modifica per individuare il nome del file
    $nameFile = $_FILES['Filedata']['name'];
    // $fileTypes = str_replace('*.','',$_REQUEST['fileext']);
    // $fileTypes = str_replace(';','|',$fileTypes);
    // $typesArray = split('\|',$fileTypes);
    // $fileParts = pathinfo($_FILES['Filedata']['name']);

    // if (in_array($fileParts['extension'],$typesArray)) {
    // Uncomment the following line if you want to make the directory if it doesn't exist
    mkdir(str_replace('//','/',$targetPath), 0755, true);

    $sql_img= "INSERT INTO tabella (nomefile)
    VALUES
    ('" . $nameFile . "')";
    $result = @mysql_query($sql_img, $connessione) or die("Error #" . mysql_errno() . ":" . mysql_error());

    move_uploaded_file($tempFile,$targetFile);
    echo str_replace($_SERVER['DOCUMENT_ROOT'],'',$targetFile);
    // } else {
    // echo 'Invalid file type.';
    // }
    }
    ?>

    Non so se è formalmente corretto ma sembra funzionare correttamente. Il problema ora è: se volessi inserire altri dati nella tabella, come li passo?

    • #7 di portapipe il 03/12/2010 - 14:36

      Per l’invio di dati alla pagina di caricamento c’è l’opzione: scriptData.
      Va usata più o meno come nella funzione .ajax di jQuery:

      'scriptData'  : {'nome':'puntoesclamativo','anni':30},

      e va inserito dove ti pare, magari dopo folder: o dove preferisci.

      All’interno inserisci dinamicamente i valori, con php (es. <?=$nome?>) oppure con jQuery (es. $(‘#nome’).val() ) o in modo statico, a seconda di quello che ti serve.

  3. #8 di bruno il 18/12/2010 - 12:24

    ciao,io è da un bel po ke sto cercando di inserire un file nel db mysql tramite uploadify ma nn riesco a capire, xke nn lo inserisce potete aiutarmi gentilemnte sto proprio impazzendoo =(

    • #9 di portapipe il 18/12/2010 - 13:37

      Scrivi un nuovo post nel forum così ne parliamo lì.

  4. #10 di bruno il 18/12/2010 - 20:39

    ciao scusa ma da dv c vado nel forum…puo essere ke nn c’è neanke una discusisone

    • #11 di portapipe il 18/12/2010 - 20:45

      Nel menù in alto c’è la voce “forum”.
      Di discussioni ce ne sono. Basta cercare ma su uploadify non si trovano molte modifiche personalizzate.

  5. #12 di bruno il 18/12/2010 - 20:58

    scusam ma se vado in alto dv c’è scritto vai a forum io non trovo neanke una diskussione e se ne voglio fare una nuova nn me lo permette potresti mandare il link del forum scusami ankora

    • #13 di portapipe il 18/12/2010 - 22:15

      Il forum è stato creato da pochi giorni e basta una registrazione gratuita ed immediata per iniziare nuove discussioni.
      Inizia una discussione su questo argomento e ti aiuterò lì.

      p.s. per “Di discussioni ce ne sono” intendevo che nel web molti hanno parlato di uploadify ma pochi con l’intento di salvare dati nel database. Ti aspetto sul forum

  6. #14 di UomoMacchina il 27/12/2010 - 00:40

    Ciao a tutti..
    Sarà perché è passata la mezzanotte da un pezzo…
    Sarà perché è da oggi pomeriggio alle 17 che cerco sul web, leggo, studio, provo… con la speranza di trovare una soluzione semplice ed efficace per l’upload di files sul server tramite form…
    Sarà perché in fondo di php e programmazione non ci capisco una mazza…

    Insomma, ho fatto innumerevoli tentativi ma ancora non riesco a far funzionare questo benedetto script, che credo sia proprio quello che fa al caso mio.
    E mi sono pure incasinato il cervello tra le versioni 2.1.4 e 3.0.0beta!

    Qualcuno di voi sarebbe tanto gentile da inviarmi un file php di esempio bello pulito pulito che funzioni?
    E magari la cartella uploadify con i giusti files all’interno nelle giuste posizioni (magari in un unico file zip).

    Grazie.

    • #15 di portapipe il 27/12/2010 - 08:59

      Ciao. Nella documentazione ufficiale trovi tutto segnato per filo e per segno.
      Per implementare uploadify basta aggiungere un form con il campo per uploadify e il codice jQuery. Le cartelle le tieni così come le esporti.
      Comunque se hai bisogno ti posso dare una mano nel forum.

  7. #16 di UomoMacchina il 27/12/2010 - 19:15

    Ciao.
    Grazie per la risposta celere.
    In effetti trattavasi di ora tarda: ho risolto a mente lucida verificando i percorsi relativi ai vari files della classe cui mancava un benedettissimo punto. 🙂

    Ti ringrazio per avermi indicato, attraverso il tuo blog, questa risorsa gratuita e versatile, che mi ha fornito la soluzione al problema che tentavo di risolvere da tempo.

    Buona vita.

  8. #17 di Jaxxon il 23/02/2011 - 21:59

    Salve, avrei una domanda su jQuery e Uploadify…
    Volendo visualizzare l’immagine che stata appena caricata sul sito senza ricaricare la pagina come posso fare?

    grazie

    • #18 di portapipe il 24/02/2011 - 15:38

      Dovresti recuperare il nome del file e usarla per richiamare una funzione che creerai. Tale funzione sostituirà il contenuto di un div con l’html di un’immagine (cioè come aggiungere un’immagine normalmente). Se l’immagine la carichi nella cartella public, ad esempio, metti come sorgente: source=”public/”+nomefotorecuperatadauploadify

      Più o meno mi son fatto capire?

      • #19 di Jaxxon il 25/02/2011 - 15:39

        Ok grazie, proverò,

        la funzione la faccio richiamare all’arrivo dell’evento onComplete.. giusto?

    • #20 di portapipe il 25/02/2011 - 15:52

      Certamente, così sempre dall’onComplete recuperi il nome e lo passi alla funzione come parametro (esempio: visualizzaimmagine(fileObj.name) )
      Nella funzione poi lo recuperi (esempio: function visualizzaimmagine(nomeimmagine){… )

  9. #21 di Leonida il 17/05/2011 - 10:45

    Ciao, una domanda:
    una volta caricate le immagini è possibile cancellarle dal db?

    • #22 di portapipe il 17/05/2011 - 17:51

      In realtà la funzione di aggiungerlo al database è una cosa in più. Lo script di per se serve per caricare solamente i file sul server. E’ per chi ha bisogno di aggiungere il nome dei file nel database che si complicano le cose, quindi se devi caricare solamente file in una cartella, vai tranquillo che questo script fa al caso tuo.

  10. #23 di david il 02/10/2012 - 11:30

    Ciao, ho una domanda:
    Quando cancello un file dalla coda se poi vado a rifare l’upload mi chiede se voglio sovrascriverlo perche è gia presente in coda….. come mai non si cancella ????

    • #24 di portapipe il 02/10/2012 - 20:39

      Ciao. Sinceramente non mi è capitato ed è da molto che non utilizzo questo plugin, quindi magari hanno fatto delle modifiche nelle nuove versioni. Che io sappia può rimanere, per colpa di qualche bug o script scritto male, il nome del file in un qualche array, che non viene aggiornato nel caso venga tolto un file dalla coda.
      Ti consiglio magari di cercare qualche plugin in jQuery che utilizzi un metodo simile a questo (domani lo cercherò io stesso visto che sono in pieno regime di programmazione e se ne troverò uno buono ne farò un articolo)

  11. #26 di david il 03/10/2012 - 13:48

    Grazie per la risposta…
    Avevo già visto blueimp ma l’ho scartato perchè troppo pesante secondo me…
    Invece questo da te descritto lo trovo molto più snello e facile…
    Forse mi sbaglio… sono un neofita.
    Nel frattempo sono anche riuscito a eliminare quel nome file dall’array risolvendo il mio problema.
    Ti ringrazio molto cmq.
    Ciao

    • #27 di portapipe il 03/10/2012 - 13:50

      Ottimo! Felice per te. Di solito sono queste le magagne che portano via un sacco di tempo. Ad ogni modo darei un occhio anche a questo in jQuery, non dovendo sottostare a Flash e migliorare anche l’indicizzazione.

  12. #28 di Dante il 19/09/2013 - 09:10

    Ho un problema… iniziamo col dire ciò che funziona con uploadify, funziona tutto con qualsiasi macchina che sia con Mac o Win e con tutti i browser (safari, explorer, opera, crome ecc). il tutto tranne con iOS con Safari app. In quel caso o iOS o safari App impediscono al sistema di leggere i nomi delle immagini che si chiamano IMG_seguito da un numero progressivo e l’estensione jpg, il sistema che non legge il nome file, chiama quindi tutte le diverse immagini selezionate per il caricamento come image.jpg e quando il caricamento finisce risulta caricata solo l’ultima immagine ripetuta per n volte (dove n sta per il numero delle immagini selezionate per il caricamento). A questo punto se ne aggiugo un altra, vengono modificate tutte le foto caricate precedentemente con l’ultima caricata, o se ne cancello una vengono cancellate tutte. Come posso risolvere il problema sul mio sito? il caricamento multiplo è nell’area riservata.

    Grazie

    • #29 di portapipe il 20/09/2013 - 09:21

      Guarda su iOS non ho provato. Per quanto so non è possibile effettuare l’upload di contenuti tramite Safari su iOS quindi devi aver installato un’app che ti abilita l’upload, ma in quel caso ovviamente Uploadify non può coprire quel tipo di caricamento.

Rispondi

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione / Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione / Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione / Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione / Modifica )

Connessione a %s...

%d blogger hanno fatto clic su Mi Piace per questo: