I made a little phonegap/cordova application, and I need to access an object inside my .js file. Turns out I have no idea on how to change the structure of my code to make this happen.
Here is my index.html code :
<!DOCTYPE html>
<html>
<head>
<title>NFC tag ID reader</title>
<script type="text/javascript" src="js/index.js"></script>
<script type="text/javascript" charset="utf-8">
// Wait for device API libraries to load
document.addEventListener("deviceready", onDeviceReady, false);
// device APIs are available
function onDeviceReady() {
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, gotFS, fail);
}
function gotFS(fileSystem) {
fileSystem.root.getFile("readme.txt", {create: true, exclusive: false}, gotFileEntry, fail);
}
function gotFileEntry(fileEntry) {
fileEntry.createWriter(gotFileWriter, fail);
}
function gotFileWriter(writer) {
writer.onwriteend = function(evt) {
console.log("contents of file now 'some sample text'");
writer.truncate(11);
writer.onwriteend = function(evt) {
console.log("contents of file now 'some sample'");
writer.seek(4);
writer.write(" different text");
writer.onwriteend = function(evt){
console.log("contents of file now 'some different text'");
}
};
};
writer.write("some sample text");
//MAKE THIS OBJECT GLOBAL ?
}
function fail(error) {
console.log(error.code);
}
</script>
</head>
<body>
<div class="app">
<script type="text/javascript">
app.initialize();
</script>
</body>
</html>
And here is my index.js code :
var app = {
/* Application constructor */
initialize: function() {
this.bindEvents();
console.log("Starting NFC Reader app");
},
/* bind any events that are required on startup to listeners: */
bindEvents: function() {
document.addEventListener('deviceready', this.onDeviceReady, false);
},
/* this runs when the device is ready for user interaction: */
onDeviceReady: function() {
nfc.addTagDiscoveredListener(
app.onNfc, // tag successfully scanned
function (status) { // listener successfully initialized
app.displayCpt("<b>"+cpt+"</b>" + ' personnes restantes.');
app.displayBjr("\n");
app.displayBjr("Identifiez-vous:");
},
function (error) { // listener fails to initialize
app.display("NFC reader failed to initialize " +
JSON.stringify(error));
}
);
},
/* displays tag ID from #nfcEvent in message div: */
onNfc: function(nfcEvent) {
var tag = nfcEvent.tag;
var nfcUid = nfc.bytesToHexString(tag.id);
var myDb = {
"04c85ccab52880": {
"name": "name",
"firstname": "fname",
"societe": "work"
}
var mapped = Object.keys(myDb).map(function(uid){
return (myDb[uid].uid = uid) && myDb[uid];
});
for(var i = 0; i < mapped.length ; i++){
if(mapped[i]['uid'] != nfcUid){
mapped[i]['uid'] += 1;
} else {
mapped[i]['uid'] = nfcUid;
app.display(mapped[i]['name'] + ' ' + mapped[i]['firstname'] + ', ' + mapped[i]['societe']);
writer.write(mapped[i]['name'] + ' ' + mapped[i]['firstname'] + ', ' + mapped[i]['societe']);
//I WOULD NEED THIS WRITER USABLE IN ORDER TO WRITE MY ARRAY CONTENT INTO A FILE
}
}
},
}; // end of app
I think my writer object needs to be global in order to make the mapped array write into a file, but I can't find a way to do that.. Any ideas ?
Thanks
Have you tried putting var writer outside of everything and removing it from the arguments list of gotFileWriter(writer)? That should make it a global variable. Note that this isn't exactly the best of programming practices, one should avoid global variables where possible.
Related
I am new to cordova and plugins..
I have created a webappp, in my app i need to download files from server..
so i have used cordova background download plugin.. and i m using intel xdk.. so i have impoted plugin there..
cordova plugin github
now.. when i download file, on notification bar its showing downloading file.. BUT ITS SHOWING PLUGIN PACKAGE NAME WHILE DOWNLOADING.... but file save as its original name.... here it is my code..
var app = {
fileName: "tera hone.mp3",
uriString: "https://api.soundcloud.com/tracks/133667943/stream?client_id=67739332564a7130c3a05f90f2d02d2e", // 38.3 MB
// Application Constructor
initialize: function() {
this.bindEvents();
},
downloadFile: function(uriString, targetFile) {
var lblProgress = document.getElementById('lblProgress');
var complete = function() {
lblProgress.innerHTML = 'Done';
};
var error = function (err) {
console.log('Error: ' + err);
lblProgress.innerHTML = 'Error: ' + err;
};
var progress = function(progress) {
lblProgress.innerHTML = (100 * progress.bytesReceived / progress.totalBytesToReceive) + '%';
};
try{
var downloader = new BackgroundTransfer.BackgroundDownloader();
// Create a new download operation.
var download = downloader.createDownload(uriString, targetFile);
// Start the download and persist the promise to be able to cancel the download.
app.downloadPromise = download.startAsync().then(complete, error, progress);
} catch(err) {
console.log('Error: ' + err);
}
},
// Bind Event Listeners
//
// Bind any events that are required on startup. Common events are:
// 'load', 'deviceready', 'offline', and 'online'.
bindEvents: function() {
document.addEventListener('deviceready', this.onDeviceReady, false);
document.getElementById('btnStart').addEventListener('click', this.startDownload);
document.getElementById('btnStop').addEventListener('click', this.stopDownload);
document.getElementById('btnFileInfo').addEventListener('click', this.getFileInfo);
},
// deviceready Event Handler
//
// The scope of 'this' is the event. In order to call the 'receivedEvent'
// function, we must explicity call 'app.receivedEvent(...);'
onDeviceReady: function() {
app.receivedEvent('deviceready');
app.startDownload();
},
startDownload: function () {
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fileSystem) {
fileSystem.root.getFile(app.fileName, { create: true }, function (newFile) {
app.downloadFile(app.uriString, newFile);
});
});
},
stopDownload: function () {
app.downloadPromise && app.downloadPromise.cancel();
},
getFileInfo: function () {
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function (fileSystem) {
fileSystem.root.getFile(app.fileName, { create: true }, function (fileEntry) {
fileEntry.file(function (meta) {
document.getElementById('lblFileInfo').innerHTML =
"Modified: " + meta.lastModifiedDate + "<br/>" +
"size: " + meta.size;
});
}, function(error) {
document.getElementById('lblFileInfo').innerHTML = "error: " + error;
});
});
},
// Update DOM on a Received Event
receivedEvent: function(id) {
var parentElement = document.getElementById(id);
var listeningElement = parentElement.querySelector('.listening');
var receivedElement = parentElement.querySelector('.received');
listeningElement.setAttribute('style', 'display:none;');
receivedElement.setAttribute('style', 'display:block;');
console.log('Received Event: ' + id);
}
};
this is my javascript file invoke from my html file.. from cordova plugin..
also when i stop downloading.. it stops but app suddenly crashed everytime....
sorry for my bad english..
Morning.
I am using the following code (Phonegap 2.9) to create/read a file on Android device.
function gotFS(fileSystem) {
//alert('first try');
savedFS = fileSystem;
fileSystem.root.getFile("dp-locations.json", null, gotFileEntry2, fail);
}
function gotFS2(fileSystem) {
//alert('try again');
fileSystem.root.getFile("dp-locations.json", {create: true}, gotFileEntry, fail);
}
function gotFileEntry(fileEntry) {
//alert('call writer');
fileEntry.createWriter(gotFileWriter, fail);
}
function gotFileEntry2(fileEntry) {
alert('fileentry2');
//fileEntry.createWriter(gotFileWriter, fail);
fileEntry.file(gotFile, failRead);
}
function gotFile(file){
alert('gotfile');
readAsText(file);
}
function readAsText(file) {
alert('here I am');
var reader = new FileReader();
reader.onloadend = function(evt) {
alert("Read as text");
alert("rat2: "+evt.target.result);
};
reader.readAsText(file);
reader.onload = function(evt){
alert(reader.result);
};
}
function failRead(evt) {
alert("112: "+evt.target.error.code);
}
function gotFileWriter(writer) {
writer.onwrite = function(evt) {
//console.log("write success");
};
//writer.write('{"routes": {}}');//start writing to JSON file
var routes = new Array();
var test = new Object({"locations":[{"name":"first","values":["cw11 1gb","po45 5wd","ta6 3eq"]},{"name":"second","values":["cw7 2yg","po4 8ej","ta9 3zd"]}]});
routes.push(test);
writer.write(routes);//start writing to JSON file
gotFileEntry2(fileEntry);
}
function fail(error) {
//console.log(error.code);
if(error.code == 1){
alert('not found');
gotFS2(savedFS);
}
alert(error.code);
}
My problem is that the script is creating the file (if it needs to), but, when the file aready exists, it doesn't seem to read it.
Function gotFile is called, but function readAsText does not seem to do as required.
I want the file contents to be added to localStorage.
What am I missing?
I am trying to load xml data and everything works good, but I would like reload xml data when device resume.
This is my code, and I don't know where to paste function for load on resume. Thanks for advices ;-)
var TITLE = "Example";
var XMLsoubor = "example.xml";
var entries = [];
var selectedEntry = "";
//listen for detail links
$(".contentLink").live("click", function () {
selectedEntry = $(this).data("entryid");
});
//Listen for main page
$("#mainPage").live("pageinit", function () {
//Set the title
$("h1", this).text(TITLE);
$.ajax({
url: XMLsoubor,
success: function (res, code) {
entries = [];
var xml = $(res);
var items = xml.find("event");
$.each(items, function (i, v) {
entry = {
title: $(v).find("id").text(),
link: $(v).find("begin").text(),
description: $.trim($(v).find("description").text())
};
entries.push(entry);
});
//store entries
localStorage["entries"] = JSON.stringify(entries);
renderEntries(entries);
},
error: function (jqXHR, status, error) {
//try to use cache
if (localStorage["entries"]) {
$("#status").html("Error");
entries = JSON.parse(localStorage["entries"])
renderEntries(entries);
} else {
$("#status").html("Error");
}
}
});
});
$("#mainPage").live("pagebeforeshow", function (event, data) {
if (data.prevPage.length) {
$("h1", data.prevPage).text("");
$("#entryText", data.prevPage).html("");
};
});
//Listen for the content page to load
$("#contentPage").live("pageshow", function (prepage) {
//Set the title
$("h1", this).text(entries[selectedEntry].title);
var contentHTML = "";
contentHTML += entries[selectedEntry].description;
contentHTML += '<p/><br><br><br>text';
$("#entryText", this).html(contentHTML);
});
function renderEntries(entries) {
var s = '';
$.each(entries, function (i, v) {
s += '<li>' + v.title + '<br>text</li>';
});
$("#linksList").html(s);
$("#linksList").listview("refresh");
}
Use the eventlistener for "resume". It should be made as soon as deviceready has fired.
http://docs.phonegap.com/en/2.9.0/cordova_events_events.md.html#resume
The very first thing you should have in your script is an event for deviceready because a lot of Cordova things aren't ready until the deviceready event has been fired, so you need to listen for deviceready, like this:
document.addEventListener("deviceready", onDeviceReady, false);
Then you add the other listeners in the onDeviceReady function and begin the rest of your app start up from there:
function onDeviceReady() {
//The device is ready when this function is called
document.addEventListener("resume", appReturnedFromBackground, false);
}
function appReturnedFromBackground() {
//This function is called when the app has returned from the background
alert("The app has returned from the background");
}
I'm moving from Air/Actionscript to WebWorks and having some difficulty. I've tried several Phonegap file browser tutorials and samples I've found around the web but they're not working on the Playbook. I've added the access_shared permission to the config. I have an and when my app is launched it's supposed to load the directories and files into the .
My js is below:
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady(){
window.requestFileSystem(
LocalFileSystem.PERSISTENT,
0, onFileSystemSuccess, fail
);
}
function onFileSystemSuccess(fileSystem) {
// Create some test files
fileSystem.root.getDirectory("myDirectory",
{ create: true, exclusive: false },
null,fail);
fileSystem.root.getFile("readthis.txt",
{ create: true, exclusive: false },
null,fail);
var directoryReader = fileSystem.root.createReader();
// Get a list of all the entries in the directory
directoryReader.readEntries(success,fail);
}
function success(entries) {
var i;
var objectType;
for (i=0; i<entries.length; i++) {
if(entries[i].isDirectory == true) {
objectType = 'Directory';
} else {
objectType = 'File';
}
$('#directoryList').append('<li><h3>' + entries[i].name + '</
h3><p>' + entries[i].toURI() + '</p><p class="ui-li-aside">Type:
<strong>' + objectType + '</strong></p></li>');
}
$('#directoryList').listview("refresh");
}
function fail(error) {
alert("Failed to list directory contents: " + error.code);
}
I found the DIR example in KitchenSink showed me what I needed to know.
$(function() {
$("<img>", {
src: "http://goo.gl/GWtGo",
error: function() { alert("error!"); },
load: function() { alert("ok"); }
});
});
Got inspiration from How can I test if a URL is a valid image (in javascript)?
UPDATE
The next step will be: how can I encapsulate this logic into a function. I tried this -> http://jsfiddle.net/wp7Ed/2/
$(function() {
function IsValidImageUrl(url) {
$("<img>", {
src: url,
error: function() { return false; },
load: function() { return true; }
});
}
alert(IsValidImageUrl("http://goo.gl/GWtGo"));
alert(IsValidImageUrl("http://error"));
});
but of course it fails... how can I return from an internl event handler? Or how can I implement this?
You cannot ever turn an asynchonous call into a synchronous one in javascript.
error and load are asynchronous events, so you have to do it like this:
function IsValidImageUrl(url) {
$("<img>", {
src: url,
error: function() { alert(url + ': ' + false); },
load: function() { alert(url + ': ' + true); }
});
}
IsValidImageUrl("http://goo.gl/GWtGo");
IsValidImageUrl("http://error");
or you can parse in callback function you define elsewhere like this:
function myCallback(url, answer) {
alert(url + ': ' + answer);
}
function IsValidImageUrl(url,callback) {
$("<img>", {
src: url,
error: function() { callback(url, false); },
load: function() { callback(url, true); }
});
}
IsValidImageUrl("http://goo.gl/GWtGo", myCallback);
IsValidImageUrl("http://error", myCallback);
The clean and performant version skips the jQuery overhead like this
function myCallback(url, answer) {
alert(url + ': ' + answer);
}
function IsValidImageUrl(url, callback) {
var img = new Image();
img.onerror = function() { callback(url, false); }
img.onload = function() { callback(url, true); }
img.src = url
}
IsValidImageUrl("http://goo.gl/GWtGo", myCallback);
IsValidImageUrl("http://error", myCallback);
I think yes because an error event is fired when image is not found. As in your code, if image is not found (meaning not a valid path to an image), the alert will come up with message error!.
Here is another version of how it might look:
$('#imgID').error(function(){
alert('image not found !');
});
You can also change the path of your image in case previously specified image was not found like this:
$('#imgID').error(function(){
this.src = 'new path to some image';
});