My custom javascript function is "not a function"? - javascript

I wrote a small .js file that has 3 functions in it for easy in-site cookie management. Here is the source for that file:
// Make Cookie
function Bake(name,value) {
var oDate = new Date();
oDate.setYear(oDate.getFullYear()+1);
var oCookie = encodeURIComponent(name) + '=' + encodeURIComponent(value) + ';expires=' + oDate.toGMTString() + ';path=/';
document.cookie= oCookie;
}
// Read Cookie
function Eat(name){
name = name.toLowerCase();
var oCrumbles = document.cookie.split(';');
for(var i=0; i<oCrumbles.length;i++)
{
var oPair= oCrumbles[i].split('=');
var oKey = decodeURIComponent(oPair[0].trim().toLowerCase());
var oValue = oPair.length>1?oPair[1]:'';
if(oKey == name)
return decodeURIComponent(oValue);
}
return '';
}
// Delete / Void Cookie
function Burn(name){
Bake(name,'');
}
I put that .js file into my "/models" folder on Cloud9. In my index.js I do have the line: var OCookie = require('../models/oatmealcookie'); to include my custom "library". However, still in index.js, I attempt to call the OCookie.Bake('test','testvalue'); before a redirect, and an error comes up on the page as TypeError: OCookie.Bake is not a function. Any help as to why it's not able to recognise my function as a function?

If that is your whole file, you aren't exporting any of your functions through module.exports. Effectively, your file is run once, and Bake, Eat, and Burn are declared as functions for the module but no other module can use them.
You would need something like:
module.exports = {
Bake: Bake,
Eat: Eat,
Burn: Burn
};
So that other modules can use your functions.

You need an exports.Bake = Bake at the end of the module.

You need to export your functions so that node.js recognises them when you require them.
See here: http://www.sitepoint.com/understanding-module-exports-exports-node-js/ for example.
var exports = module.exports = {
// Make Cookie
'Bake': function (name,value) {
var oDate = new Date();
oDate.setYear(oDate.getFullYear()+1);
var oCookie = encodeURIComponent(name) + '=' + encodeURIComponent(value) + ';expires=' + oDate.toGMTString() + ';path=/';
document.cookie= oCookie;
}
// Read Cookie
'Eat': function (name){
name = name.toLowerCase();
var oCrumbles = document.cookie.split(';');
for(var i=0; i<oCrumbles.length;i++)
{
var oPair= oCrumbles[i].split('=');
var oKey = decodeURIComponent(oPair[0].trim().toLowerCase());
var oValue = oPair.length>1?oPair[1]:'';
if(oKey == name)
return decodeURIComponent(oValue);
}
return '';
}
// Delete / Void Cookie
'Burn': function (name){
Bake(name,'');
}
}
By convention though, you would start your function names with lower case.

Related

Is there a JavaScript InDesign function to get ID value

I used the command to export the hard drive ID to drive C:
var command="wmic diskdrive get SerialNumber > C:/idhdd.txt";
app.system("cmd.exe /c\""+command+"" );
I get the text file
SerialNumber
2012062914345300
Is there a JavaScript statement to remove SerialNumber, I just want to get the ID in the text file and save it to the hard drive C.
Here's ready-to-use getDriveIDs() function that should work in any Adobe app and will return array of HDD ID strings for you. I hope this can be easily generalized for other scenarios with Windows scripting inside Adobe scripting ;-)
//----------------------------------------------------------------------//
// Detects IDs (serial numbers) of connected drives and returns them as array of strings.
var getDriveIDs = function() {
var idFile = File(Folder.temp + '/saved_hdd_serials.txt');
var scriptFile = File(Folder.temp + '/dump_hdd_serials.bat');
var scriptContent = 'wmic diskdrive get SerialNumber > ' + idFile.fsName + '\n';
var ids = []
withTempFile(scriptFile, scriptContent, function() {
scriptFile.execute();
$.writeln(idFile.length == 0); // wait for asynchronous script execution to finish
$.sleep(1);
withTempFile(idFile, undefined, function(file, lines) {
ids = lines.slice(1);
});
});
return ids;
};
//----------------------------------------------------------------------//
// utilities
var withTempFile = function(file, content, callback) {
if (undefined == content) { // read temp file
file.open('r');
content = [];
while (!file.eof)
content.push(file.readln());
} else { // write temp file
file.open('w');
file.write(content);
content = undefined;
}
file.close();
callback(file, content);
file.remove();
}
//----------------------------------------------------------------------//
// main: demo
var ids = getDriveIDs();
alert('Drive IDs:\n\t' + ids.join('\n\t'));

