Partiamo dalla semplice lettura di un file con copia del contenuto nel browser; ho utilizzato jQuery solamente per rendere il codice più conciso ed elegante e la closure su fileReader.onload per lo stesso motivo:
<!doctype html>
<html>
<head>
<title>Leggere i Files tramite le File APIs</title>
<style>
fieldset {
width: 500px;
padding: 10px;
font-size: 11px;
}
</style>
<script src="jquery.js"></script>
<script>
// # Al DOM Ready
$(function() {
// # bind dell'evento change
$("#fileinput").change(function(event) {
// # in event.target.files trovo l'oggetto FileList
// # in questo caso il file è uno solo quindi lo trovo
// # nella posizione 0
var file = event.target.files[0];
// # Controllo la dimensione del file
if(file.size > 200) {
alert("Non sono consentiti file di dimensione maggiore di 200B");
return false;
}
// # Istanzio il fileReader
var fileReader = new FileReader();
// # Leggo il file
fileReader.readAsText(file);
// # A caricamento terminato inserisco in pagina il contenuto
fileReader.onload = function (event) {
$("#contenuto_file").html(event.target.result);
};
});
});
</script>
</head>
<body>
<fieldset><legend>Scegli un file dal filesystem</legend>
<input type="file" id="fileinput" name="fileinput"><br />
<output id="contenuto_file"></output>
</fieldset>
</body>
</html>
Il risultato in Opera quando proviamo ad inserire un file più grande di 200B:
il processo andato a buon fine al termine del caricamento di un piccolo file di testo:
Uno degli aspetti più interessanti riguarda la possibilità di monitorare il progresso del caricamento di un file senza fatica:
<!doctype html>
<html>
<head>
<title>Monitorare un upload tramite le File APIs</title>
<style>
fieldset {
width: 500px;
padding: 10px;
font-size: 11px;
}
</style>
<script src="jquery.js"></script>
<script>
// # Al DOM Ready
$(function() {
// # caching del selettore per l'elemento progress
var progressBar = $("#progress_bar");
// # bind dell'evento change
$("#fileinput").change(function(event) {
// # in event.target.files trovo l'oggetto FileList
// # in questo caso il file è uno solo quindi lo trovo
// # nella posizione 0
var file = event.target.files[0];
// # Istanzio il fileReader
var fileReader = new FileReader();
// # imposto un handler per l'onprogress
fileReader.onprogress = function(event) {
// # Se è possibile effettuare il calcolo
if (event.lengthComputable) {
// # calcolo il loaded, sarà un numero compreso tra 0 ed 1
var loaded = event.loaded / event.total;
if (loaded < 1) {
// # imposto il valore dell'elemento progress
progressBar.attr("value", loaded );
}
}
};
// # imposto un handler per l'onerror
fileReader.onerror = function(event) {
alert("Si è verificato un errore nel caricamento");
return false;
};
// # Leggo il file
fileReader.readAsArrayBuffer(file);
// # A caricamento terminato termino
// # il riempimento della progressbar
fileReader.onload = function (event) {
progressBar.attr("value", 1 );
alert("Caricamento completato");
};
});
});
</script>
</head>
<body>
<fieldset><legend>Scegli un file dal filesystem</legend>
<input type="file" id="fileinput" name="fileinput"><br />
<progress id="progress_bar"></progress>
</fieldset>
</body>
</html>
La situazione durante il caricamento di un file di grosse dimensioni in Opera:
Il risultato visivo al termine del caricamento:
Notate nell’esempio la definizione degli handlers per l’evento progress e per l’evento error. Ho utilizzato il nuovo elemento progress per renderizzare la barra, elemento che in questo caso risulta indicatissimo.
Possiamo unire le potenzialità delle File APIs con le Drag&Drop APIs:
<!doctype html>
<html>
<head>
<title>File APIs e Drag&Drop</title>
<style>
#dropdiv {
width: 200px;
height: 100px;
padding: 10px;
border: 2px dashed #999;
text-align: center;
line-height: 100px;
}
</style>
<script src="jquery.js"></script>
<script>
function drop(event) {
if(event.preventDefault) {
event.preventDefault();
}
// # Recupero il file dall'oggetto DataTransfer
var file = event.dataTransfer.files[0];
// # Istanzio il fileReader
var fileReader = new FileReader();
// # Leggo il file
fileReader.readAsText(file);
// # A caricamento terminato inserisco in pagina il contenuto
fileReader.onload = function (event) {
$("#contenuto_file").append(event.target.result);
};
return false;
}
// "Cancel" di dragover
function dragover(event) {
if(event.preventDefault) {
event.preventDefault();
}
return false;
}
// "Cancel" di dragenter
function dragenter(event) {
if(event.preventDefault) {
event.preventDefault();
}
return false;
}
</script>
</head>
<body>
<div id="dropdiv" ondrop="drop(event)" ondragover="dragover(event)" ondragenter="dragenter(event)">Trascina qui un file</div>
<output id="contenuto_file"></output>
</body>
</html>
Ecco l’area di deposito prima del caricamento:
ed il risultato dopo aver trascinato un file di testo all’interno: