Autor | Zpráva | ||
---|---|---|---|
Tirus Profil |
#1 · Zasláno: 11. 9. 2014, 08:55:54
Snažím se napsat drop zonu pro X souborů. Funkčnost má být taková, že tam dropnu XXX souborů a následně je jeden po druhým odešlu buď jako formulář, nebo jako json objekt (ajaxově) a následně bych si vrátil pouze snippet (v Nette) a ten si nahradil aby uživatel viděl v seznamu fotek i tu přidanou a tu co se zrovna odeslala, z toho seznamu souborů buď odebrat a nebo ji označit jako success
Takže tolik kolik dám souborů, tolikrát se mi to odešle na server a tolikrát se mi překreslí seznam fotek. evt.stopPropagation(); evt.preventDefault(); var files = evt.dataTransfer.files; // FileList object. // files is a FileList of File objects. List some properties. var output = []; for (var i = 0, f; f = files[i]; i++) { if (!f.type.match('image.*')) { continue; } output.push('<li class="bg-info" id="file_' + i + '"><strong>', escape(f.name), '</strong> (', f.type || 'n/a', ') - ', f.size, ' bytes', '</li>'); } document.getElementById('list').innerHTML = '<ul class="files">' + output.join('') + '</ul>'; for (var i = 0, f; f = files[i]; i++) { if (!f.type.match('image.*')) { continue; } reader = new FileReader(); reader.onload = function(e) { console.log(e); document.getElementById('file_' + i).className = 'bg-success'; // zde mi to pise Uncaught TypeError: Cannot set property 'className' of null //coz mi prijde jako hloupost, protoze element s ID file_# tam je }; reader.readAsText(f) } } function handleDragOver(evt) { evt.stopPropagation(); evt.preventDefault(); evt.dataTransfer.dropEffect = 'copy'; // Explicitly show this is a copy. } // Setup the dnd listeners. var dropZone = document.getElementById('drop_zone'); dropZone.addEventListener('dragover', handleDragOver, false); dropZone.addEventListener('drop', handleFileSelect, false); |
||
Chamurappi Profil |
#2 · Zasláno: 11. 9. 2014, 09:04:42
Reaguji na Tira:
„ document.getElementById('file_' + i).className = 'bg-success'; // zde mi to píše Uncaught TypeError: Cannot set property 'className' of null “
Hodnota proměnné i v okamžiku zavolání funkce v onload bude už jiná, než jaká byla při vzniku této funkce. V té doby už cyklus dávno skončil (kvůli tomu, že i přesáhlo velikost pole files ). Potřebuješ to íčko nějak zakonzervovat, viz lexikální uzávěr.
|
||
Tirus Profil |
#3 · Zasláno: 11. 9. 2014, 12:56:37
Chamurappi:
1. jsi první na diskusních forech, kdo můj nick správně sklonil :) 2. zpět k dotazu Upravil jsem to na reader.onload = function(e, i) { console.log(e); document.getElementById('file_' + index).className = 'bg-success'; //coz mi prijde jako hloupost, protoze element s ID file_# tam je }(i); |
||
juriad Profil |
Tirus:
To skoloňování je zde automatické :-) Napiš do odpovědi písmena ri a pak Ctrl+Dolů a najeď šipkami na zdejší jména. for (var i = 0, f; f = files[i]; i++) (function(index) { if (!f.type.match('image.*')) { continue; } reader = new FileReader(); reader.onload = function(e) { console.log(e); document.getElementById('file_' + index).className = 'bg-success'; // zde mi to pise Uncaught TypeError: Cannot set property 'className' of null //coz mi prijde jako hloupost, protoze element s ID file_# tam je }; reader.readAsText(f) })(i); Aneb, co to dělá: for (...) vyžaduje za sebou buď jeden příkaz nebo blok příkazů obalený složenými závorkami {} .
V tomto případě je ten jediný příkaz definice a okamžité zavolání funkce: (function(index) {...})(i) |
||
Tirus Profil |
#5 · Zasláno: 11. 9. 2014, 13:25:41
Reaguji na juriada:
ahááá :) děkuji Jinak dal jsem tam ten kod co si poslal a v tu chvíli mi přestalo fungovat drag&drop zona. do konzole to nevypise zadnou chybu |
||
juriad Profil |
Ahá, já si nevšiml toho continue, ten samozřejmě musí zůstat mimo tu funkci.
for (var i = 0, f; f = files; i++) { if (!f.type.match('image.*')) { continue; } reader = new FileReader(); (function(index) { reader.onload = function(e) { console.log(e); document.getElementById('file_' + index).className = 'bg-success'; // zde mi to pise Uncaught TypeError: Cannot set property 'className' of null //coz mi prijde jako hloupost, protoze element s ID file_# tam je }; })(i); reader.readAsText(f) } |
||
Tirus Profil |
Reaguji na juriada:
ok a to z jakého důvodu prosím? Mohu do té funkce normálně dát ajax? tam bych dal odeslání toho souboru v base64 vc. nazvu souboru apod. na server a zpět bych si poslal snippet apod.. (z nette). ale to už zas musím nějak proštudovat :) |
||
juriad Profil |
#8 · Zasláno: 11. 9. 2014, 14:43:40
Z důvodu, že nemůžeš definovat funkci, která obsahuje continue bez smyčky.
var fn; for (var i = 0; i < 10; i++) { // od této funkce chceme, aby přeskočila i == 5 fn = function(i) { if (i == 5) { continue; } } fn(i); // při i == 5 bude continue alert(i); // vypíše všechna čísla kromě 5 } fn(5); // a sakra :-) Ano, v té funkci můžeš dělat cokoli, co neovlivňuje jazykové konstrukty mimo ní - tedy asi jen break a continue uvnitř for, while a switche. Asi tě napadne, že return uvnitř té funkce ukončí jen tu vnitřní aktuální funkci, nikoli tu vnější. |
||
Tirus Profil |
Reaguji na juriada:
jo, super, tak to už i chápu :) Nedalo by se ten kod i napsat trochu hezčí? (jsem zvyklej na jQuery) function handleFileSelect(evt) { evt.stopPropagation(); evt.preventDefault(); var files = evt.dataTransfer.files; // FileList object. // files is a FileList of File objects. List some properties. var output = []; for (var i = 0, f; f = files[i]; i++) { if (!f.type.match('image.*')) { continue; } output.push('<li class="bg-info" id="file_' + i + '"><strong>', escape(f.name), '</strong> (', f.type || 'n/a', ') - ', f.size, ' bytes', '</li>'); } document.getElementById('list').innerHTML = '<ul class="files">' + output.join('') + '</ul>'; for (var i = 0, f; f = files[i]; i++) { if (!f.type.match('image.*')) { continue; } (function(index) { reader = new FileReader(); reader.onload = function(e) { console.log(e); document.getElementById('file_' + index).className = 'bg-success'; $('#file_' + index).fadeOut('slow'); }; reader.readAsText(f) })(i); } } function handleDragOver(evt) { evt.stopPropagation(); evt.preventDefault(); evt.dataTransfer.dropEffect = 'copy'; // Explicitly show this is a copy. } // Setup the dnd listeners. var dropZone = document.getElementById('drop_zone'); dropZone.addEventListener('dragover', handleDragOver, false); dropZone.addEventListener('drop', handleFileSelect, false); Jen poslední věc. Jak zde mohu nějak sepsat ten upload jeden po druhém? to mám do toho onload? Právě přemýšlím jak to zkomponovat s Nette Ajaxem abych mohl překreslovat ty snippety :( (dělám takovýhle elaborát prvně) - edit (na to napojení na Ajax se mi rýsuje odpověď [http://forum.nette.org/cs/20667-custom-ajax-request-a-invalidace]) |
||
juriad Profil |
#10 · Zasláno: 11. 9. 2014, 15:20:29 · Upravil/a: juriad
Ano, můžeš to zkrátit. Řádky 21 až 29 můžeš přestěhovat do toho prvního foru.
Vůbec nevadí, že v té době ještě file_N neexistuje, protože reader.onload se může zavolat až teprve skončíš se zpracováním funkce handleFileSelect a to už ty elementy existovat budou. Podívej se na tento example: https://developer.mozilla.org/en-US/docs/Using_files_from_web_applications#Handling_the_upload_process_for_a_file.2C_asynchronously Jen prostě místo vytváření objektu XMLHttpRequest v sendFile použiješ něco jiného (nette ajax). |
||
Tirus Profil |
Reaguji na juriada:
Takže říkáš něco jako. reader.onload = function(e) { console.log(e); document.getElementById('file_' + index).className = 'bg-success'; $.nette.ajax({ type: "JSON", url: url, data: data }); }; ? ještě jen pár informací. Potřeboval bych věci jako je obsah souboru, nazev a velikost atd. Název a velikost už vím jak, ale nenašel jsem, jak získat ten obsah. Nebo mám posílat rovnou celej reader? |
||
Tirus Profil |
#12 · Zasláno: 11. 9. 2014, 22:43:51
Reaguji na juriada:
Tak jsem to sešmoulil :) <script> function handleFileSelect(evt) { evt.stopPropagation(); evt.preventDefault(); console.log(evt); if (evt.target.id == 'inputFiles') { var files = evt.target.files; // FileList object. } else { var files = evt.dataTransfer.files; // FileList object. } console.log(files); // files is a FileList of File objects. List some properties. var output = []; var maxSize = {$maxUpload}; for (var i = 0, f; f = files[i]; i++) { if (!f.type.match('image.*')) { continue; } var bigger = false; if (f.size > maxSize) { bigger = true; } var itemLi = '<li class="bg-'; if(bigger){ itemLi += 'danger'; }else{ itemLi += 'info'; } itemLi += '" id="file_' + i + '"><strong>'+ escape(f.name)+ '</strong> ('+ f.type + ') - '+f.size+ ' bytes'+'</li>'; output.push(itemLi); if (bigger) { continue; } (function(index, fi) { reader = new FileReader(); reader.onload = function(e) { console.log(e); $.nette.ext("unique", null); $.nette.ajax({ type: 'POST', url: {link upload!}, data: { file: e.target.result, fileType: fi.type, fileName: fi.name, fileSize: fi.size }, success: function(data, status, xhr) { document.getElementById('file_' + index).className = 'bg-success'; $('#file_' + index).fadeOut('slow'); }, error: function(){ document.getElementById('file_' + index).className = 'bg-danger'; } }); }; reader.readAsDataURL(f) })(i, f); } document.getElementById('list').innerHTML = '<ul class="files">' + output.join('') + '</ul>'; } function handleDragOver(evt) { evt.stopPropagation(); evt.preventDefault(); evt.dataTransfer.dropEffect = 'copy'; // Explicitly show this is a copy. } // Setup the dnd listeners. document.getElementById('inputFiles').addEventListener('change', handleFileSelect, false); var dropZone = document.getElementById('drop_zone'); dropZone.addEventListener('dragover', handleDragOver, false); dropZone.addEventListener('drop', handleFileSelect, false); </script> Pro info počítá to s nette a pár věcma, ale to si každý může sám upravit. Jen se optám, je nějaká možnost jak to ještě upravit aby to fungovalo tak, že se soubory budou zasílat posobě? teď to funguje tak, že se vše odešle najednou :( |
||
Tirus Profil |
Reaguji na juriada:
nešlo by to udělat nějak aby to nenačítalo celej seznam do paměti a pak odesílal, ale aby to odesílalo rovnou jeden soubor po druhém? <script> function handleFileSelect(evt) { evt.stopPropagation(); evt.preventDefault(); if (evt.target.id == 'inputFiles') { var files = evt.target.files; // FileList object. } else { var files = evt.dataTransfer.files; // FileList object. } // files is a FileList of File objects. List some properties. var output = []; var maxSize = {$maxUpload}; for (var i = 0, f; f = files[i]; i++) { if (!f.type.match('image.*')) { continue; } var bigger = false; if (f.size > maxSize) { bigger = true; } var itemLi = '<li class="bg-'; if (bigger) { itemLi += 'danger'; } else { itemLi += 'info'; } itemLi += '" id="file_' + i + '"><strong>' + escape(f.name) + '</strong> (' + f.type + ') - ' + f.size + ' bytes' + '</li>'; output.push(itemLi); if (bigger) { continue; } $.xhrPool = []; $.xhrPool.abortAll = function() { $.each(this, function(jqXHR) { jqXHR.abort(); }); }; $.ajaxSetup({ beforeSend: function(jqXHR) { $.xhrPool.push(jqXHR); } }); (function(index, fi) { reader = new FileReader(); reader.onload = function(e) { $.nette.ext("unique", null); $.nette.ajax({ type: 'POST', url: {link upload!}, data: { file: e.target.result, fileType: fi.type, fileName: fi.name, fileSize: fi.size, }, success: function(data, status, xhr) { if (data.redirect) { $.xhrPool.abortAll(); window.location.assign(data.redirect); } document.getElementById('file_' + index).className = 'bg-success'; $('#file_' + index).fadeOut('slow'); }, error: function(jqXHR, textStatus, errorThrown) { console.log(textStatus, errorThrown); } }); }; reader.readAsDataURL(f) })(i, f); } document.getElementById('list').innerHTML = '<ul class="files">' + output.join('') + '</ul>'; } function handleDragOver(evt) { evt.stopPropagation(); evt.preventDefault(); evt.dataTransfer.dropEffect = 'copy'; // Explicitly show this is a copy. } // Setup the dnd listeners. document.getElementById('inputFiles').addEventListener('change', handleFileSelect, false); var dropZone = document.getElementById('drop_zone'); dropZone.addEventListener('dragover', handleDragOver, false); dropZone.addEventListener('drop', handleFileSelect, false); </script> |
||
Časová prodleva: 10 let
|
0