HTML5 drag a drop image upload
- CJHornster
- Člen | 56
Čau,
na netu jsem našel tento tutoriál, ale je řešený přes php … tak se nějak pokouším přijít jak to spojit s presenterem v nette
http://tutorialzine.com/2011/09/html5-file-upload-jquery-php/
nemáte nějaký nápad jak místo post_file.php volat metodu z presenteru?
- MartinitCZ
- Člen | 580
Osobně bych se soubor nesnažil volat z presenteru, ale celý soubor bych
přepsal do „Nette way“. ;)
Vytvořit si formulář
s uploadem a zpracovat to čistě v něm, tedy žádné $_FILE,
$_GET …
Editoval MartinitCZ (26. 7. 2014 17:39)
- CJHornster
- Člen | 56
no to mám už teď, ale problém je, že přesně nevím jak na to navázat ten HTML5 drag n drop uploader (s progresem uploadu)
Editoval CJHornster (26. 7. 2014 23:11)
- CJHornster
- Člen | 56
tak sem se to pokoušel zprovoznit, nejdříve normálně podle návodu, ale skončil jsem u toho, že mě to řve:
POST http://localhost:8080/VyzadameNette/www/admin/post_file.php 500 (Internal Server Error) jquery.filedrop.js:311
XMLHttpRequest.sendAsBinary jquery.filedrop.js:311
send jquery.filedrop.js:215
Uncaught SyntaxError: Unexpected token < jquery.js:4
x.extend.parseJSON jquery.js:4
xhr.onload
Script mam takhle:
$(function(){
var dropbox = $('#dropbox'),
message = $('.message', dropbox);
dropbox.filedrop({
// The name of the $_FILES entry:
paramname:'pic',
maxfiles: 5,
maxfilesize: 2,
url: 'post_file.php',
uploadFinished:function(i,file,response){
$.data(file).addClass('done');
// response is the JSON object that post_file.php returns
},
error: function(err, file) {
switch(err) {
case 'BrowserNotSupported':
showMessage('Your browser does not support HTML5 file uploads!');
break;
case 'TooManyFiles':
alert('Too many files! Please select 5 at most! (configurable)');
break;
case 'FileTooLarge':
alert(file.name+' is too large! Please upload files up to 2mb (configurable).');
break;
default:
break;
}
},
// Called before each upload is started
beforeEach: function(file){
if(!file.type.match(/^image\//)){
alert('Only images are allowed!');
// Returning false will cause the
// file to be rejected
return false;
}
},
uploadStarted:function(i, file, len){
createImage(file);
},
progressUpdated: function(i, file, progress) {
$.data(file).find('.progress').width(progress);
}
});
var template = '<div class="preview">'+
'<span class="imageHolder">'+
'<img />'+
'<span class="uploaded"></span>'+
'</span>'+
'<div class="progressHolder">'+
'<div class="progress"></div>'+
'</div>'+
'</div>';
function createImage(file){
var preview = $(template),
image = $('img', preview);
var reader = new FileReader();
image.width = 100;
image.height = 100;
reader.onload = function(e){
// e.target.result holds the DataURL which
// can be used as a source of the image:
image.attr('src',e.target.result);
};
// Reading the file as a DataURL. When finished,
// this will trigger the onload function above:
reader.readAsDataURL(file);
message.hide();
preview.appendTo(dropbox);
// Associating a preview container
// with the file, using jQuery's $.data():
$.data(file,preview);
}
function showMessage(msg){
message.html(msg);
}
});
v budoucnu sem myslel, že by to mohlo bejt propojený z nette nějak takhle:
$(function(){
var dropbox = $('#dropbox'),
message = $('.message', dropbox);
dropbox.filedrop({
// The name of the $_FILES entry:
paramname:'pic',
maxfiles: 5,
maxfilesize: 2,
url: {link imageUpload!},
uploadFinished:function(i,file,response){
//$.data(file).addClass('done');
// response is the JSON object that post_file.php returns
},
... atd
Nevíte co s tím, nebo nevvíte o jiném způsobu jak implementovat drag n drop?
Editoval CJHornster (28. 7. 2014 11:00)
- David Kudera
- Člen | 455
V té chybě: určitě jsi tam chtěl mít v URL {BasePath}
?
Jen se ptám, třeba je to úmysl..
- CJHornster
- Člen | 56
tak už to funguje:
tahle úprava pomohla
dropbox.filedrop({
// The name of the $_FILES entry:
paramname:'pic',
maxfiles: 5,
maxfilesize: 2,
url: '../post_file.php',
ted jen vyřešit jak to spojit s nette, protože na každý obrázek potřebuji uložit cestu do DB
Editoval CJHornster (28. 7. 2014 11:07)
- David Kudera
- Člen | 455
spojení s nette by nemělo být nijak složité. Můžeš si vytvořit nějakou akci v presenteru a v ní ty soubory zpracuješ. Tady je dokumentace, kde je popsáno, jak přistoupit k souborům. Jak uložit takový soubor je tady na fóru několikrát (hledej např. form upload) a místo té funkce exist_status můžeš použít třeba JsonResponse
$this->sendResponse(new JsonResponse(array('status' => $status)));
- CJHornster
- Člen | 56
jj na to jsem taky narazil, ale nějak se mě to nevede dát dohromady s mým kódem
- David Kudera
- Člen | 455
Nastavuješ v tom skriptu správnou url? Zavolá se vůbec ta akce presenteru? Klidně pošli i kód té akce samotné. První je ale dobrý vědět, jestli se vůbec zavolá..
- CJHornster
- Člen | 56
ta akce se nejspíše vůbec nezavolá, protože cokoliv zkusím, tak mě píše script.js syntax error
jde mě vlastně o to drag n dropem nahrát ty obrázky na server a pak jejich adresy (odkazy na ně uložit do DB) (popřípadě je ještě zformátovat jako všem nastavit pomocí nette 200px width)
Editoval CJHornster (28. 7. 2014 12:58)
- CJHornster
- Člen | 56
právě, že takhle, když volám nějakeou metodu z presenteru, tak mě to nefunguje a kříčí, že to nemůže nic takovýho najít
dropbox.filedrop({
// The name of the $_FILES entry:
paramname:'pic',
maxfiles: 5,
maxfilesize: 2,
url: '../post_file.php',
- David Kudera
- Člen | 455
no ale ../post_file.php
určitě není url na akci toho
presenteru že? nějak mu ji musíš nastavit. Jedna možnost je si např.
udělat v layoutu nebo v templatě proměnnou
<script type="text/javascript">
var imageUploadUrl = {link ImagePresenter:upload};
</script>
no a pak ji použít v té konfiguraci
url: imageUploadUrl
- CJHornster
- Člen | 56
jj o něco podbného jsem se pokoušel, ale narazil jsem na problém
Uncaught SyntaxError: Unexpected token < jquery.js:4
x.extend.parseJSON jquery.js:4
xhr.onload
toto mám v layoutu
<script type="text/javascript">
var imageUploadUrl = {link ImagePresenter:upload};
</script>
a toto v script.js
dropbox.filedrop({
// The name of the $_FILES entry:
paramname:'pic',
maxfiles: 5,
maxfilesize: 2,
url: imageUploadUrl,
už jsme se do toho tak zamotal, že nevím ani kde pořádně sem :D
- David Kudera
- Člen | 455
jo sorry, ono se to escapuje.. tak např. takhle:
var imageUploadUrl = "{$presenter->link('Image:upload')|noescape}";
z nějakýho důvodu mi nefunguje {link Image:upload|noescape}
,
jinak bych použil to..
jo a kdyžtak se i podívej a pošli sem, co to vlastně vrací za ten response
- CJHornster
- Člen | 56
no ted to vyhazuje tohle:
Uncaught SyntaxError: Unexpected token < jquery.js:4
x.extend.parseJSON jquery.js:4
xhr.onload
spíš mam pocit, že to tam dávám nějak blbě já
tady je view (images.latte)
{block content}
<script type="text/javascript">
var imageUploadUrl = "{$presenter->link('AdminPresenter:imageUpload')|noescape}";
</script>
<div id="dropbox" class="col-md-12">
<span class="message">Drop images here to upload. <br /><i>(they will only be visible to you)</i></span>
</div>
ten script ted vypadá takhle:
$(function(){
var dropbox = $('#dropbox'),
message = $('.message', dropbox);
dropbox.filedrop({
// The name of the $_FILES entry:
paramname:'pic',
maxfiles: 5,
maxfilesize: 2,
url: imageUploadUrl,
uploadFinished:function(i,file,response){
$.data(file).addClass('done');
// response is the JSON object that post_file.php alert
//returns("prdel");
},
error: function(err, file) {
switch(err) {
case 'BrowserNotSupported':
showMessage('Your browser does not support HTML5 file uploads!');
break;
case 'TooManyFiles':
alert('Too many files! Please select 5 at most! (configurable)');
break;
case 'FileTooLarge':
alert(file.name+' is too large! Please upload files up to 2mb (configurable).');
break;
default:
break;
}
},
// Called before each upload is started
beforeEach: function(file){
if(!file.type.match(/^image\//)){
alert('Only images are allowed!');
// Returning false will cause the
// file to be rejected
return false;
}
},
uploadStarted:function(i, file, len){
createImage(file);
},
progressUpdated: function(i, file, progress) {
$.data(file).find('.progress').width(progress);
}
});
var template = '<div class="preview">'+
'<span class="imageHolder">'+
'<img />'+
'<span class="uploaded"></span>'+
'</span>'+
'<div class="progressHolder">'+
'<div class="progress"></div>'+
'</div>'+
'</div>';
function createImage(file){
var preview = $(template),
image = $('img', preview);
var reader = new FileReader();
image.width = 100;
image.height = 100;
reader.onload = function(e){
// e.target.result holds the DataURL which
// can be used as a source of the image:
image.attr('src',e.target.result);
};
// Reading the file as a DataURL. When finished,
// this will trigger the onload function above:
reader.readAsDataURL(file);
message.hide();
preview.appendTo(dropbox);
// Associating a preview container
// with the file, using jQuery's $.data():
$.data(file,preview);
}
function showMessage(msg){
message.html(msg);
}
});
a funkce v AdminPresenter je:
public function handleImageUpload()
{
$demo_mode = false;
$upload_dir = 'uploads/';
$allowed_ext = array('jpg','jpeg','png','gif');
if(strtolower($_SERVER['REQUEST_METHOD']) != 'post'){
exit_status('Error! Wrong HTTP method!');
}
if(array_key_exists('pic',$_FILES) && $_FILES['pic']['error'] == 0 ){
$pic = $_FILES['pic'];
if(!in_array(get_extension($pic['name']),$allowed_ext)){
exit_status('Only '.implode(',',$allowed_ext).' files are allowed!');
}
if($demo_mode){
// File uploads are ignored. We only log them.
$line = implode(' ', array( date('r'), $_SERVER['REMOTE_ADDR'], $pic['size'], $pic['name']));
file_put_contents('log.txt', $line.PHP_EOL, FILE_APPEND);
exit_status('Uploads are ignored in demo mode.');
}
// Move the uploaded file from the temporary
// directory to the uploads folder:
if(move_uploaded_file($pic['tmp_name'], $upload_dir.$pic['name'])){
exit_status('File was uploaded successfuly!');
}
}
exit_status('Something went wrong with your upload!');
// Helper functions
function exit_status($str){
echo json_encode(array('status'=>$str));
exit;
}
function get_extension($file_name){
$ext = explode('.', $file_name);
$ext = array_pop($ext);
return strtolower($ext);
}
}
Editoval CJHornster (28. 7. 2014 17:13)
- David Kudera
- Člen | 455
Já být na tvým místě, tak bych si to určitě debugoval.
Jo ale teď koukám.. Víš určitě nebude jen tak fungovat když kód z nějakýho souboru jen tak přesuneš do akce presenteru. Musíš to přepsat postupně do nette, takže použít ty odkazy a věci, co jsem ti psal nahoře. Např. vytvořit funkce exit_status a get_extension uvnitř metody presenteru určitě není tak úplně správně. Takže mrkni i do log složky, jestli tam jsou uložené nějaké chyby
- CJHornster
- Člen | 56
jj to je pravda, ale asi mám problém se vůbec dostat na server
ještě mě napadlo to udělat na prasáka a třeba v js z funkce createImage nějak volat metodu z presenteru a tý předat jméno toho filu a to uložit do DB
- David Kudera
- Člen | 455
To takhle nejde. Leda by jsi to poslal „předem“ název přes ajax a v další fázy samotný soubor a nějak je spojil.. To mi přijde ale docela dost strašný a děsivý… Napřímo totiž z js nic v php nezavoláš.
A myslím tím „asi“ jako asi jo nebo asi ne? :-)
Chtělo by to vědět na jisto. Klidně si na začátek té metody dej Debugger::log(‚funguje‘); a pak se mrkni do logu a taky na to, jestli ti to nepadá přímo na nějaké chybě, ale to taky uvidíš ve složce log
Editoval David Kudera (28. 7. 2014 20:51)
- CJHornster
- Člen | 56
tak jsem to zkoušel debugovat a funkce se vůbec neprovede
Edit1: nakonec se na to asi vykašlu a zkusím implementovat MultipleFileUpload
Edit2: Ten se mě nakonec povedlo implementovat, ale nějak se mě nedaří zaplnout vzhled uploadify
Editoval CJHornster (29. 7. 2014 10:26)