I'm using mootools request to push image data to a server to import images. My question is how to determine if an image path is valid before completing the request?
Here's what I have now--
http://jsfiddle.net/sTbFb/1/
function doUpload(){
var remoteFile = document.id('uploadRemote').get('value');
var imageRequest = new Request({
url:'index.php',
method: 'post',
data: 'path='+remoteFile,
onRequest: function() {
console.log(remoteFile);
var myimage = Asset.image(remoteFile,
{
//onError: imageRequest.cancel() // <-- this doesn't work either
onError: this.cancel()
}
);
},
onSuccess: function(response) {
alert(response);
}
}).send();
}
document.id('submit').addEvent('click', function(){
doUpload();
});
I'm trying to use Asset.image to test if a path is truly an image-- then if it's not, to cancel the request. However, it's not working out.
Any hints on what I'm doing wrong? Thanks!
You can't get the path to the selected file from an <input type="file" />. So, you won't be able to load it before you upload it. The best you can do is to check the file extension.
Edit: Perhaps the problem is with this line:
onError: this.cancel()
It should be:
onError: function () {
imageRequest.cancel();
}
Related
I have been struggling with a problem for some time. I cannot understand the reason as it happens in a specific case, not with the others.
I have a javascript function that calls a PHP script to upload a file to the server (standard code, have been using it and works perfectly normally).
function upload_picture(fieldID, success, error) {
var folderName;
switch (fieldID) {
case "pop_drawing":
folderName = "pop_dwg";
break;
case "pop_installation":
folderName = "pop_inst";
break;
case "pop_picture":
folderName = "pop_pict";
break;
}
var file_data = $('#' + fieldID).prop('files')[0];
var form_data = new FormData();
form_data.append('folder', folderName);
form_data.append('file', file_data);
$.ajax({
url: 'dbh/upload.php',
dataType: 'text',
type: 'POST',
cache: false,
contentType: false,
processData: false,
data: form_data,
success: function (response) {
event.preventDefault();
console.log (response); // display success response from the PHP script
if (response.indexOf("yüklendi") > 0) {
success();
}
},
error: function (response) {
event.preventDefault();
console.log (response); // display success response from the PHP script
error(response);
}
});
}
The function is called from several points in the code and it works OK except one point. At this particular point when it returns it changes the page URL from
http://localhost/pop/#
to
http://localhost/pop/?pop_drawing=&pop_installation=&pop_picture=Compelis-Logo.jpg&pop_need_special_prod=Hay%C4%B1r&pop_need_application=Hay%C4%B1r&pop_order_made=Evet&pop_approval=4&pop_cost_visible=Hay%C4%B1r#
due to a reason I could not understand. This string in the URL line are some parameters on the web page where I press the button to call the function.
The code which call the function is:
function uploadPopPicture () {
if ($('#pop_picture_label').html() !== 'Seçili dosya yok...') {
upload_picture('pop_picture',
function(){
console.log('Görsel yüklendi...');
},
function(error){
console.log('Error:', error);
});
}
}
Same code (obviously with different parameters) is used elsewhere in the program and works OK.
Any ideas what I might be missing.
Many thanks in advance
A button's default behaviour is "submit". If you don't specify any particular behaviour then that's what it will do. So when clicked it will submit your form, regardless of any JavaScript.
Add the attribute type="button" to your button HTML and that will stop it from automatically submitting the form.
I'm sorry for that question but I have a persistent bug and I don't understand at all what's happening ...
I have an ajax upload function that is working fine
function startUp(hash) {
$('#file_up_form').ajaxForm({
beforeSend: function(xhr) {
xhr.setRequestHeader("X-CSRF-Token", '{{ Session::token() }}' );
xhr.setRequestHeader('Sha-Sha',hash);
//other stuff
},
uploadProgress: function(event, position, total, percentComplete) {
//some stuff
},
complete : function(xhr) {
//some stuff
},
error : function(xhr) {
//some stuff
}
});
}
When I call it that way :
$("#start_up_button").on('click', function() {
if(checkFile()){
startUp('f4274dd2284704f1158b2cecd71666a37ba5b949f97fc521974f98fa3dd0ea706cca7253244e20f2a4c4c694052097c45260edfe679c9e7b56896858a34839cd');
//getHash();
}
else{
$('#myModalerror').modal('show');
$("#myModalerror").css("z-index", "1500");
}
});
Everything works fine.
But when I uncomment the second line and comment the first to call it from :
function getHash(){
input = document.getElementById('fileToUpload');
file = input.files[0];
var reader = new FileReader();
reader.onload = function(e) {
var shaObj = new jsSHA(reader.result,"BYTES");
var hash = shaObj.getHash("SHA-512", "HEX");
console.log(hash);
startUp(hash);
};
reader.readAsBinaryString(file);
}
Nothing work for ajax : the console.log display the correct hash but there are no headers set, and nothing from '//some stuff' works ... But the file is uploaded !! (??) I tried to wrap the call with a
setTimeout(function() {
startUp(hash);
}, 200);
but Firefox just crash. Any idea ??
thx
The behaviour of ajaxForm() in $('#file_up_form').ajaxForm({ ... }) is not to trigger an AJAX request.
It is an event binding function. (I've not gone through the API documentation, but probably it binds a form submit event to one of its inner library function)
To actually trigger an AJAX request you've to add a <input type="submit" > button inside the HTML <form>, and just click it. (Library will prevent traditional form submission, and submit it via AJAX)
Example implementation:
JS:
<script type="text/javascript">
$(document).ready(function(){
$("#file_up_form").ajaxForm({ // bind library function to the form
beforeSend: function(xhr){
input = document.getElementById('fileToUpload');;
file = input.files[0];
if(file){
var reader = new FileReader();
reader.readAsBinaryString(file);
var shaObj = new jsSHA(reader.result,"BYTES");
var hash = shaObj.getHash("SHA-512", "HEX");
xhr.setRequestHeader('Sha-Sha', hash);
}else{
alert("First, please select a file to upload.");
return false;
}
},
uploadProgress: function(event, position, total, percentComplete){ },
success: function() { },
complete: function(response) { },
error: function() { }
});
});
</script>
HTML:
<body>
<form id="file_up_form" action="upload.php" method="post">
<input type="file" id="fileToUpload" name="uploadedfile" />
<!-- Click on submit to perform AJAX call -->
<input type="submit" value="Upload">
</form>
</body>
Thx,
But that can't work because javascript is ***** not synchrone and I need to force the synchronisation with the reader.onload() callback and then call ajax ... the ajax request will be sent, no matter if the hash is computed or not, if I am inside .ajaxForm() it's over, even the setTimeout(function(){...}) is asynch itself too, so it has no effect the ajax request is sent ... or if I place it in an other place it just crash firefox ...
I have an upload button to trigger the request as you mention of course, and it is the only trigger I have to process the computation of the sha-512 first and then trigger ajax with the form binding.
But what I don't understand is :
why "startUp('ARandomHash');" works perfectly inside the $("#start_up_button").on('click', function() {...}); and "hash=...; console.log(hash); startUp(hash);" print the correct hash but ajax is a total fail inside the reader.onload() callback ... the event is trigger by the same click event, it has just 2 scope of execution more ...
I don't think I am loosing the submit event with these 2 scope more because the file is uploaded correctly ... it is just the beforeSend:..., uploadProgress:..., etc that are not executed.
I think I'll rather try to cast hash, it may be a character encoding problem, it has no sense otherwise, it should fail for the "startUp('ARandomHash');" as well ...
But thx, if someone has a better idea =)
I have an issue trying to remove the files which I have passed dropzone.js after calling the database.
When I navigate to the page and upload a new image and then remove it without refreshing the page it all works as expected.
Below is my current upload method
myDropzone.on("success", function (file, response) {
console.log(response);
file.serverId = response;
});
This is what is inside the response after doing console.log(response);
Object { UniqueId="evgopvdjfs1w9sos3jt5"}
Which is correct.
Now when I press F5 and refresh the page I populate dropzone with the following snippet which returns me the image that I've just uploaded.
$.getJSON("/Person/GetPreviews/").done(function (data) {
if (data.Data != '') {
$.each(data.Data, function (index, item) {
var UniqueId = item.ImageName;
var mockFile = {
name: item.ImageName,
serverId: UniqueId // This is what I need to delete the image
};
console.log(mockFile);
// Call the default addedfile event handler
myDropzone.emit("addedfile", mockFile);
// And optionally show the thumbnail of the file:
myDropzone.emit("thumbnail", mockFile, item.ImageUrl);
myDropzone.files.push(mockFile);
});
}
});
Now when I do console.log(mockFile); the below is shown, again this is correct.
Object { name="evgopvdjfs1w9sos3jt5", UniqueId="evgopvdjfs1w9sos3jt5"}
Now when it comes to removing the file this is my current delete function
removedfile: function (file) {
console.log(file);
$.ajax({
type: 'POST',
url: '#Url.Action("DeleteUploadedFile", "Person", new {userId= #Model.UserId})',
data: "id=" + file.serverId['UniqueId'],
dataType: 'html',
});
var ref;
return (ref = file.previewElement) != null ? ref.parentNode.removeChild(file.previewElement) : void 0;
},
Now when I press remove file on the pre populated image from the database, it throws an error on
data: "id=" + file.serverId['UniqueId'],
saying its underfined, I personally cannot see how because both console.logs show the UniqueId it makes me wonder if I'm missing something when I'm pre populating dropzone with the images?
As you can see I have a console.log(file); in the delete function which when hit shows the following
Object { name="evgopvdjfs1w9sos3jt5", UniqueId="evgopvdjfs1w9sos3jt5"}
Can anyone see whats wrong?
So this question is a bit old. I came across it and also found this answer, which helped me:
http://www.stackoverflow.com/questions/24445724/add-existing-image-files-in-dropzone
This particular question was answered here and just points out a mix-up between serverId and UniqueId:
https://github.com/enyo/dropzone/issues/844
The reading works.
However I got a syntax error in the firefox console (which is tiresome when I read 30 files).
The files are annotation files like (time \t value) with no headers like :
0.0 5.2
0.5 5.6
1.0 6.3
...
This is the ajax code :
function getdatafromfile(filename) {
// Read annotation file. Example : %timeinstant \t %value \n
// Return an array of string
var arraydata
$.ajax({
type: "GET",
url: filename,
dataType: "text",
async: false,
success: function(csv) {arraydata = $.csv.toArrays(csv,{separator:'\t'}); }
});
return arraydata}
And with d3:
d3.text(filename, function(text) {
var data = d3.tsv.parseRows(text).map(function(row) {
return row.map(function(value) {
return +value;
});
});
console.log(data);
});
}
It seems that I could use one of those code, but I got a syntax error in both cases (with firefox 33.1).
A file reader could work like the code below.
In the example I've added a flag to use the content of the variable instead of a file. That's just for the demo and can be removed. The same code is here as jsFiddle.
Maybe you could add some validation before or after the $.csv method. So you know that the file was a csv/tsv file.
If you need to open the file with-out user interaction, you have to look for something different because JS is not allowed to open a file with-out the user choosing the file (security concerns, see this SO question).
You could add your data to a database and read it from there. e.g. Firebase or MongoDB or use a JSON file. The code of my other answer should work for a JSON file that you host with your webpage.
var demoTxt = "0.0 5.2\
0.5 5.6\
1.0 6.3";
var flag_usedemofile = true; //if true var demoTxt will be used
function doOpen(evt) {
var files = evt.target.files,
reader = new FileReader();
reader.onload = function() {
if ( !flag_usedemofile) {
var arraydata = $.csv.toArrays(this.result,{separator:' '});
showout.value = arraydata; //this.result;
} else {
var arraydata = $.csv.toArrays(demoTxt,{separator:' '});
showout.value = arraydata;
console.log(arraydata);
}
};
reader.readAsText(files[0]);
}
var openbtn = document.getElementById("openselect"),
showout = document.getElementById("showresult");
openselect.addEventListener("change", doOpen, false);
#showresult {
width:98%;
height: 300px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery-csv/0.71/jquery.csv-0.71.min.js"></script>
<input type="file" id="openselect" />
<textarea id="showresult"></textarea>
I'm not exactly sure what syntax error you are getting. But I think the error have something to do with the mime type of your json request.
I think the best way is to wrap your data in json and then use JSONP. (I have also tried to get it working with text/plain, but with-out success.)
Please check the following example for details. You can also find the same example on
jsFiddle.
(function ($) {
var url = 'http://www.mocky.io/v2/547c5e31501c337b019a63b0'; // dummy url
var jsonCallback = function (csv) {
var arraydata;
console.log(data);
$('#data').html(JSON.stringify(csv, null, 2));
arraydata = $.csv.toArrays(csv.data,{separator:'\t'});
console.log(arraydata);
};
$.ajax({
type: 'GET',
url: url,
contentType: "application/json",
dataType: 'jsonp'
}).done(jsonCallback)
.fail(function (xhr) {
alert("error" + xhr.responseText);
});
})(jQuery);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<pre id='data'></pre>
I don't really know what's going on here. Every time I try to upload a file, all the file contains is:
------WebKitFormBoundaryJ0uWMNv89fcUsC1t--
I have searched for the past 2 days for some sort of explanation, but I am just going in circles. I have no idea why this is happening.
Form:
<form id="upload-file" ecntype="multipart/form-data">
<input name="picture" type="file">
<input type="button" value="Upload" id="upload-button" />
</form>
Javascript:
$('#upload-button').click(function(e){
e.preventDefault();
var formData = new FormData($('#upload-file'));
$.ajax({
url: '/image',
type: 'POST',
xhr: function() {
var myXhr = $.ajaxSettings.xhr();
if(myXhr.upload){
myXhr.upload.addEventListener('progress',progressHandlingFunction, false);
}
return myXhr;
},
data: formData,
cache: false,
// contentType: false,
processData: false
});
});
Controller:
def image = Action(parse.temporaryFile) { request =>
request.body.moveTo(new File("/tmp/picture"))
Ok("File uploaded")
}
The problem was occuring in the Javascript, not the Scala. I was not referencing the form elements improperly.
var formData = new FormData($('#upload-file')[0]);
However, I also had problems with parse.temporaryFile and it was not properly storing the file using the code above. When I inspected the stored files in a text editor, I noticed it still had the ------WebKitFormBoundaryJ0uWMNv89fcUsC1t-- stuff at the beginning of the file, followed by the form information, then followed by the file bytes.
To fix this, I just used the default method for multipartform upload as per the Play Documentation, and it worked perfectly.
def image = Action(parse.multipartFormData) { request =>
request.body.file("picture").map { picture =>
val filename = picture.filename
picture.ref.moveTo(new File(s"/tmp/picture/$filename"))
Ok("ok")
}.getOrElse {
InternalServerError("file upload error")
}
}