IF statement to check if file exists in path not working - javascript

I am trying to check if a file from a multiple upload exists in the path already, if so i want to chuck out a validation error. Its the else if part that is not working. The number directory gets created in the ajax controller server side, but i want to do a check before they upload further files with the same name to that directory. Is this possible? What am i doing wrong here?
function makeProgress(number){
var url = getRelativeURL("web/fileUpload");
var formData = new FormData();
formData.append('number', number);
fls = document.getElementById("attachmentFileUploadInput").files; //number of files...
console.log(fls);
var location = "C:/temp/" + number + "/";
console.log(location);
// maximum number of files at a time is 10
if(fls.length >= 11){
FileUploadLengthVisible(true);
return false;
}
var j;
for(j=0;j<fls.length;j++){
if (fls[j].size > 5000000) //5MB size per file
{
FileUploadSizeVisible(true);
return false;
}
else if (location + fls[j] == true)
{
alert("file exists");
return false;
}
else
{
formData.append('files[]', fls[j]); //note files[] not files
$.ajax({
url : url,
data : formData,
processData : false,
cache: false,
contentType: false,
type : 'POST',
success : function(data) {
FileUploadVisible(true);
$('#attachmentModal').modal('hide')
$(':input','#attachmentModal').val("");
$("#pbarmain").hide();
$("#pbar").hide();
$("#actionPlanDiv").hide();
setObjectEnabled('#Upload',false);
},
error : function(err) {
FileUploadErrorVisible(true);
}
});
console.log('loop each file working');
}
}
console.log("form data " + formData);
}

Related

How I can use $_FILES value without input that has `file` attribute?

