how to implement function from another .js file in Titanium - titanium

how to use functions/methods from another .js file in titanium?
eg
Utils.js
var db = Titanium.Database.open('myinfodb');
function addIntoDb(name) {
db.execute('INSERT INTO info (name) VALUES(?)', name);
Ti.Ti.API.info(name+' Added to db');
}
function getFromDb() {
var holddatavar = db.execute('SELECT name FROM info');
return holddatavar;
}
db.close();
how to use this in my current js file?

db.js
// creates your database if necessary
var db = Titanium.Database.open('myinfodb');
db.execute('CREATE TABLE IF NOT EXISTS [info] (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT)');
db.close();
var addIntoDb = function(name) {
var db = Titanium.Database.open('myinfodb');
db.execute('INSERT INTO info (name) VALUES(?)', name);
Ti.Ti.API.info(name+' Added to db');
db.close();
}
exports.addIntoDb = addIntoDb; // <=== This exposes the function to another file
// This function would remain accessible only to the file because we didn't export the function
function getFromDb() {
var holddatavar = db.execute('SELECT name FROM info');
return holddatavar;
}
Then you would use it in other JavaScript files to access it like so:
var db = require('/mypath/db'); // NO .js extension on this
db.addIntoDb('Pravin');

Got it.
just
Ti.include('/ui/common/Utils.js');
and
Utils.js will be
addStudent= function addIntoDb(name) {
var db = Titanium.Database.open('myinfodb');
db.execute('INSERT INTO info (name) VALUES(?)', name);
Ti.API.info(name+' Added to db');
}
getStudent=function getFromDb() {
var db = Titanium.Database.open('myinfodb');
var holddatavar = db.execute('SELECT name FROM info');
return holddatavar;
}

If you are not using commonJS then you can do it simply including that file i mean create one file for such function and include that file in your current.js file and call that function.

