In this tutorial I will create a sample app which uploads a file to webserver using Intel XDK file upload API and also shows the percentage of file upload. I will also show how to write a backend PHP script to handle the upload.
Why not use AJAX?
We can use AJAX to upload files to server. But AJAX has some limitations. Limitations are:
- AJAX doesn’t provide any reporting on the percentage of the file uploaded.
- Mobile Internet is generally slow. We should upload only one file at a time so that we don’t overhaul Internet by multiple connection. AJAX doesn’t provide any means to report if multiple files are being uploaded at a time.
Intel XDK file upload API solves both the above issues.
Basic APP Template
Put this code in index.html file. It creates a button and progress bar.
<html>
<head>
<title>Blank Hybrid App Project Template</title>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<style>
@-ms-viewport { width: 100vw ; zoom: 100% ; }
@viewport { width: 100vw ; zoom: 100% ; }
@-ms-viewport { user-zoom: fixed ; }
@viewport { user-zoom: fixed ; }
</style>
<script src="lib/ft/fastclick.js"></script>
<link rel="stylesheet" href="css/app.css">
</head>
<body>
<button onclick="upload_to_server();">Create and Upload Text File</button>
<progress value="0" min="0" max="100" id="progress"></progress>
<script src="intelxdk.js"></script>
<script src="cordova.js"></script>
<script src="xhr.js"></script>
<script src="js/app.js"></script>
<script src="js/init-app.js"></script>
<script src="js/init-dev.js"></script>
</body>
</html>
Including Intel XDK File Upload API
Before we proceed with using Intel XDK File upload API we need to make sure you include Intel XDK File plugin in your app.
Creating a Text File
Let’s create a text file using Cordova File System API. We are going to uploading this created text file. You can also upload a existing file.
{
requestFileSystem(LocalFileSystem.PERSISTENT, 0, onSuccess, onError);
}
function onSuccess(fileSystem)
{
var directoryEntry = fileSystem.root;
directoryEntry.getFile("readme.txt", {create: true, exclusive: false}, function(fileEntry){
fileEntry.createWriter(function(writer){
writer.write("This is the text inside readme file");
var pathOfFile = fileEntry.fullPath;
}, function(error){
alert("Error occurred while writing to file. Error code is: " + error.code);
});
}, function(error){
alert("Error occurred while getting a pointer to file. Error code is: " + error.code);
});
}
function onError(evt)
{
alert("Error occurred during request to file system pointer. Error code is: " + evt.code);
}
Uploading File and Showing Progress
We are going to use uploadToServer function of File Upload API to upload the file. Here is the code to upload it to server.
First parameter of the function should be absolute path to the file. And second parameter should point to the web server script which is going to handle the upload.
function updateUploadProgress(bytesSent,totalBytes)
{
if(totalBytes>0)
currentProgress=(bytesSent/totalBytes)*100;
document.getElementById("progress").setAttribute("value", currentProgress);
}
document.addEventListener("intel.xdk.file.upload.busy",uploadBusy);
document.addEventListener("intel.xdk.file.upload",uploadComplete);
document.addEventListener("intel.xdk.file.upload.cancel",uploadCancelled);
function uploadBusy(evt)
{
alert("Sorry, a file is already being uploaded");
}
function uploadComplete(evt)
{
if(evt.success==true)
{
alert("File "+evt.localURL+" was uploaded");
}
else {
alert("Error uploading file "+evt.message);
}
}
function uploadCancelled(evt)
{
alert("File upload was cancelled "+evt.localURL);
}
Complete APP Code
Here is the combination of all the above code
<html>
<head>
<title>Blank Hybrid App Project Template</title>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<style>
@-ms-viewport { width: 100vw ; zoom: 100% ; }
@viewport { width: 100vw ; zoom: 100% ; }
@-ms-viewport { user-zoom: fixed ; }
@viewport { user-zoom: fixed ; }
</style>
<script src="lib/ft/fastclick.js"></script>
<link rel="stylesheet" href="css/app.css">
</head>
<body>
<button onclick="upload_to_server();">Create and Upload Text File</button>
<progress value="0" min="0" max="100" id="progress"></progress>
<script src="intelxdk.js"></script>
<script src="cordova.js"></script>
<script src="xhr.js"></script>
<script src="js/app.js"></script>
<script src="js/init-app.js"></script>
<script src="js/init-dev.js"></script>
<script>
function upload_to_server()
{
requestFileSystem(LocalFileSystem.PERSISTENT, 0, onSuccess, onError);
}
function onSuccess(fileSystem)
{
var directoryEntry = fileSystem.root;
directoryEntry.getFile("readme.txt", {create: true, exclusive: false}, function(fileEntry){
fileEntry.createWriter(function(writer){
writer.write("This is the text inside readme file");
var pathOfFile = fileEntry.fullPath;
intel.xdk.file.uploadToServer(pathOfFile,"http://labs.qnimate.com/intelxdk-upload/upload.php", "", "text/plain", "updateUploadProgress");
}, function(error){
alert("Error occurred while writing to file. Error code is: " + error.code);
});
}, function(error){
alert("Error occurred while getting a pointer to file. Error code is: " + error.code);
});
}
function onError(evt)
{
alert("Error occurred during request to file system pointer. Error code is: " + evt.code);
}
function updateUploadProgress(bytesSent,totalBytes)
{
if(totalBytes>0)
currentProgress=(bytesSent/totalBytes)*100;
document.getElementById("progress").setAttribute("value", currentProgress);
}
document.addEventListener("intel.xdk.file.upload.busy",uploadBusy);
document.addEventListener("intel.xdk.file.upload",uploadComplete);
document.addEventListener("intel.xdk.file.upload.cancel",uploadCancelled);
function uploadBusy(evt)
{
alert("Sorry, a file is already being uploaded");
}
function uploadComplete(evt)
{
if(evt.success==true)
{
alert("File "+evt.localURL+" was uploaded");
}
else {
alert("Error uploading file "+evt.message);
}
}
function uploadCancelled(evt)
{
alert("File upload was cancelled "+evt.localURL);
}
</script>
</body>
</html>
Handling Upload Using PHP
Here is the code to handle the uploaded file using PHP. Here we move the uploaded file to a uploads folder.
move_uploaded_file($_FILES["Filedata"]["tmp_name"], "uploads/" . $_FILES["Filedata"]["name"]);
?>
Conclusion
If your app has uploading file functionality then its always better to display upload progress. This provides a great user experience.