In my case I manipulate an image using client-side javascript, because I want to scale it before uploading it:
$("#base_img_to_compress").on("change", (e) => {
resizeImage(source, 1440, 1080).then((imgData) => {
appendToFormHiddenImageInput("base_img_data",imgData);
});
});
$("#upload_form").on("submit",(e)=>{
$.ajax({
method:"POST",
//How I can configure the postdata here ?
})
});
function appendToFormHiddenImageInput(name, imgData) {
const child = $("#upload_form").children("input[name=" + name + "]");
if (child.length > 0) {
child.remove();
}
const input = document.createElement('input');
input.type = "hidden";
input.setAttribute("type", "hidden");
input.setAttribute("name", name);
input.setAttribute("value", imgData);
$("#upload_form").append(input);
}
function resizeImage(element, width, height) {
const element_file = element.files[0];
return imageConversion.compressAccurately(element_file, {
quality: 0.7,
type: "image/png",
width: width,
height: height,
size: 80
}).then((file) => {
return imageConversion.filetoDataURL(file);
})
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/WangYuLue/image-conversion/build/conversion.js"></script>
<form id="upload_form">
<button type="submit" id="savebtn">Save me</button>
</form>
<input id="base_img_to_compress" type="file" />
The php script that handles the upload is rather simple:
$file = $_FILES['base_img_data'];
if($file['tmp_name']){
echo "FILE UPLOADED";
exit;
}
echo "FILE NOT UPLOADED";
But in order for $_FILES to work need the data to be uploaded as multipart/form-data where the base_img_data must be encoded as base64 string. Is there a way to do this at my javascript without using an <input type="file" /> input element as w3schools say so?
In other words the part that troubles me is this piece of javascript:
$("#upload_form").on("submit",(e)=>{
$.ajax({
method:"POST",
//How I can configure the postdata here ?
})
});
I mean, I need to populate the ajax accordingly in order to emulate a multipart form upload without using an input field that has file attribute. But in my case, I use hidden input fields with values encoded as base64, therefore the PHP won't recognize the incoming uploaded file using $_FILES magic variable.
Quick Answer
You have to manually build your own FormData object. This is an approach:
const formData = new FormData();
$("#upload_form :input").each((index,element)=>{
let value = $(element).val();
if($(element).attr('type') == "hidden"){
formData.append($(element).attr('name'),DataURIToBlob(value),`myfile_${index}.png`);
}
formData.append($(element).attr('name'),value);
});
function DataURIToBlob(dataURI) {
const splitDataURI = dataURI.split(',')
const byteString = splitDataURI[0].indexOf('base64') >= 0 ? atob(splitDataURI[1]) : decodeURI(splitDataURI[1])
const mimeString = splitDataURI[0].split(':')[1].split(';')[0]
const ia = new Uint8Array(byteString.length)
for (let i = 0; i < byteString.length; i++){
ia[i] = byteString.charCodeAt(i)
}
return new Blob([ia], { type: mimeString })
}
Then do the ajax call like that:
$.ajax({
method:"POST",
data: formData,
url: "./script.php",
processData: false,
contentType: false,
success: ()=>{
alert("BANZAI");
}
})
In your example a complete submit method is:
$("#upload_form").on("submit",(e)=>{
e.preventDefault();
const formData = new FormData();
$("#upload_form :input").each((index,element)=>{
let value = $(element).val();
if($(element).attr('type') == "hidden"){
console.log(formData);
formData.append($(element).attr('name'),DataURIToBlob(value),`myfile_${index}.png`);
}
formData.append($(element).attr('name'),value);
});
$.ajax({
method:"POST",
data: formData,
url: "./script.php",
processData: false,
contentType: false,
success: ()=>{
alert("BANZAI");
}
})
});
function DataURIToBlob(dataURI) {
const splitDataURI = dataURI.split(',')
const byteString = splitDataURI[0].indexOf('base64') >= 0 ? atob(splitDataURI[1]) : decodeURI(splitDataURI[1])
const mimeString = splitDataURI[0].split(':')[1].split(';')[0]
const ia = new Uint8Array(byteString.length)
for (let i = 0; i < byteString.length; i++){
ia[i] = byteString.charCodeAt(i)
}
return new Blob([ia], { type: mimeString })
}
Please notice that upon ajax alongside with data option I use these options as well:
processData: false,
contentType: false,
If they are not set to false then the upload won't happen.
What if I also have/populate hidden input fields that do not contain file data?
Upon placing input differentiate it using a data attribute, for example, data-file once you dynamically add it. In your example an approach should be to replace the following function:
function appendToFormHiddenImageInput(name, imgData) {
const child = $("#upload_form").children("input[name=" + name + "]");
if (child.length > 0) {
child.remove();
}
const input = document.createElement('input');
input.type = "hidden";
input.setAttribute("type", "hidden");
input.setAttribute("name", name);
input.setAttribute("value", imgData);
input.setAttribute("data-file",true); // <<< This appends the distingushing indicator
$("#upload_form").append(input);
}
The use the following submit method:
$("#upload_form").on("submit",(e)=>{
e.preventDefault();
const formData = new FormData();
$("#upload_form :input").each((index,element)=>{
let value = $(element).val();
if($(element).attr('type') == "hidden" && $(element).data('file') === true ){
console.log(formData);
formData.append($(element).attr('name'),DataURIToBlob(value),`myfile_${index}.png`);
}
formData.append($(element).attr('name'),value);
});
$.ajax({
method:"POST",
data: formData,
url: "./script.php",
processData: false,
contentType: false,
success: ()=>{
alert("BANZAI");
}
})
});
function DataURIToBlob(dataURI) {
const splitDataURI = dataURI.split(',')
const byteString = splitDataURI[0].indexOf('base64') >= 0 ? atob(splitDataURI[1]) : decodeURI(splitDataURI[1])
const mimeString = splitDataURI[0].split(':')[1].split(';')[0]
const ia = new Uint8Array(byteString.length)
for (let i = 0; i < byteString.length; i++){
ia[i] = byteString.charCodeAt(i)
}
return new Blob([ia], { type: mimeString })
}
Pay attention to the line:
if($(element).attr('type') == "hidden" && $(element).data('file') === true )
I also check if the field is an input file or not.
Also pay attention to:
input.setAttribute("data-file",true);
Why does it work?
It works because using form-data you make a POST encoded as multipart/form-data. $_FILES is a parsed value from a body that seems to be a file. In our case we re-constructed the form as multipart one at line:
formData.append($(element).attr('name'),DataURIToBlob(value),`myfile_${index}.png`);
At function appendToFormHiddenImageInput
Miscellanous
In my case I set a name with fixed file extension, if you want to manage it manually use the blob type. I could do it like this:
const name = `myfile_${index}`
value = DataURIToBlob(value);
let suffix = 'png'
swich(value.type)
{
// handle suffix here
}
name = `${name}.${suffix}`
formData.append($(element).attr('name'),value,name);
Replacing the:
formData.append($(element).attr('name'),DataURIToBlob(value),`myfile_${index}.png`);
Also, I made sure, that on the php side I had the appropriate value on upload_max_filesize setting it php.ini.

While uploading multiple input files to the document library, Ajax executes after the loop ends in jQuery

I'm having a problem when using the jQuery .each() and .ajax() functions together when i want to upload all input file to SharePoint document library .
function checkAttachments(NewlyCreatedItemId)
{
$("[type='file']").each(function(){
var FileUploaderID=$(this).attr("id");
var attachfor=$(this).attr("alt");
var file = document.getElementById(FileUploaderID.toString()).files[0];
if (file != undefined) {
uploadDocument(FileUploaderID,attachfor,NewlyCreatedItemId);
}
else {
alert('Please, upload attachments for ');
}
});
}
function uploadDocument(uploader,attachfor,createdID) {
var files = $("#"+uploader+"")[0].files;
if (files.length > 0) {
var fileName = files[0].name;
var webUrl = _spPageContextInfo.webAbsoluteUrl;
var documentLibrary = "ClaimAttachments";
var targetUrl = _spPageContextInfo.webServerRelativeUrl + "/" + documentLibrary;
// Construct the Endpoint
var url = webUrl + "/_api/Web/GetFolderByServerRelativeUrl(#target)/Files/add(overwrite=true, url='" + fileName + "')?#target='" + targetUrl + "'&$expand=ListItemAllFields";
uploadFileToFolder(files[0], url, function(data) {
var file = data.d;
var DocFileName = file.Name;
var updateObject = {
__metadata: {
type: file.ListItemAllFields.__metadata.type
},
FileLeafRef: DocFileName , //FileLeafRef --> Internal Name for Name Column
AttachFor : attachfor ,
RequestGUID : createdID
};
alert("File uploaded successfully!");
}, function(data) {
alert("File uploading failed");
});
} else {
alert("Kindly select a file to upload.!");
}
}
function getFileBuffer(uploadFile) {
var deferred = jQuery.Deferred();
var reader = new FileReader();
reader.onloadend = function(e) {
deferred.resolve(e.target.result);
}
reader.onerror = function(e) {
deferred.reject(e.target.error);
}
reader.readAsArrayBuffer(uploadFile);
return deferred.promise();
}
function uploadFileToFolder(fileObj, url, success, failure) {
var apiUrl = url;
// Initiate method calls using jQuery promises.
// Get the local file as an array buffer.
var getFile = getFileBuffer(fileObj);
// Add the file to the SharePoint folder.
getFile.done(function(arrayBuffer) {
$.ajax({
url: apiUrl,//File Collection Endpoint
type: "POST",
data: arrayBuffer,
processData: false,
async: false,
headers: {
"accept": "application/json;odata=verbose",
"X-RequestDigest": jQuery("#__REQUESTDIGEST").val(),
},
success: function(data) {
success(data);
},
error: function(data) {
success(data);
}
});
});
}
it uploads the file of the first file uploader only because when it reach to the ajax call in function (uploadFileToFolder) go to the next iteration, how to can solve it .

How Do I Send The File Data Without Form With Ajax On Server?

I've coded a javascript code which nicely collects every file user wants to upload. But things turned when I added drag/drop file option.
By default, I had a code which monitored input[type='file'] change event handler and once it was detected, actions were performed and files were sent to server for upload.
But since drag/drop doesn't change the input[type='file'] value and neither I can change it programmatically due to security reasons, I'm struck how do I send files which are dragged and dropped on the site.
Here's some of my code:
document.getElementById('drop').addEventListener('drop', function (e) {
e = e || window.event;
e.preventDefault();
var dt = e.dataTransfer;
var files = dt.files;
for (var i=0; i<files.length; i++) {
var file = files[i];
var reader = new FileReader();
reader.readAsDataURL(file);
addEventHandler(reader, 'loadend', function(e, file) {
var bin = this.result;
var filename = file.name;
var filesize = (file.size/1048576).toFixed(2) + ' MB';
alert(' '+filename+' '+filesize+' '); // DEBUGGING ONLY
console.log("YEAY");
if(filecheck(filename)) { // Additional Function
step2(filesize, filename, bin); // Additional Function
$('.btn').click(function() { // Button to be clicked to start upload
$('#main_img_upload').submit(); // Form with that input[type='file']
});
}
else {
alert("Wrong File");
return false;
}
}.bindToEventHandler(file), false);
}
return false;
});
Obviously, it starts upload but server doesn't receive anything as no change has been made to form. But I have all the necessary details (name of file, size of file, etc..)
Any help would be appreciated.
Try out this code.
data.append("FileName", files[0]);
$.ajax({
url: "../",
type: "POST",
processData: false,
contentType: false,
data: data,
success: function (data) {
if (data) {
}
},
error: function (er) {
MSGBox(er);
}
});
}