var All = require('ui/common/All');
Tree = require('ui/common/Tree');
EBOM = require('ui/common/E-BOM');
MBOM = require('ui/common/M-BOM');
SBOM = require('ui/common/S-BOM');
//create object instance
var self = Ti.UI.createWindow({
title:'Products',
exitOnClose:true,
navBarHidden:true,
backgroundColor:'#ffffff',
/////////////////////////////////////////////////////////////////////////////
activity: {
onCreateOptionsMenu: function(e) {
var menu = e.menu;
var menuItem = menu.add({ title: "C-BOM", icon: 'Arrow-Hover.jpg' });
//menuItem.setIcon("Arrow-Hover.jpg");
menuItem.addEventListener("click", function(e) {
var all = new All();
self.add(all);
});
(.....)

Best is to make subfolder in /lib folder like /Utils and put there a file in /Utils/Utils.js.
Then in index.js controller add global variable like :
Alloy.Globals.Helpers=Ti.include('/Utils/Utils.js')
When you do it like this your file is now accessible in any controller you make.
Note this is for Alloy but it is almost the same for classic Titanium.

Related

Suitescript error: TypeError: Cannot set property "JSZipSync" of undefined

I have the following script where I am getting an error message:
org.mozilla.javascript.EcmaError: TypeError: Cannot set property
"JSZipSync" of undefined to
"org.mozilla.javascript.InterpretedFunction#6e57e155"
(/SuiteScripts/Suitelet to Excel.js#17(eval)#2)
According to Netsuite support, there are no issues with the script and they are not getting this error message
/**
*#NApiVersion 2.x
*#NScriptType Suitelet
*/
define(["N/search", "N/file", "N/https"], function (search, file, https) {
function onRequest(context) {
// Load the xlsx library from the CDN
var response = https.get({
url: "https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.17.0/xlsx.full.min.js",
});
var script = response.body;
eval(script);
// Replace this with the ID of the saved search you want to run
var searchId = "customsearch_my_saved_search";
// Run the search and get the results
var searchResult = search.load({
id: searchId,
});
var searchRows = searchResult.run().getRange({
start: 0,
end: 1000,
});
// Create an array to hold the data for the Excel file
var data = [];
// Add the column names as the first row
var columnNames = [];
searchResult.columns.forEach(function (column) {
columnNames.push(column.label);
});
data.push(columnNames);
// Add the search results to the data array
searchRows.forEach(function (row) {
var rowData = [];
searchResult.columns.forEach(function (column) {
rowData.push(
row.getValue({
name: column.name,
})
);
});
data.push(rowData);
});
// Create the Excel file
var ws = XLSX.utils.aoa_to_sheet(data);
var wb = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(wb, ws, "Sheet1");
var binaryData = XLSX.write(wb, {
type: "binary",
bookType: "xlsx",
});
var fileName = "search_results.xlsx";
var folderId = -4; // -4 represents the "Home" folder in the file cabinet
var file = file.create({
name: fileName,
fileType: file.Type.EXCEL,
contents: binaryData,
folder: folderId,
});
// Send the file as a response to the user
context.response.writeFile({
file: file,
isInline: true,
});
});
}
return {
onRequest: onRequest,
};
});
I can't tell where I am going wrong?
The JSZipSync is a function in the xlsx.full.min.js library which I believe I have loaded correctly.
I have also tried storing this file in the filing cabinet and referencing that instead of a link to the CDN website.
The same error message is generated in both cases

Aurelia PhantomJs target is undefined

We have an application runs on node , express server and aureliajs . We want to enable seo with prerendering. So we installed prerender.io and prerender-node.
But while trying to render pages with prerender , phantomjs give error TypeError: undefined is not an object (evaluating 'target.__useDefault')
and the code is :
function ensureOriginOnExports(executed, name) {
var target = executed;
var key = void 0;
var exportedValue = void 0;
if (target.__useDefault) {
target = target['default'];
}
.
.
.
in vendor-bundle.js
ensureOriginOnExports used in two places first one :
DefaultLoader.prototype.loadModule = function (id) {
var _this2 = this;
var existing = this.moduleRegistry[id];
if (existing !== undefined) {
return Promise.resolve(existing);
}
return new Promise(function (resolve, reject) {
require([id], function (m) {
_this2.moduleRegistry[id] = m;
resolve(ensureOriginOnExports(m, id));
}, reject);
});
};
second one :
DefaultLoader.prototype.loadModule = function (id) {
var _this3 = this;
return System.normalize(id).then(function (newId) {
var existing = _this3.moduleRegistry[newId];
if (existing !== undefined) {
return Promise.resolve(existing);
}
return System.import(newId).then(function (m) {
_this3.moduleRegistry[newId] = m;
return ensureOriginOnExports(m, newId);
});
});
};
So the solition to my problem was , first i used bluebird polyfill then i had to add create intl.js polyfill under /src/intl.js .
also i had to load babel-polyfill too.
It looks like phantom js looks that file for i18n support.

Creating a pdf from a Knockout JS view & viewModel

Scenario: In our application a user can create a invoice by filling in certain fields on a Knockout view. This invoice can be previewed, via another Knockout page. I want to use the preview url within our PDF creator (EVOPdf), so we can provide the user with a PDF from this invoice.
To preview the invoice we load the data (on document ready) via an ajax-request:
var InvoiceView = function(){
function _start() {
$.get("invoice/GetInitialData", function (response) {
var viewModel = new ViewModel(response.Data);
ko.applyBindings(viewModel, $("#contentData").get(0));
});
};
return{
Start: _start
};
}();
My problem is within the data-binding when the PDF creator is requesting the url: the viewModel is empty. This makes sense because the GetInitialData action is not called when the PDF creator is doing the request. Calling this _start function from the preview page directly at the end of the page does not help either.
<script type="text/javascript">
$(document).ready(function() {
InvoiceView.Start();
});
</script>
Looking at the documentation of EvoPdf, JavaScript should be executed, as the JavaScriptEnabled is true by default: http://www.evopdf.com/api/index.aspx
How could I solve this, or what is the best approach to create an pdf from a knockout view?
Controller action code:
public FileResult PdfDownload(string url)
{
var pdfConverter = new PdfConverter();
// add the Forms Authentication cookie to request
if (Request.Cookies[FormsAuthentication.FormsCookieName] != null)
{
pdfConverter.HttpRequestCookies.Add(
FormsAuthentication.FormsCookieName,
Request.Cookies[FormsAuthentication.FormsCookieName].Value);
}
var pdfBytes = pdfConverter.GetPdfBytesFromUrl(url);
return new FileContentResult(pdfBytes, "application/pdf");
}
Javascript:
var model = this;
model.invoiceToEdit = ko.observable(null);
model.downloadInvoice = function (invoice) {
model.invoiceToEdit(invoice);
var url = '/invoice/preview';
window.location.href = '/invoice/pdfDownload?url=' + url;
};
The comment of xdumaine prompted me to think into another direction, thank you for that!
It did take some time for the Ajax request to load, but I also discovered some JavaScript (e.g. knockout binding) errors along the way after I put a ConversionDelay on the pdf creator object
pdfConverter.ConversionDelay = 5; //time in seconds
So here is my solution for this moment, which works for me now:
To start the process a bound click event:
model.downloadInvoice = function (invoice) {
var url = '/invoice/preview/' + invoice.Id() + '?isDownload=true';
window.open('/invoice/pdfDownload?url=' + url);
};
which result in a GET resquest on the controller action
public FileResult PdfDownload(string url)
{
var pdfConverter = new PdfConverter { JavaScriptEnabled = true };
// add the Forms Authentication cookie to request
if (Request.Cookies[FormsAuthentication.FormsCookieName] != null)
{
pdfConverter.HttpRequestCookies.Add(
FormsAuthentication.FormsCookieName,
Request.Cookies[FormsAuthentication.FormsCookieName].Value);
}
pdfConverter.ConversionDelay = 5;
var absolutUrl = ToAbsulte(url);
var pdfBytes = pdfConverter.GetPdfBytesFromUrl(absolutUrl);
return new FileContentResult(pdfBytes, "application/pdf");
}
The Pdf creator is requesting this action on the controller, with isDownload = true (see bound click event):
public ActionResult Preview(string id, bool isDownload = false)
{
return PartialView("PdfInvoice", new InvoiceViewModel
{
IsDownload = isDownload,
InvoiceId = id
});
}
Which returns this partial view:
PartialView:
// the actual div with bindings etc.
#if (Model.IsDownload)
{
//Include your javascript and css here if needed
#Html.Hidden("invoiceId", Model.InvoiceId);
<script>
$(document).ready(function () {
var invoiceId = $("#invoiceId").val();
DownloadInvoiceView.Start(invoiceId);
});
</script>
}
JavaScript for getting the invoice and apply the knockout bindings:
DownloadInvoiceView = function() {
function _start(invoiceId) {
$.get("invoice/GetInvoice/" + invoiceId, function(response) {
var viewModel = new DownloadInvoiceView.ViewModel(response.Data);
ko.applyBindings(viewModel, $("#invoiceDiv").get(0));
});
};
return {
Start: _start
};
}();
DownloadInvoiceView.ViewModel = function (data) {
var model = this;
var invoice = new Invoice(data); //Invoice is a Knockout model
return model;
};

How can I save a zip file to local storage in a win8 app using JSZip?

I'm able to create the JSZip object in my code, but I'm having trouble saving that to local storage in my windows 8 app. The examples I'm able to find set the browser's location.href to trigger a download, which isn't really an option for me.
I've included my code below. The zip file I end up with is invalid and can't be opened. Any help would be appreciated.
For reference: JSZip
function _zipTest() {
var dbFile = null;
var zipData = null;
Windows.Storage.StorageFile.getFileFromPathAsync(config.db.path)
.then(function (file) {
dbFile = file;
return Windows.Storage.FileIO.readBufferAsync(file);
})
.then(function (buffer) {
//Read the database file into a byte array and create a new zip file
zipData = new Uint8Array(buffer.length);
var dataReader = Windows.Storage.Streams.DataReader.fromBuffer(buffer);
dataReader.readBytes(zipData);
dataReader.close();
var localFolder = Windows.Storage.ApplicationData.current.localFolder;
return localFolder.createFileAsync(dbFile.displayName.concat('.zip'), Windows.Storage.CreationCollisionOption.replaceExisting)
})
.then(function (file) {
//Write the zip data to the new zip file
var zip = new JSZip();
zip.file(dbFile.displayName, zipData);
var content = zip.generate();
return Windows.Storage.FileIO.writeTextAsync(file, content);
});
}
you can do something on these lines. This code seem to generate valid .zip file in the temp folder.
var zip = new JSZip();
var storage = Windows.Storage;
storage.StorageFile.getFileFromApplicationUriAsync(new Windows.Foundation.Uri('ms-appx:///images/logo.png')).then(function ongetfile(file)
{
var blob = MSApp.createFileFromStorageFile(file);
var url = URL.createObjectURL(blob, { oneTimeOnly: true });
return WinJS.xhr({ url: url, responseType: 'arraybuffer' });
}).then(function onreadbuffer(req)
{
var b = req.response;
zip.file('logo.png', b);
return storage.ApplicationData.current.temporaryFolder.createFileAsync('a.zip', storage.CreationCollisionOption.replaceExisting);
}).then(function onnewfile(out)
{
var content = zip.generate({ type: 'uint8array' });
return storage.FileIO.writeBytesAsync(out, content);
}).then(null, function onerror(error)
{
// TODO: error handling
});

HTML5 Drag n Drop File Upload

I'm running a website, where I'd like to upload files with Drag 'n Drop, using the HTML5 File API and FileReader. I have successfully managed to create a new FileReader, but I don't know how to upload the file. My code (JavaScript) is the following:
holder = document.getElementById('uploader');
holder.ondragover = function () {
$("#uploader").addClass('dragover');
return false;
};
holder.ondragend = function () {
$("#uploader").removeClass('dragover');
return false;
};
holder.ondrop = function (e) {
$("#uploader").removeClass('dragover');
e.preventDefault();
var file = e.dataTransfer.files[0],
reader = new FileReader();
reader.onload = function (event) {
//I shoud upload the file now...
};
reader.readAsDataURL(file);
return false;
};
I also have a form (id : upload-form) and an input file field (id : upload-input).
Do you have any ideas?
P.S. I use jQuery, that's why there is $("#uploader") and others.
Rather than code this from scratch, why not use something like html5uploader, which works via drag n drop (uses FileReader etc.): http://code.google.com/p/html5uploader/
EDIT: apparently we respondents are supposed to tend to our answers forever more, for fear for down-votes. The Google Code link is now dead (four years later), so here's a jQuery plugin that is very similar: http://www.igloolab.com/jquery-html5-uploader/
You'll want to extract the base64 encoded file contents and ajax them over tot the server.
JavaScript
var extractBase64Data;
extractBase64Data = function(dataUrl) {
return dataUrl.substring(dataUrl.indexOf(',') + 1);
};
// Inside the ondrop event
Array.prototype.forEach.call(event.dataTransfer.files, function(file) {
var reader;
if (!file.type.match(options.matchType)) {
return;
}
reader = new FileReader();
reader.onload = function(event) {
var contentsBase64;
if (event.target.readyState === FileReader.DONE) {
contentsBase64 = extractBase64Data(event.target.result);
return $.post(someURL, {
contentsBase64: contentsBase64
});
}
};
reader.readAsDataURL(file);
});
CoffeeScript
extractBase64Data = (dataUrl) ->
dataUrl.substring(dataUrl.indexOf(',') + 1)
# Inside the ondrop event
Array::forEach.call event.dataTransfer.files, (file) ->
return unless file.type.match(options.matchType)
reader = new FileReader()
reader.onload = (event) ->
if event.target.readyState == FileReader.DONE
contentsBase64 = extractBase64Data(event.target.result)
$.post someURL,
contentsBase64: contentsBase64
reader.readAsDataURL(file)