webdesign / development + awesome
archivovaný archívny archív
Pri uploadovaní cez HTML formulár, hlavne ak sa jedná o veľké súbory, môže byť problém, že používateľ nevie aká časť zo súboru sa uploadla, či sa súbor vôbec uploaduje a prinajhoršom si myslí, že sa vôbec nič nedeje a nervózne kliká na submit. Ešte horšie ako zvýšená záťaž na server, ktorú generuje, je riziko, že sa na celú stránku vyserie, lebo si myslí, že nefunguje. :)
V tomto tutoriale si povieme ako za pomoci PHPčka a jQuery jednoducho vytvoriť progress bar, ktorý sa priebežne obnovuje podľa množstva prenesených dát z uploadovaných súborov a snáď pomôže predísť úniku netrpezlivých používateľov zo stránky.
Aby ste vedeli o čom je reč, tu si môžete pozrieť demo.
Na celú túto srandu v prvom rade potrebujete mať na serveri nainštalovaný PHP modul s názvom uploadprogress. Bohužiaľ sú dostupné len zdrojáky, takže ak ich nemáte ako skompilovať alebo nemáte prístup k serveru kde je tento modul už pridaný, ste pretty much fucked. :) Pod Linuxom by sa mali dať inštalovať rozšírenia cez PECL, čo som zatiaľ neskúšal a pod Windowsom ich treba kompilovať, čo je zase neskutočný pain na to, že chceme vlastne len poondený progress bar. :p
Príncíp nášho uploadera je taký, že v Javascripte zachytíme udalosť kedy sa odošle formulár (onsubmit) a spustíme funkciu, ktorá každých pár sekúnd počas odosielania súborov zisťuje informácie o priebiehajúcom uploade a zobrazuje ich.
<form action="upload_finished.php" method="post" enctype="multipart/form-data" id="upload_form"> <h1>brm.sk / upload progress bar demo</h1> <input id="progress_key" name="UPLOAD_IDENTIFIER" type="hidden" value="<?= md5( microtime().rand() ) ?>"> <div id="attachments"> <p>Uploadni súbor: <input type="file" name="attachment"></p> <div style="text-align: right;"><input type="submit"></div> </div> <div id="uploadprogress" style="display: none;"> Uploadujú sa súbory... <div class="progress_border"> <div id="progress"><!-- --></div> </div> <p id="progress_txt">Zostáva: ?</p> </div> </form>
Fromulár je jednoduchý a jediná neštandardná vec na ňom je pole UPLOAD_IDENTIFIER obsahujúce náhodnú hodnotu, ktorá slúži pre modul uploadprogress, aby sme si podľa neho vedeli vypýtať informácie o našom uploade.
V JavaScripte sa dejú o niečo zaujímavejšie veci:
$(function()
{
new Image().src = "progressbar.png";
$('#upload_form').submit(function()
{
if ($("#uploadprogress").is(":visible")) return false;
if ($("#attachments input[type=file]").val().length > 0)
{
$("#attachments").hide();
$("#uploadprogress").show();
setInterval(get_upload_progress, 2000);
}
else
{
alert("Vyber súbor, ktorý sa má uploadnúť!");
return false;
}
});
$("#progress").css("width", "0px"); // bez tohoto by nefungovala animacia progressbaru v novej Opere s novym jQuery (wtf)
});
function get_upload_progress()
{
$.get("uploadprogress.php", { id: $("#progress_key").val() },
function(data)
{
if (!data) return;
$("#progress").stop().animate(
{width: Math.round(100 * (data.bytes_uploaded / data.bytes_total))+"%"},
200);
var min = Math.floor(data.est_sec / 60);
var sec = (data.est_sec % 60)+'';
if (sec.length == 1) sec = "0"+sec;
$("#progress_txt").html("Zostáva "+min+":"+sec
+" (aktuálna rýchlosť: "+Math.round(data.speed_last/1024)+"kB/s)");
}, 'json');
}
Najskôr sa preloadne obrázok progress baru, keďže po odoslaní formulára by sa už v niektorých prehliadačoch nenačítal. Nasleduje funkcia, ktorá sa zavolá pri odoslaní formulára (či už kliknutím na tlačítko submit alebo stlačením enteru) a má za úlohu 3 veci.
Funkcia obnovujúca údaje o uploade posiela ajax požiadavky s IDčkom UPLOAD_IDENTIFIER, dostane údaje formátované ako JSON a na základe nich zmení šírku progress baru (v percentách) plus vypíše naformátované kecy o zostávajúcom čase a rýchlosti.
Na server už treba umiestniť už len jednoduchý skript, ktorý vracia údaje v spomínanom formáte JSON:
<?php
header("Cache-Control: no-cache, must-revalidate");
header("Expires: Thu, 01 Jan 1970 00:00:00 GMT");
if ($_GET['id'])
{
echo json_encode(uploadprogress_get_info($_GET['id']));
}
?>
Prvé 2 riadky zabezpečia aby prehliadač nepoužíval cache a vždy načítal čerstvé údaje a funkcia uploadprogress_get_info() vracia informácie o uploade - presnejšie: time_start (čas začatia uploadu), time_last (aktuálny čas), speed_average (priemerná rýchlosť), speed_last (posledná meraná rýchlosť), bytes_uploaded, bytes_total, files_uploaded a est_sec (odhad zostávajúceho času).
Tu nájdete celý zdroják: source.rar.
Archivovaný archív je bez komentárov. Radšej.
6 komentárov
komentuj ku každému komentáru sa v databáze ukladá iba meno, text a dátum, iba za účelom zobrazenia pod článkomneukladá sa email, IP adresa ani informácie o prehliadači a údaje sa nepoužívajú na reklamu, newsletter, na žiadnu ekonomickú aktivitu, nikam sa neposielajú, sú v databáze len aby sa mohli zobraziť pod článkom