How to get uploaded images from Parse using javascript API

Problem:
I have the Url (eg. http://files.parse.com/../../..jpg ) of the uploaded file and it's fileName, and now need to retrieve the corresponding file from that Url(Parse.com) by using Only via Javascript . Any one have the answer let me know. Thank you very much!
Code: (upload):
function uploadFn(fileName,fileType,fileData,c){
var parseUrl='https://api.parse.com/1/files/'+fileName;
$.ajax({
type:'post',
beforeSend:function(req){
req.setRequestHeader('X-Parse-Application-Id',myParseAppId);
req.setRequestHeader('X-Parse-REST-API-Key',myParseRestApiId);
req.setRequestHeader('Content-Type',fileType); // fileType always == 'image/jpg;'
},
url:parseUrl,
data:fileData,
processData:false,
contentType:false,
success:function(rslt){
if(rslt){
alert('Upload success\n Filename:'+rslt.name+'\n Url:'+rslt.url);
imgObj.save({curUser:curUser,fileName:rslt.name,fileUrl:rslt.url,fileId:c},
{success:function(succ){
alert('File info saved!');
},error:function(err){
alert('Error:'+err.code);
}
}) // save
}
},
error:function(err){
//var errObj=jQuery.parseJSON(err);
alert('Error:'+err.responseText);
}
});
}
upload is not a problem. It works fine! Only for retrieving from Parse.com
(toRetrieve) [I tried as: ]
function fetchImg(url){
$.ajax({
url:url,
async:false,
type:'POST',
beforeSend:function(req){
req.setRequestHeader('X-Parse-Application-Id',myParseAppId);
req.setRequestHeader('X-Parse-REST-API-Key',myParseRestApiId);
req.setRequestHeader('Content-Type','image/jpg');
},
complete:function(rslt){
$('#imgId').attr('src','data:image/jpg;base64,'+rslt.responseText);
},
success:function(){//Success
},
error:function(err){
alert('Error: '+err.responseText+'\nStatus: '+err.statusText);
}
})
}
[output:]
'Error-msg>The specified method not allowed against this resouce' Status: Method Not allowed!.
Notes: ¤ (I saved the fileName, fileUrl to the Parse DataBrowser, and used this for try to retrieve the uploaded file.)
¤ (App is based on 'Phonegap')
¤ Im novice to Parse/Javascript.
Thanks a lot! *
Check here: Load contents of image from camera to a file
basically: with the info in this post. . Big thanks to Raymond Camden!
function gotPic(data) {
window.resolveLocalFileSystemURI(data, function(entry) {
var reader = new FileReader();
reader.onloadend = function(evt) {
var byteArray = new Uint8Array(evt.target.result);
var output = new Array( byteArray.length );
var i = 0;
var n = output.length;
while( i < n ) {
output[i] = byteArray[i];
i++;
}
var parseFile = new Parse.File("mypic.jpg", output);
parseFile.save().then(function(ob) {
navigator.notification.alert("Got it!", null);
console.log(JSON.stringify(ob));
}, function(error) {
console.log("Error");
console.log(error);
});
}
reader.onerror = function(evt) {
console.log('read error');
console.log(JSON.stringify(evt));
}
entry.file(function(s) {
reader.readAsArrayBuffer(s);
}, function(e) {
console.log('ee');
});
});
}
I think to retrieve the image method should be GET instead of POST for your ajax request.

Image upload to facebook from clientside using FormData() - what's wrong?

On input file change event, I am executing the following code.
create a form data by encoding the image to "multipart/form-data"
alert('before calling FB.api-post :' + imgFile.name) - this works
create the param to be used in FB.api
call FB.api - but this never
gets executed. - what's wrong ?
var fData = new FormData();
var imgFile = $('input[type="file"]')[0].files[0];
fData.append("image", imgFile);
alert('before calling FB.api-post :' + imgFile.name);
var params = {
"access_token": $D("access_token"),
"message": $D("img_message"),
"upload file": true,
"source":fData
}
FB.api('/me/photos', 'POST', params,
function (response) {
alert('asasasasasasasasasasasasas');
if (!response || response.error) {
$D("preview").innerHTML = "Error in facebook Photo UPLOAD : " + response.error;
alert('Error in facebook Photo UPLOAD : ' + response.error);
}
else {
$D("preview").innerHTML = "Photo UPLOADED : " + response;
alert('uploaded');
}
}
);
});
Note: $D is nothing but the following shortcut
function $D(element) {
return document.getElementById(element);
}

Categories

Resources