What I am trying to do is updating AngularJS variable from controller function and when I console its updated instantly but when I print it on View it updates after about 5-8 secs.
I try with both ng-model and curly braces but in both cases it after few seconds in view but in console its updated instantly.
I call uploadedMedia function in fine uploader callback and its working fine with console.log
$scope.UploadedMedia = function(){
console.log($scope.Album[0].Media.length);
$scope.UploadedMediaVal = $scope.Album[0].Media.length;
console.log($scope.Album[0].Media.length);
}
$scope.initFineUploader = function(){
var fcnt = 0;
var iuploader = new qq.FineUploaderBasic({
multiple: true,
autoUpload: true,
title: "Attach Photos",
button: $("li[data-type='uploadMediabutton']")[0],
request: {
endpoint: site_url + "api/uploadimage",
customHeaders: {
"Accept-Language": accept_language
},
params: {
Type: 'ratings',
unique_id: function() {
return '';
},
LoginSessionKey:LoginSessionKey,
DeviceType:'Native'
}
},
maxConnections : 50,
validation: {
acceptFiles: '.bmp,.jpeg,.jpg,.gif,.png',
allowedExtensions: ['bmp','jpeg', 'jpg', 'gif', 'png', 'JPEG', 'JPG', 'GIF', 'PNG'],
sizeLimit: 4194304 // 40mb
},
callbacks: {
onUpload: function(id, fileName) {
$scope.Album[0].Media.push({MediaGUID:'',ImageName:'',Caption:'',MediaType:'Image',VideoLength:'',ConversionStatus:'',IsLoader:'1',FileName:fileName});
$scope.UploadedMedia();
$('.rating-submit').attr('disabled','disabled');
fcnt++;
},
onProgress: function(id, fileName, loaded, total) {
$scope.Uploading = 1;
},
onComplete: function(id, fileName, responseJSON) {
fcnt--;
if (responseJSON.Message == 'Success') {
$($scope.Album[0].Media).each(function(mk,mv){
if(mv.FileName == fileName){
$scope.Album[0].Media[mk]['MediaGUID'] = responseJSON.Data.MediaGUID;
$scope.Album[0].Media[mk]['ImageName'] = responseJSON.Data.ImageName;
$scope.Album[0].Media[mk]['IsLoader'] = 0;
}
});
var fNameExt = fileName.substr(fileName.lastIndexOf('.') + 1);
$('li[data-filename="'+fileName+'"]').remove();
setTimeout(function(){
$('li[data-filename="'+fileName+'"] .m-laoder').remove();
},1000);
} else {
$('li[data-filename="'+fileName+'"]').remove();
}
if(fcnt <= 0){
$scope.Uploading = 0;
$('.rating-submit').removeAttr('disabled');
$('.attached-media-list li.media-loader').remove();
}
$scope.UploadedMedia();
},
onValidate: function(b) {
if($scope.Album[0].Media.length>=10){
showResponseMessage('You can upload maximum 10 images, please delete any old image to upload new one.','alert-danger');
return false;
}
var validExtensions = ['bmp','jpeg', 'jpg', 'gif', 'png', 'JPEG', 'JPG', 'GIF', 'PNG']; //array of valid extensions
var fileName = b.name;
var fileNameExt = fileName.substr(fileName.lastIndexOf('.') + 1);
if ($.inArray(fileNameExt, validExtensions) == -1) {
showResponseMessage('Allowed file types only bmp, jpeg, jpg, gif and png.','alert-danger');
return false;
}
if (b.size > 4194304) {
showResponseMessage('Image file should be less than 4 MB','alert-danger');
}
},
onError: function(){
$('.attached-media-list li.media-loader:last-of-type').remove();
}
}
});
}
<div>
{{UploadedMediaVal}}
<span ng-bind="UploadedMediaVal"></span>
</div>
Write $scope.$apply();, after modifying your variable.
How do you invoke SomeOtherFunction? Is it triggered in the angular digest phase or by a dom event. In the second case you have to wrap the commands with a $scope. $apply (){}
Here is sample demo you code that may help you http://dojo.telerik.com/UmIvO
But I think is it possible to share you album array to test
I have tested it is giving immediate response could you please check with your album array. So that may help you out.
Related
Hello to everyone here!
First, I searched for duplicate posts but I've not found something like my issue.
I'm making some tests (you will see some repeat in my code) to upload multiple files with bootstrap fileinput and I have some issues using the "delete" button on thumbnail previews.
The upload function is working fine, showing already uploaded images if exists with initialPreview option.
I'm trying to dynamically create the intialPreviewConfig option, and for the moment I don't know why it's not working (clicking the "delete" button give no actions at all, it's like the option is not present). However, when I manually add the intialPreviewConfig (not in a variable), it's magically working fine.
Sample javascript code (some of values are different in my true code) :
var e = 'http://localhost/foo/';
// Where other_prev is an array of img
// Where other_images_path is an array of paths to images
var other_prev = ['...'];
var other_images_path = ['...'];
var uploadOtherFileInput = function ($input) {
console.log(other_prev); // Okay : array with img tags
console.log(other_images_path); // Okay : array with urls to images
var id_to_upload;
// If id already exists
if($('#id').length) {
id_to_upload = $('#id').val();
} else {
id_to_upload = $('#id_to_upload').val();
}
// Construct initial preview config for deleting images
var initialPreviewConfig = [];
if(Array.isArray(other_images_path)) {
var xhr;
// Convert paths of images to blob objects
for(var i = 0; i < other_images_path.length; i++) {
(function (i) {
xhr = new XMLHttpRequest();
xhr.open('GET', other_images_path[i], true);
xhr.responseType = 'blob';
xhr.onload = function (ev) {
if (this.status == 200) {
var blobFile = this.response;
var splitted_path = other_images_path[i].split('/');
var img_name = splitted_path[splitted_path.length - 1];
blobFile.name = img_name;
initialPreviewConfig.push({
"caption": img_name,
"size": blobFile.size,
"url": e + 'ajax/delete_image',
"key": i + 1
});
}
};
xhr.send();
}).call(this, i);
}
}
// Console log is working
console.log(initialPreviewConfig);
// Making the bootstrap fileinput
// Working fine to show previews and upload new images
// Not working for initialPreviewConfig to delete images
$input.fileinput({
language: 'fr',
allowedFileExtensions: ["jpg", "jpeg", "png"],
uploadUrl: e + 'ajax/upload_image_sup',
uploadAsync: false, // Permet d'obtenir toutes les images en une fois et d'attendre la fin
minFileCount: 0,
maxFileCount: 20,
resizeImage: true,
showClose: false,
showCaption: false,
showBrowse: true,
showUpload: false,
showUploadedThumbs: false,
showPreview: true,
uploadExtraData: function () {
var out = {};
out.id = id_to_upload;
return out;
},
layoutTemplates: {
footer: '<div class="file-thumbnail-footer">\n' +
' <div class="file-caption-name" style="width:{width}">{caption}</div>\n' +
' {actions}\n' +
'</div>',
actions: '<div class="file-actions">\n' +
' <div class="file-footer-buttons">\n' +
' {delete} {zoom}' +
' </div>\n' +
' {drag}\n' +
' <div class="file-upload-indicator" title="{indicatorTitle}">{indicator}</div>\n' +
' <div class="clearfix"></div>\n' +
'</div>'
},
initialPreviewFileType: 'image',
initialPreview: other_prev,
initialPreviewConfig: initialPreviewConfig
});
// Okay it's a repeat thing but it's just for test purposes
if(Array.isArray(other_images_path)) {
var xhr;
for(var i = 0; i < other_images_path.length; i++) {
(function (i) {
xhr = new XMLHttpRequest();
xhr.open('GET', other_images_path[i], true);
xhr.responseType = 'blob';
xhr.onload = function (e) {
if (this.status == 200) {
var blobFile = this.response;
var splitted_path = other_images_path[i].split('/');
var img_name = splitted_path[splitted_path.length - 1];
blobFile.name = img_name;
// Add preview to stack for overwrite
$input.fileinput('addToStack', blobFile);
}
};
xhr.send();
}).call(this, i);
}
}
};
Console logs of other_prev and other_images_path are okay to create the previews.
Now the console log of the variable initialPreviewConfig is (width is not present but I removed it, no changes) :
[]
0: {caption: "xxx.jpeg", size: 381939, url: e + "ajax/delete_image", key: 1}
1: {caption: "yyy.jpeg", size: 381939, url: e + "ajax/delete_image", key: 2}
2: {caption: "zzz.jpeg", size: 381939, url: e + "ajax/delete_image", key: 3}
3: {caption: "aaa.jpeg", size: 381939, url: e + "ajax/delete_image", key: 4}
4: {caption: "bbb.JPG", size: 2442700, url: e + "ajax/delete_image", key: 5}
length: 5
__proto__: Array(0)
So everything seems to be OK... But that is not working for deleting.
However, if I manually create the config it's working "fine" (the ajax/delete_image route is not created at the moment but the click is OK and I get an error for this).
Example (values are not important here) :
...
initialPreviewFileType: 'image',
initialPreview: other_prev,
initialPreviewConfig: [
{caption: "xxx.jpg", size: 576237, width: "120px", url: e + "ajax/delete_image", key: 1},
{caption: "yyy.jpg", size: 576237, width: "120px", url: e + "ajax/delete_image", key: 2},
...
]
...
Can somebody help me with this issue or facing / faced the same ?
Tell me if you want more examples or a JSFiddle.
For this test, I'm using :
PHP 5.6 with framework CodeIgniter 3
Chrome 75
Bootstrap 3.3.7
jQuery 3.1.1
Bootstrap Fileinput 4.4.3
I also could use jQuery ($.ajax, $.get...) instead of XMLHttpRequest but it's not the question I think.
Thanks!
Good day!
Okay so it was as always an async problem.
It could be solved in many ways like promises or callback functions, but to keep consistent with the code I'm now creating the array of objects from the server before loading the page (like initialPreview thumbnails).
Sorry for the inconvenience!
I am trying to add offline functionality to my HTML5 video player. I am attempting to write the files into the chrome file system as a blob and then read them from there. I believe that I am running into an issue where the files are not actually being written, just the file name. As my below code is currently constituted, it works, though still only if it is permanently connected to the internet. My goal is to have the files download to a persistent directory in the filesystem and then continue to play if the internet is disconnected.
$(document).ready(function() {
var dir = "http://www.kevmoe.com/networks/gsplayer/";
var fileextension = ".mp4";
var srcfiles = $.ajax({
//This will retrieve the contents of the folder if the folder is configured as 'browsable'
url: dir,
success: function(data) {
//List all .mp4 file names in the page
$(data).find("a:contains(" + fileextension + ")").each(function() {
var filename = $(this).attr("href").replace(window.location.host, "").replace("http://", "");
$("#container").append("<div id='div1' class='video'><video id='video1' class='vidarray' preload='none' poster='bkg.png'><source src='" + filename + "' type='video/mp4'></video></div>");
async: false;
window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;
window.requestFileSystem(window.PERSISTANT, 200000 * 1024 * 1024, initFS, errorHandler);
function initFS(fs) {
console.log('filesystem engaged'); // Just to check if everything is OK :)
// place the functions you will learn bellow here
function errorHandler(err) {
var msg = 'An error occured: ';
};
function createDir(rootDir, folders) {
rootDir.getDirectory(folders[0], {
create: true
}, function(dirEntry) {
if (folders.length) {
createDir(dirEntry, folders.slice(1));
}
}, errorHandler);
};
createDir(fs.root, 'files/video/'.split('/'));
fs.root.getDirectory('video', {}, function(dirEntry) {
var dirReader = dirEntry.createReader();
dirReader.readEntries(function(entries) {
for (var i = 0; i < entries.length; i++) {
var entry = entries[i];
if (entry.isDirectory) {
console.log('Directory: ' + entry.fullPath);
} else if (entry.isFile) {
console.log('File: ' + entry.fullPath);
}
}
}, errorHandler);
}, errorHandler);
fs.root.getFile(filename, {
create: true,
exclusive: true
}, function(fileEntry) {
fileEntry.createWriter(function(fileWriter) {
var blob = new Blob([data], {
type: 'video/mp4'
});
fileWriter.write(blob);
}, errorHandler);
console.log('file downloaded');
}, errorHandler);
//Try to add an event listener for when all files are finished loading into file system. Then use another function to source the videos locally.
var dirReader = fs.root.createReader();
var entries = [];
// Call the reader.readEntries() until no more results are returned.
dirReader.readEntries(function(results) {
//List all .mp4 file names in the page
$(results).find("a:contains(" + fileextension + ")").each(function() {
var filename = $(this).attr("href").replace(window.location.host, "").replace("http://", "");
$("#container").append("<div id='div1' class='video'><video id='video1' class='vidarray' preload='none' poster='bkg.png'><source src='" + filename + "' type='video/mp4'></video></div>");
async: false;
}, errorHandler);
});
};
function errorHandler() {
console.log('An error occured');
};
});
var videos = $('.video');
//handle ending of video
videos.find('video').on('ended', function() {
playNextVideo(videos);
});
// start with the first one
playNextVideo(videos);
function playNextVideo(videoList) {
var activeVideo = videoList.filter('.active').removeClass('active'), // identify active video and remove active class
activeIndex = videoList.index(activeVideo), // get the active video index in the group
nextVideo = videoList.eq(activeIndex + 1), // get the next video in line
actualVideo;
// if there is no next video start from first
if (nextVideo.length == 0) nextVideo = videoList.first();
// pause all videos
videoList.find('video').each(function() {
this.pause();
})
// get reference to next video element
actualVideo = nextVideo.find('video').get(0);
// add active class to next video
nextVideo.addClass('active');
// load and play
actualVideo.volume = 0.04;
actualVideo.load();
actualVideo.play();
}
}
});
});
filesystem: protocol stores files with reference to same origin as document which requests LocalFileSystem. That is, if JavaScript at Question is created at, for example, http://example.org, the path to LocalFileSystem should be same origin as http://example.org, not file: protocol.
If you are trying to store files or folders for accessing at file: protocol, offline, you can create an .html document to use as a template bookmark.
Visit the local .html file once while online to get files and populate LocalFileSystem. If navigator.onLine is true, navigate to http://example.org, else get and process files and folders stored at LocalFileSystem.
Create a list as JSON or JavaScript Array to store list of files to fetch, instead of parsing an .html document for file locations.
Store local file as a bookmark. Launch Chromium, Chrome with --allow-file-access-from-files flag set to access filesystem: protocol from file: protocol and file: protocol at filesystem: protocol, if not online.
<!DOCTYPE html>
<html>
<head>
<title>LocalFileSystem Offline Videos Bookmark</title>
</head>
<body>
<script>
// location to visit if online
const onLineURL = "https://lorempixel.com/"
+ window.innerWidth
+ "/"
+ window.innerHeight + "/cats";
const props = {
requestedBytes: 1024 * 1024 * 20000,
folder: "videos",
// list of files to fetch for offline viewing
mediaList: [
"http://mirrors.creativecommons.org/movingimages/webm/"
+ "ScienceCommonsJesseDylan_240p.webm"
, "https://nickdesaulniers.github.io/netfix/demo/frag_bunny.mp4"
]
};
let grantedBytes = 0;
function getLocalFileSystem ({requestedBytes = 0, mediaList=[], folder = ""}) {
if (!requestedBytes || !mediaList.length || !folder) {
throw new Error("requestedBytes: Number"
+ " or mediaList: Array"
+ " or folder: String not defined");
};
// do stuff with `filesystem:` URL
function processLocalFilePath(localPath) {
const video = document.createElement("video");
document.body.appendChild(video);
video.controls = true;
video.src = localPath;
}
function errorHandler(err) {
console.log(err);
}
function writeFile(dir, fn, fp, localPath) {
console.log(dir, fn, fp, localPath);
dir.getFile(fn, {}, function(fileEntry) {
fileEntry.createWriter(function(fileWriter) {
fileWriter.onwriteend = function(e) {
// do stuff when file is written
console.log(e.type, localPath + " written");
window.webkitResolveLocalFileSystemURL(localPath
, function(file) {
// file exists in LocalFileSystem
processLocalFilePath(localPath);
}, errorHandler)
};
fileWriter.onerror = errorHandler;
fetch(fp).then(function(response) {
return response.blob()
}).then(function(blob) {
fileWriter.write(blob);
}).catch(errorHandler)
}, errorHandler);
}, errorHandler);
}
if (mediaList && mediaList.length) {
navigator.webkitTemporaryStorage.requestQuota(requestedBytes
, function(grantedBytes_) {
grantedBytes = grantedBytes_;
console.log("Requested bytes:", requestedBytes
, "Granted bytes:", grantedBytes);
window.webkitRequestFileSystem(window.TEMPORARY
, grantedBytes
, function(fs) {
const url = fs.root.toURL();
mediaList.forEach(function(filename) {
const localPath = url + folder + "/"
+ filename.split("/").pop();
window.webkitResolveLocalFileSystemURL(localPath
, function(file) {
// file exists in LocalFileSystem
console.log(localPath + " exists at LocalFileSystem");
processLocalFilePath(localPath)
}, function(err) {
console.log(err, localPath
+ " not found in LocalFileSystem");
// Exception is thrown if file
// or folder path not found
// create `folder` directory, get files
fs.root.getDirectory(folder, {}
, function(dir) {
writeFile(dir
, filename.split("/").pop()
, filename
, localPath);
}),
errorHandler
})
})
})
}, errorHandler)
}
}
if (location.href !== onLineURL && navigator.onLine) {
location.href = onLineURL;
} else {
getLocalFileSystem(props);
}
</script>
</body>
</html>
See also
How to use webkitRequestFileSystem at file: protocol
How to print all the txt files inside a folder using java script
Read local XML with JS
How to Write in file (user directory) using JavaScript?
An alternative approach could be to utilize ServiceWorker
Adding a Service Worker and Offline into your Web App
Service Worker Sample: Custom Offline Page Sample
Your user must grant your app permission to store data locally before your app can use persistent storage.
That's why you have to request quota first. The amount of bytes you ask for is 200000 * 1024 * 1024 bytes.
window.storageInfo.requestQuota(PERSISTENT, 200000 * 1024 * 1024,
function(grantedBytes) {
window.requestFileSystem(window.PERSISTENT, grantedBytes, onInitFs, errorHandler);
},
errorHandler
);
MDN documentation
I noticed you are writing this for Chrome, here's how you manage the quota in Chrome
I created a simple cordova android app and I am trying to download an image from an URL to the pictures gallery, but I really can't figure out what is going wrong.
I have already searched a lot here in stackoverflow, including the following links:
Phonegap - Save image from url into device photo gallery
How to save an Image object into a file in Android with Phonegap?
I have installed cordova File Transfer plugin and tried to do the example from the official site, but it didn't work too: https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-file-transfer/
I tried 2 different codes, which are:
1) First attempt:
document.getElementById("myBtn").addEventListener("click", function () {
download("http://cordova.apache.org/static/img/cordova_bot.png", "data", "new_file");
});
function download(URL, Folder_Name, File_Name) {
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, fileSystemSuccess, fileSystemFail);
function fileSystemSuccess(fileSystem) {
var download_link = encodeURI(URL);
ext = download_link.substr(download_link.lastIndexOf('.') + 1); //Get extension of URL
var directoryEntry = fileSystem.root; // to get root path of directory
directoryEntry.getDirectory(Folder_Name, {
create: true,
exclusive: false
}, onDirectorySuccess, onDirectoryFail); // creating folder in sdcard
var rootdir = fileSystem.root;
var fp = rootdir.toURL();
fp = fp + "/" + Folder_Name + "/" + File_Name + "." + ext; // fullpath and name of the file which we want to give
filetransfer(download_link, fp);
}
function onDirectorySuccess(parent) {
// Directory created successfuly
}
function onDirectoryFail(error) {
alert("Unable to create new directory: " + error.code);
}
function fileSystemFail(evt) {
//Unable to access file system
alert(evt.target.error.code);
}
}
function filetransfer(download_link, fp) {
var fileTransfer = new FileTransfer();
fileTransfer.download(download_link, fp,
function (entry) {
alert("download complete: " + entry.fullPath);
//cordova.plugins.imagesaver.saveImageToGallery(entry.fullPath, successCallback, errorCallback);
},
function (error) {
alert("download error source " + error.source);
}
);
}
In this attempt, I get the alert message "download complete: /my_folder/new_file.png" but I can't find where the picture is downloaded.
It is definitely not in the pictures gallery or anywhere I can find it.
2) Second attempt:
function download() {
window.requestFileSystem(window.TEMPORARY, 5 * 1024 * 1024, function (fs) {
var url = 'http://cordova.apache.org/static/img/cordova_bot.png';
fs.root.getFile('downloaded-image.png', {
create: true,
exclusive: false
}, function (fileEntry) {
file_transfer(fileEntry, encodeURI(url), true);
}, onErrorCreateFile);
}, onErrorLoadFs);
}
function onErrorLoadFs(msg){
alert(msg);
}
function onErrorCreateFile(msg){
alert(msg);
}
function file_transfer(fileEntry, uri, readBinaryData) {
var fileTransfer = new FileTransfer();
var fileURL = fileEntry.toURL();
fileTransfer.download(
uri,
fileURL,
function (entry) {
alert("download complete: " + entry.toURL());
if (readBinaryData) {
// Read the file...
readBinaryFile(entry);
} else {
// Or just display it.
displayImageByFileURL(entry);
}
},
function (error) {
alert("download error source " + error.source);
alert("download error target " + error.target);
alert("upload error code" + error.code);
},
null, // or, pass false
{
//headers: {
// "Authorization": "Basic dGVzdHVzZXJuYW1lOnRlc3RwYXNzd29yZA=="
//}
}
);
}
In this attempt, I get the alert message "download complete: file:///data/user/0/com.companyname.xxxxxxx/cache/downloaded-image.png", but I also can't find the picture anywhere in the device.
I have already tried the application in two different android devices.
This is how I did it.
you will need the cordova file plugin
it wil take a url(png in my case)
and it will save it in your download folder (which makes it apear in the gallery of your phone)
//download file to device
function DownloadToDevice(fileurl) {
var blob = null;
var xhr = new XMLHttpRequest();
xhr.open("GET", fileurl);
xhr.responseType = "blob";//force the HTTP response, response-type header to be blob
xhr.onload = function()
{
blob = xhr.response;//xhr.response is now a blob object
console.log(blob);
var storageLocation = "";
switch (device.platform) {
case "Android":
storageLocation = 'file:///storage/emulated/0/';
break;
case "iOS":
storageLocation = cordova.file.documentsDirectory;
break;
}
var folderpath = storageLocation + "Download";
var filename = "Myimg.png";
var DataBlob = blob;
window.resolveLocalFileSystemURL(folderpath, function(dir) {
dir.getFile(filename, {create:true}, function(file) {
file.createWriter(function(fileWriter) {
fileWriter.write(DataBlob);
//Download was succesfull
}, function(err){
// failed
console.log(err);
});
});
});
}
xhr.send();
}
You should change the line
window.requestFileSystem(window.TEMPORARY, 5 * 1024 * 1024,
->
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0,
and
if download success, you should re-scan your device storage, because Cordova does not know if the file is downloaded.
so i made a plugin ,
It is a plugin that updates the gallery after downloading.
https://github.com/pouu69/cordova-plugin-gallery-refresh
If you are still looking for solution try this working plugin for android
cordova plugin add cordova-plugin-downloadimage-to-gallery
I use this function with callbacks.
To check the different types of cordovaFileSystem see here or check the ones available to you by typing in the console console.log(cordova.file)
downloadFileToDevice('https://example.com/image.jpg', 'myimg.jpg', cordova.file.cacheDirectory,
(err, filePath) => {
if (err) {
console.log('An error was found: ', err)
} else {
console.log('file downloaded successfully to: ' + filePath)
}
})
Function declaration
function downloadFileToDevice (fileurl, filename, cordovaFileSystem, callback) {
var blob = null
var xhr = new XMLHttpRequest()
xhr.open('GET', fileurl)
xhr.responseType = 'blob' // force the HTTP response, response-type header to be blob
xhr.onload = function () {
blob = xhr.response // xhr.response is now a blob object
var DataBlob = blob
window.resolveLocalFileSystemURL(cordovaFileSystem, function (dir) {
dir.getFile(filename, { create: true }, function (file) {
file.createWriter(function (fileWriter) {
fileWriter.write(DataBlob)
callback(null, cordovaFileSystem + filename)
}, function (err) {
callback(err)
})
})
})
}
xhr.send()
}
I'm using the following code to upload multiple documents to the server.
var docFileUploader = new sap.ui.unified.FileUploader({
name : fileUploaderName,
uploadOnChange: false,
uploadUrl: uploadUrlStr,
multiple:true,
additionaldata : nodeObjId ,
fileSizeExceed: function (oEvent) {
var sName = oEvent.getParameter("fileName");
var fSize = oEvent.getParameter("fileSize");
var fLimit = oFileUploader.getMaximumFileSize();
Messenger().post({
message: "File: " + sName + " is of size " + fSize + " MB which exceeds the file size limit of " + fLimit + " MB.",
type: 'error',
showCloseButton: true
});
},
uploadComplete: function (oEvent) {
var sResponse = oEvent.getParameter("response");
console.log(sResponse);
var thisDlg = this.getParent().getParent().getParent().getParent();
console.log(thisDlg);
if (sResponse) {
var m = /^\[(\d\d\d)\]:(.*)$/.exec(sResponse);
if (m[1] == "200") {
uploadSuccess = true;
thisDlg.setBusy(false);
console.log("The document has been uploaded successfully");
setTimeout(function() { Messenger().post("The document has been uploaded successfully");}, 100);
}
else {
thisDlg.setBusy(false);
setTimeout(function() { Messenger().post({
message: 'Oops! Error in document upload. <br>Please try again or contact your administrator.',
type: 'error',
showCloseButton: true
});},100);
}
}
thisDlg.setBusy(false);
console.log("The document has been uploaded successfully");
setTimeout(function() { Messenger().post("The document has been uploaded successfully");}, 100);
thisDlg.close();
thisDlg.destroy();
setTimeout(function() { reloadPage(attrGrpName); }, 100);
}
});
The controller part is as below:
#RequestMapping(value = "doc/upload", method = RequestMethod.POST, consumes = "multipart/form-data")
public #ResponseBody String uploadDoc(#RequestParam("uploadDoc-data") ObjectId nodeId,
#RequestParam(value = "uploadDoc", required = true) MultipartFile[] files, #RequestParam String userId, #RequestParam String passwd) {
if (files != null) {
return service.uploadDoc(nodeId, files[0], userId, passwd);
} else
return "No files found to upload";
}
Even if I use files[0] gives me an ArrayIndexOutofBound 0 Exception. It means the MultipartFile[] is returning an empty array only. I was able to upload one file without multiple attributes. The problem arises if I set the multiple attributes to 'true'. What am I missing? Please help me.
So It appears that I have stumbled across a very bizarre issue with phonegap 2.2.0.
I am trying to take a picture, and send it through the filetransfer plugin, like so:
if(navigator.camera) {
navigator.camera.getPicture(function(imageURI){
console.log('captured image = '+imageURI);
$('#photoConfirmation .image-preview').attr('src', imageURI);
self.photoURI = imageURI;
$('#photoConfirmation').show().simpledialog2({
'mode' : 'bool',
'prompt' : '',
'useModal': true,
'zindex':1001,
'callbackClose': function(e){
$('#photoConfirmation').hide();
}
});
},
function(message){
alert('Failed to get picture: ' + message);
}, {
sourceType:1,
quality: 50,
destinationType:1
});
} else {
alert('Camera is not supported on this device.');
}
var options = new FileUploadOptions();
options.fileKey="files[]";
options.fileName = 'image_something'.jpg';
options.mimeType="image/jpeg";
options.chunkedMode = false;
var params = new Object();
params.extraData= 'object-' + anObject.id;
options.params = params;
var ft = new FileTransfer();
ft.upload(imageURI, "http://someupload.com/destination/url", function(r){alert('Finished upload!');}, function(error){console.log(error);alert('Error uploading image with code: ' +error.code)}, options);
The problem is, this shows up in the preview, but does not upload! The picture is definitely getting captured because I see it in the image preview... I could've sworn I did something like this before. Does anyone see anything that I am doing wrong here?
There is a reference implementation of the FileTransfer plugin (which uses the captured photo from a camera) on the Cordova API Documentation, which many differences in it's implementation from yours. Reading though your code it looks like you are firing off a File Transfer before you capture the photo (and create the imageURI). Also you are using numerical constants for sourceType and destinationType. Though these are most likly not causing the problem you are experiencing, the correct forms for these is:
destinationType: navigator.camera.DestinationType.FILE_URI,
sourceType: navigator.camera.PictureSourceType.PHOTOLIBRARY
Here is an example with some small typo fixes (I'm assuming that extra ' in the fileName isn't a part of your code) of what should be a working version:
if (navigator.camera) {
navigator.camera.getPicture(
function (imageURI) {
console.log('captured image = ' + imageURI);
$('#photoConfirmation .image-preview').attr('src', imageURI);
self.photoURI = imageURI;
$('#photoConfirmation').show().simpledialog2({
'mode': 'bool',
'prompt': '',
'useModal': true,
'zindex': 1001,
'callbackClose': function (e) {
$('#photoConfirmation').hide();
var options = new FileUploadOptions();
options.fileKey = "files[]";
options.fileName = 'image_something.jpg';
options.mimeType = "image/jpeg";
options.chunkedMode = false;
var params = new Object();
params.extraData = 'object - ' + anObject.id;
options.params = params;
var ft = new FileTransfer();
ft.upload(imageURI, "http://someupload.com/destination/url", function (r) {
alert('Finished upload!');
}, function (error) {
console.log(error);
alert('Error uploading image with code: ' + error.code)
}, options);
}
});
},
function (message) {
alert('Failed to get picture: ' + message);
}, {
sourceType: navigator.camera.PictureSourceType.PHOTOLIBRARY,
quality: 50,
destinationType: navigator.camera.DestinationType.FILE_URI
});
} else {
alert('Camera is not supported on this device.');
}