inDesign scripting: Include remote .js-file in script-file (and use it's variables)

I'm trying to access a remote .jsfile within an inDesign script to use it's variables. I found functions for including js-files locally but haven't found a good way to include.
http://remote-site.com/test.js:
var testVar = "it works!";
myscript.js, including locally (working):
app.doScript(new File("/Users/Popmouth/test.js"));
alert(testVar);
myscript.js, including locally including remotely (not working):
app.doScript(new File("http://remote-site.com/test.js"));
alert(testVar);
I also found this snippet, this alert works (alerts the content of the file, i.e. "var testVar = "it works!;") but I don't know how to use the vars in my alert function below:
var HTTPFile = function (url,port) {
if (arguments.length == 1) {
url = arguments[0];
port = 80;
};
this.url = url;
this.port = port;
this.httpPrefix = this.url.match(/http:\/\//);
this.domain = this.httpPrefix == null ? this.url.split("/")[0]+":"+this.port :this.url.split("/")[2]+":"+this.port;
this.call = "GET "+ (this.httpPrefix == null ? "http://"+this.url : this.url)+" HTTP/1.0\r\nHost:" +(this.httpPrefix == null ? this.url.split("/")[0] :this.url.split("/")[2])+"\r\nConnection: close\r\n\r\n";
this.reply = new String();
this.conn = new Socket();
this.conn.encoding = "binary";
HTTPFile.prototype.getFile = function(f) {
var typeMatch = this.url.match(/(\.)(\w{3,4}\b)/g);
if (this.conn.open(this.domain,"binary")) {
this.conn.write(this.call);
this.reply = this.conn.read(9999999999);
this.conn.close();
} else {
this.reply = "";
}
return this.reply.substr(this.reply.indexOf("\r\n\r\n")+4);;
};
}
var remoteFile = new HTTPFile("http://remote-site.com/test.js");
alert(.getFile());
This function
Ok, so I went to adobe-forums and got the following string which replaces app.doScript(new File("/Users/Popmouth/test.js"));:
var remoteCode = 'http://remote-site.com/test.js'; //location of your remote file
var script = app.doScript("do shell script \"curl 'remoteCode'\"".replace("remoteCode", remoteCode), ScriptLanguage.APPLESCRIPT_LANGUAGE);
// Set script args
app.scriptArgs.setValue("scriptArg1", "Hello");
// Set environmental vars
$.setenv("envVar1", "World");
// Run the "remote" script
app.doScript(script, ScriptLanguage.JAVASCRIPT);

uwp javascript list files in music library folder

The following lists files in a folder "Assets" in app and functions correctly.
// Get the path to the app's Assets folder.
var root = Windows.ApplicationModel.Package.current.installedLocation.path;
var path = root + "\\Assets";
//var path = Windows.Storage.KnownFolders.musicLibrary;
var StorageFolder = Windows.Storage.StorageFolder;
var folderPromise = StorageFolder.getFolderFromPathAsync(path);
folderPromise.done(function getFolderSuccess(folder) {
var filesInFolderPromise = folder.getFilesAsync();
filesInFolderPromise.done(function getFilesSuccess(filesInFolder) {
s = "";
filesInFolder.forEach(function forEachFile(item) {
s = s + item.name + "<br />";
});
document.getElementById('filelist').innerHTML = s;
});
});
I want to modify it to list the files in the musicLibrary. When I change the path name to
var path = Windows.Storage.KnownFolders.musicLibrary;
I get
JavaScript runtime error: The parameter is incorrect
Please help me with the appropriate syntax. The musicLibrary capability is set in the manifest.
Windows.Storage.KnownFolders.musicLibrary
is not a path string. This is StorageFolder class. Thus the call of getFolderFromPathAsync fails. Please refer the Microsoft docs.
KnownFolders Class (You can select 'JavaScript' from the language combobox on the right pane)
The object is to get the files async from the Music folder. This is done directly as follows:
var f = Windows.Storage.KnownFolders.musicLibrary;
f.getFilesAsync().done(function getFilesSuccess(filelist) {
s = "";
filelist.forEach(function forEachFile(item) {
s = s + item.name + "<br />";
});
document.getElementById('filelist').innerHTML = s;
});
Thanks to pnp0a03, and a quick re reading of the documentation.
For those struggling with syntax, this answer is equivalent:
var f = Windows.Storage.KnownFolders.musicLibrary;
f.getFilesAsync().then(success42);
function success42(filelist) {
s = "";
filelist.forEach(function forEachFile(item) {
s = s + item.name + "<br />";
});
document.getElementById('filelist').innerHTML = s;
}

Get String Value of Blob Passed to e.parameter in Apps Script

I'm using this code to get a blob passed to a function:
function submit(e){
var arrayBlob = e.parameter.arrayBlob;
Logger.log("arrayBlob #2 = " + arrayBlob.getDataAsString());
This is the error I get:
Execution failed: TypeError: Can not find getDataAsString function in
the Blob object.'arrayBlob'
How do I get the string value of this blob?
Here is my code:
function showList(folderID) {
var folder = DocsList.getFolderById(folderID);
var files = folder.getFiles();
var arrayList = [];
for (var file in files) {
file = files[file];
var thesesName = file.getName();
var thesesId = file.getId();
var thesesDoc = DocumentApp.openById(thesesId);
for (var child = 0; child < thesesDoc.getNumChildren(); child++){
var thesesFirstParagraph = thesesDoc.getChild(child);
var thesesType = thesesFirstParagraph.getText();
if (thesesType != ''){
var newArray = [thesesName, thesesType, thesesId];
arrayList.push(newArray);
break;
}
}
}
arrayList.sort();
var result = userProperties.getProperty('savedArray');
arrayList = JSON.stringify(arrayList);
var arrayBlob = Utilities.newBlob(arrayList);
Logger.log("arrayBlob #1 = " + arrayBlob.getDataAsString()); // Here it`s OK
var mydoc = SpreadsheetApp.getActiveSpreadsheet();
var app = UiApp.createApplication().setWidth(550).setHeight(450);
var panel = app.createVerticalPanel()
.setId('panel');
panel.add(app.createHidden('arrayBlob', arrayBlob));
var label = app.createLabel("Selecione os itens desejados").setStyleAttribute("fontSize", 18);
app.add(label);
arrayList = JSON.parse(arrayList);
panel.add(app.createHidden('checkbox_total', arrayList.length));
for(var i = 0; i < arrayList.length; i++){
var checkbox = app.createCheckBox().setName('checkbox_isChecked_'+i).setText(arrayList[i][0]);
Logger.log("arrayList[i][0] = " + arrayList[i][0]);
Logger.log("arrayList[i] ====> " + arrayList[i]);
panel.add(checkbox);
}
var handler = app.createServerHandler('submit').addCallbackElement(panel);
panel.add(app.createButton('Submit', handler));
var scroll = app.createScrollPanel().setPixelSize(500, 400);
scroll.add(panel);
app.add(scroll);
mydoc.show(app);
}
function submit(e){
var arrayBlob = e.parameter.arrayBlob;
Logger.log("arrayBlob #2 = " + arrayBlob.getDataAsString());
// Continues...
}
I'd like the solution worked with more than one user simultaneous using the script.
Update:
Add a global variable OUTSIDE of any function:
var arrayBlob = Utilities.newBlob("dummy data");
function showList(folderID) {
Code here ....
};
Check that the code has access to the blob:
function submit(e){
Logger.log("arrayBlob.getDataAsString(): " + arrayBlob.getDataAsString());
//More Code . . .
}
This solution eliminates the need of embedding a hidden element in the dialog box with a value of the blob.
You won't need this line:
panel.add(app.createHidden('arrayBlob', arrayBlob));
There are other changes I'd make to the code, but I simply want to show the main issue.
Old Info:
In the function showList(), the method getDataAsString() works on the blob named arrayBlob.
Logger.log("arrayBlob #1 = " + arrayBlob.getDataAsString()); // Here it`s OK
In the function, submit(), the same method does not work.
var arrayBlob = e.parameter.arrayBlob;
In the function showList(), the code is assigning a newBlob to the variable arrayBlob. So arrayBlob is available to have the getDataAsString() method used on it.
var arrayBlob = Utilities.newBlob(arrayList);
In the function, submit(), you are trying to pass the arrayBlob blob variable into the submit() function, and reference it with e.parameter.
If you put a Logger.log() statement in the submit() function.
function submit(e){
Logger.log('e: ' + e);
Logger.log('e.parameter` + e.parameter);
var arrayBlob = e.parameter.arrayBlob;
Those Logger.log statements should show something in them. If there is nothing in e.parameter, then there is nothing for the .getDataAsString() to work on.
It looks like you are putting the arrayBlob into a hidden panel.
panel.add(app.createHidden('arrayBlob', arrayBlob));
But when the object is getting passed to the submit(e) function, the arrayBlob might not be getting put into that object.
So, what I'm saying is, the:
Logger.log("arrayBlob #2 = " + arrayBlob.getDataAsString());
Line may be perfectly good, but there is no arrayBlob there to work on. This hasn't fixed your problem, but do you think I'm understanding part of what is going on?
I'm not sure why you are using Blob's here at all, you could simply work with JSON instead.
However, if you have a reason to use Blobs, you can pass the JSON data through your form and create the Blob in your handler, as the modified code below does:
function showList(folderID) {
var folder = DocsList.getFolderById(folderID);
var files = folder.getFiles();
var arrayList = [];
for (var file in files) {
file = files[file];
var thesesName = file.getName();
var thesesId = file.getId();
var thesesDoc = DocumentApp.openById(thesesId);
for (var child = 0; child < thesesDoc.getNumChildren(); child++){
var thesesFirstParagraph = thesesDoc.getChild(child);
var thesesType = thesesFirstParagraph.getText();
if (thesesType != ''){
var newArray = [thesesName, thesesType, thesesId];
arrayList.push(newArray);
break;
}
}
}
arrayList.sort();
var result = UserProperties.getProperty('savedArray');
//get JSON data pass through form.
var arrayBlob = JSON.stringify(arrayList);
var mydoc = SpreadsheetApp.getActiveSpreadsheet();
var app = UiApp.createApplication().setWidth(550).setHeight(450);
var panel = app.createVerticalPanel()
.setId('panel');
//include JSON Data in the form.
panel.add(app.createHidden('arrayBlob', arrayBlob));
var label = app.createLabel("Selecione os itens desejados").setStyleAttribute("fontSize", 18);
app.add(label);
panel.add(app.createHidden('checkbox_total', arrayList.length));
for(var i = 0; i < arrayList.length; i++){
var checkbox = app.createCheckBox().setName('checkbox_isChecked_'+i).setText(arrayList[i][0]);
Logger.log("arrayList[i][0] = " + arrayList[i][0]);
Logger.log("arrayList[i] ====> " + arrayList[i]);
panel.add(checkbox);
}
var handler = app.createServerHandler('submit').addCallbackElement(panel);
panel.add(app.createButton('Submit', handler));
var scroll = app.createScrollPanel().setPixelSize(500, 400);
scroll.add(panel);
app.add(scroll);
mydoc.show(app);
}
function submit(e){
var arrayBlob = Utilities.newBlob(e.parameter.arrayBlob);
Logger.log("arrayBlob #2 = " + arrayBlob.getDataAsString());
// Continues...
}
In the method you were using originally, the Blob itself was never included in the form, you were simply passing the string "Blob" around.
This is because the function createHidden(name, value); expects two strings as parameters, so it calls ".toString()" on the arrayBlob object, which returns the string "Blob".

Read a cookie when implementing inside of another function

I have the following function to change stylesheets on my website that I want to use cookies to keep stylesheet theme persistent across pages.
<script type="text/javascript">
var i=1;
function styleSheet(){
if(i%2==0){
swapper('css/main.css');
document.cookie = "username=Visitor";
}
else{
swapper('css/stylesheetalternate.css');
document.cookie = "username=alternateVisitor";
}
i++;
}
<button onclick="styleSheet()">Click me</button>
I'm already setting my cookies inside of this function. I'm not too interested in setting expiration dates or anything like that, the default is fine for me. What I do want to try doing however is read the cookies inside of this function each time that I use the button I created. Is there no way to read it inside of the same function?
I'm aware that there exists a jquery library that does this, but I don't want to use jquery if I can get a better performance with javascript.
EDIT:
<script type="text/javascript">
var i=1;
function styleSheet(){
if(i%2==0){
swapper('css/main.css');
document.cookie = "username=Visitor";
readCookie(Visitor);
}
else{
swapper('css/stylesheetalternate.css');
document.cookie = "username=alternateVisitor";
readCookie(alternateVisitor);
}
i++;
}
Do you mean something like the following when you say to use readCookie inside of my function? What I notice from this sort of implementation is that after swapping stylesheets once, it is for whatever reason impossible to swap again until the page is reloaded.
Here's a set of plain javascript cookie functions that you can use from any function. So, to your question, you can call readCookie("username") from your function (or read any other cookie value):
// createCookie()
// name and value are strings
// days is the number of days until cookie expiration
// path is optional and should start with a leading "/"
// and can limit which pages on your site can
// read the cookie.
// By default, all pages on the site can read
// the cookie if path is not specified
function createCookie(name, value, days, path) {
var date, expires = "";
path = path || "/";
if (days) {
date = new Date();
date.setTime(date.getTime()+(days*24*60*60*1000));
expires = "; expires=" + date.toGMTString();
}
document.cookie = name + "=" + value + expires + "; path=" + path;
}
function readCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0)==' ') c = c.substring(1,c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
}
return null;
}
function eraseCookie(name) {
createCookie(name, "", -1);
}
document.cookies is just a big list of all the cookies. You can parse through it to find the one you're interested in:
function getCookieValue(cookieName) {
var value = null;
document.cookie.split(';')
.forEach(function(pair){
var pairArray = pair.split('=');
if (pairArray[0]==cookieName) {
value = pairArray[1];
}
});
return value;
}
(Untested, let me know how it goes.)

Categories

Resources