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