Goal:
To sum it up, I'm trying to replace an excel spreadsheet. I'm creating an application that will run in IE9, but does not connect to the internet or an intranet (I know, I know. Just bear with me. If you're curious read more below). It needs to use CRUD (create, read, update, and delete) methods on a set of data that changes daily. The dataset must persist even when the browser is closed.
Question:
What options are available, using javascript and html, for storing data on the local computer the web page is accessed on? I'm doing this at work, so there will be no server-side to this. I also will not be able to install any software on the computer, although I can download javascript plugins. The webpage will be loaded from a file on the computer, using Win 7 and IE9.
Background:
This deserves an explanation. I use an excel spreadsheet to track a set of data that changes daily. I'm learning HTML and javascript, and I can create a much better (and easier to use) solution as a webpage. I can create the UI / UX, but I'm having a difficult time figuring out how to store the data on the local computer. Any good suggestions?
Attempts:
Unfortunately, it seems localStorage is not an option. I'm attempting to use jStorage, but I've been running into problems there, also. A similar set of problems has been encountered using simpleStorage.
Thank you for considering, please let me know if any more info is needed, or if I need to clarify something.
Addendum:
Localstorage, and other forms of HTML5 storage, do not work. Officially it does, unofficially it is very buggy. See blog post here, and SO answer here. Either way, with the following simple code:
HTML:
<!DOCTYPE html>
<html>
<head>
<title>Backlog Tracker</title>
<script src="jquery-2.1.1.min.js"></script>
<script src="backlog_localstorage.js"></script>
</head>
<body>
</body>
</html>
and javascript (ref as "backlog_localstorage.js" above):
$(document).ready(function(){
$("body").append("<button>Try It</button>");
$("button").click(function(){
localStorage.setItem("key1", "Hello");
console.log(localStorage.getItem("key1"));
});
});
... I get the following error: "SCRIPT5007: Unable to get value of the property 'setItem': object is null or undefined" on the line localStorage.setItem("key1", "Hello");
HTA (which is really just an html file with one extra tag and a different file extension) is one possible solution for windows users:
Important: Save as demo.hta to run on windows as an app
<!DOCTYPE html>
<html> <!-- some parts lifted from
http://msdn.microsoft.com/en-us/library/ms536496(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/ms536473(v=vs.85).aspx
-->
<head>
<title>State Saving Demo</title>
<hta:application id="App"
application="yes"
applicationname="demo"
icon="calc.exe"
border="thin"
caption="yes"
sysmenu="yes"
showintaskbar="yes"
singleinstance="yes"
sysmenu="no"
maximizeButton="yes"
minimizeButton="yes"
navigable="no"
scroll="yes"
contextmenu="no"
selection="no"
windowstate="normal" >
<!-- Use Internet Explorer 10 Standards mode (to use JSON, CSS3, etc...) -->
<meta http-equiv="x-ua-compatible" content="IE=10">
</head>
<body onload=loadMe() >
<h1 id=h1>Command-line args: </h1>
<h3>Persisted Text</h3>
<textarea rows=20 cols=100 id=mydata onchange=saveMe() >
You can change me and i won't forget!
</textarea>
<script>
document.title+=" - Today is " + Date(); // task/title bar demo
h1.innerHTML+= JSON.stringify( App.commandLine ); // optional invocation info here (much like a real app)
// app-specific custom code:
FILENAME="state.txt";
function saveMe(){save(FILENAME, mydata.value); }
function loadMe(){mydata.value=load(FILENAME) || mydata.value;}
// generic utils:
function load(filename) { //IE FSO file Loader
var file,
text="",
fso= new ActiveXObject('Scripting.FileSystemObject');
try{
file = fso.OpenTextFile(filename, 1, false);
text = file.readAll();
file.Close();
}catch(y){}
return text;
}
function save(filename, sData){ //IE FSO file Saver
var file,
fso = new ActiveXObject('Scripting.FileSystemObject');
file = fso.CreateTextFile(filename, 2, false);
file.write(sData);
file.Close();
return file;
}
</script>
</body>
</html>
I recently re-discovered HTAs, and they are not half bad. I don't think I would want to distribute and maintain them, but HTA's are an easy way to make simple desktop app using HTML, CSS, and JS. Its nice not to have to build anything to "recompile" the app after changes are made. saves a few steps compared to node-webkit, packaged apps, air, cordova, etc, but HTA's have a major downside: they only work on windows afaik...
Looks to me like you can use LocalStorage, the big question is how are you trying to store it? You can easily store an object/array into LocalStorage, and that object/array can be your data, then JS can output this into a table. If you're looking to store actual files then you're looking at something more like an ActiveX plugin.
http://caniuse.com/#search=localstorage
Alternatively if you have internet access through a desktop or a phone you can put this on Google Drive. This would be far easier than reinventing the wheel.
Related
I use Intellij Idea. I want to download jquery library to have access offline to it in Intellij Idea in my Spring Project. So I typed "Alt + enter" on the link
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
and chose "Download library".
The library has dowloaded, and the problem is that after it I can't run my program, because all the time I see
Error:java: Illegal char <:> at index 4: http:\api.jquery.com
without any path. I have't even have something like written in my whole project.
When I had just global link to "https://code.jquery.com/jquery-1.12.4.min.js" and had internet access all worked properly.
I tried to download library in local file and put in header link to it actually after deleting library from intellij. But still don't working.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
</head>
<body>
<input type="number" id="myInput" name="myInput" onchange="countOfTryings(this)">
<a name="toChallenge" href="http://some_web_site.com?parameter1=4">This is link</a>
<a name="toChallenge" href="http://some_web_site_other.com?parameter1=4">This is link 2</a>
<script>
function countOfTryings(variable) {
$('a[name="toChallenge"]').each(function () {
var oldUrl = $(this).attr("href"); // Get current url
var str = oldUrl.substring(0, oldUrl.indexOf("parameter1"));
var newUrl = oldUrl.replace(oldUrl, str + "parameter1=" + variable.value); // Create new url
$(this).attr("href", newUrl); // Set herf value
});
}
</script>
</body>
</html>
I want my program to change the urls of hyperlinks with name="toChallenge". To change the value of the request parameter "parameter1" to new value, what will be in input with id="myInput".
After submiting a report to Intellij Idea I got an answer, that JS libraries are added to the Java classpath which is a bug, and to fix thit problem I need to do next:
Project settings (ctrl+alt+shift+s by default) -> Modules -> in "Modules" select "Dependencies" -> find jquery dependency -> delete jquery dependency -> click "apply"
I had same problem but deleting dependency did not help. I had to go to global libraries and delete jquery library as well.
[ctrl+alt+shift+s] -> Modules -> Dependencies -> delete jquery dependency
maven -> reload all maven projects
As both Jan and Odeta point out in their answers, this can be fixed by deleting the dependency in the module and global library. However, I think I can refine this a little further. When I looked under the global library, I found there was both the released artifact and a link to the documentation. If you delete the documentation reference, it should fix the problem and the dependency can remain.
I'm new in Node.js and I'm doing a local App with Node.js+HTML5+Javascript with which I would like to move files from one local folder to another local folder. The main functionality of this app is to get a local file "A", read its content, copy this content encrypted in another file "B", and then store "B" in other location and finally delete file "A" in the local system. The problem that I've found is on getting the real path of the first file, and I know that it is difficult to get it (as I've seen in several discussions) for security reasons, but I really need it in order to delete file "A". I realised that with my current code I only can get this real path in IE explorer. The main part of the code involved is the following, in which I'm only able to get the file name in both Firefox and Chrome:
index.ejs:
<!DOCTYPE html>
<html>
<head>
<script src="../scripts/get_file.js"></script>
<title><%= title %></title>
<link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body>
<form method='get' action='/moveFile'>
<div id="page-wrapper">
<h1>File Browser</h1>
<div>
Select a file:
<input type="file" name="fileInput" id="fileInput">
<input type="submit" value="Upload File"/>
</div>
</div>
</form>
</body>
</html>
get_file.js:
window.onload = function() {
var fileInput = document.getElementById('fileInput');
fileInput.addEventListener('change', function(e) {
var file = fileInput.files[0];
});
}
fs_controller.js:
exports.moveFile = function(req,res) {
console.log(req.query.fileInput);
};
I've tried with the following options:
I've seen that bodyparser is only used for express 3.0, and I have
express 4.13.1.
I've tried with Busboy, without results.
I've tried with filepath utility, but it returns the path
where is the main script of the application, so it's not useful for
this case.
Formidable only returns a tmp path.
I've tried with multiparty, and it also returns a tmp path.
The only solution that may be could work is to modify some properties
in Firefox, like
netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
and in Chrome, with --allow-file-access-from-files. However, I think
that it's not a clean solution.
I dont know if there are better solutions with Node.js to make this type of app. The main features that I actually need is to work with local files and folders (all types of basic operations with them), and to have a little database for storing the users of the app, and I would like to implement it with a MVC design pattern.
Thanks for your effort!
I have been digging in the this site and others for several days and the answer to my problem still escapes me.
I have read all of these pages:
http://pastebin.com/cbagkw8h
but none of them exactly answers this question:
I am trying to get a Rally Dashboard (custom board) to appear in HTML/Javascript in a confluence wiki. I have gotten a simple Standard Report working using a read-only account and AppSDK1.32 with loginKey by embedding the following HTML/Javascript into the Confluence wiki page:
{html}
<meta name="Name" content="App Example: Rally Application" />
<meta name="Version" content="2011.04" />
<meta name="Vendor" content="Rally Software" />
<script type="text/javascript"
src="https://rally1.rallydev.com/apps/1.32/sdk.js?loginKey=loginkeyloginkeyloginkeyloginkeyloginkeyloginkeyloginkeyloginkeyloginkeyloginkeyloginkeyloginkeyloginkeyloginkeyloginkeyloginkey">
</script>
<script type="text/javascript">
function onLoad() {
var rallyDataSource = new rally.sdk.data.RallyDataSource(
'__WORKSPACE_OID__',
'__PROJECT_OID__',
'__PROJECT_SCOPING_UP__',
'__PROJECT_SCOPING_DOWN__');
rally.sdk.ui.AppHeader.destroy();
var reportConfig = {report: rally.sdk.ui.StandardReport.IterationBurndown,
width : 400, height: 300};
var report = new rally.sdk.ui.StandardReport(reportConfig);
report.display("reportDiv");
}
rally.addOnLoad(onLoad);
</script>
<div id="reportDiv" style="width: 400px; margin-left:20px"></div>
<br/>
{html}
I am trying to expand this success to an entire dashboard with App SDK2.x using the new apiKey - by using the following code:
{html}
<meta name="Name" content="App Example: Rally Application" />
<meta name="Version" content="2015.04" />
<meta name="Vendor" content="eBay Enterprise" />
<script type="text/javascript"
src="https://loginapirally1.rallydev.com/apps/1.32/sdk.js?loginKey=loginkeyloginkeyloginkeyloginkeyloginkeyloginkeyloginkeyloginkeyloginkeyloginkeyloginkeyloginkeyloginkeyloginkeyloginkeyloginkey">
</script>
<script type="text/javascript">
function onLoad() {
rally.sdk.ui.AppHeader.destroy();
document.getElementById("iframeA").width = screen.width - 60 ;
document.getElementById("iframeA").height = (screen.width - 60 ) * 3;
}
rally.addOnLoad(onLoad);
</script>
<iframe id="iframeA" src="https://loginapirally1.rallydev.com/#/111111111d/custom/222222222?expandApp=333333333&apiKey=_apikeyapikeyapikeyapikeyapikeyapikeyapikey" width="1024" height="1024">
</iframe>
<br/>
{html}
I am noticing a few things:
1) it almost works - I get the dashboard/report title but not the cards
2) the apiKey seems to have no affect at all - I still get prompted for a login and password (which I could stand if I could see the cards).
3) it doesn't seem to matter if I put the apiKey before or after the hash symbol
Citation A suggested using the "full screen" dashboard/report but didn't cover the apiKey.
Citaton B says that the AppSDK2 uses the apiKey as of Apr 14 2014 but doesn't say how to use it exactly with AppSDK2.
I have gotten the apiKey to work with the Ruby API but it is unclear how to access the dashboard/reports from there.
Citation C says that the AppSDK1 is based on the Javascript dojo framework and the AppSDK2 is based on the Javascript Sencha's ExtJS but avoids giving any kind of rosetta stone from one to the other.
The only other options I can think of is to 1) copy the entire HTML page-source from the "Custom Board" and then start debugging the Javascript with ExtJS (but I cannot find an example of where to put the apiKey for ExtJS) or 2) bypass all of the APIs and use Ruby Watir-Webdriver (which uses
Selenium) and VNCServer to clip an image of the "Custom Board" page and show THAT in confluence.
Citations: http://pastebin.com/YMUEPjSF
The issue seems to be specific to the canned Custom Board that cannot be loaded externally. It should work if you write a js source code to build a similar Board and compile that into a deployment html. That is similar to option (1) you mentioned in the end of your post if I understand it correctly.
Here is my test where I compared Custom Board and Custom HTML side by side.
Below is a screenshot from Rally. This custom dashboard has Custom Board on the left and Custom HTML on the right. The Custom HTML is using a code example of filterable board from AppSDK2 documentation.
Next I use this code:
<html>
<head>
<title>Custom Grid</title>
<meta name="Name" content="App: Custom Dashboard"/>
<meta name="Version" content="2011.08.31"/>
<meta name="Vendor" content="Rally Labs, NickM"/>
<script type="text/javascript" src="https://rally1.rallydev.com/apps/1.32/sdk.js?loginKey=c33e83...."></script>
<script type="text/javascript">
rally.addOnLoad(function() {
var iframe = document.createElement("iframe");
iframe.src = "https://loginapirally1.rallydev.com/#/14018981229/custom/34207853894"
iframe.width = 2000;
iframe.height = 1000;
document.getElementById("storyboard").appendChild(iframe);
});
</script>
</head>
<body>
<div id="storyboard"></div>
</body>
</html>
Here is the dashboard loaded externally on localhost:3000. The left column of the dashboard where Custom Board is expected to load is empty, but the right column with a custom html code of a board loads successfully:
It looks like the canned Custom Board cannot be loaded externally but a custom html code written in AppSDK2 can be displayed externally.
A couple of observations:
There is really no upgrade path from AppSDK1 to AppSDK2. The underlying frameworks and the class structures are very different and the code cannot be simply refactored. There is no translation from one to the other.
LoginKey is intended to work with AppSDK1. Both are legacy. Both predate AppSDK2 and ApiKey. To use ApiKey with custom html apps written with AppSDK2 see "Use API Key with AppSDK2" article.
AppSDK2 does not support LoginKey usage for authentication. The reason it seems to work in this example is that we load the entire page. Loading the entire page using iframe's src property is possible with LoginKey. In this example there is no reason to use ApiKey and LoginKey together. You are right that ApiKey makes no difference in this use case.
The way LoginKey works is that it "tricks" the browser into thinking that there is this different server, loginapirally1.rallydev.com. If you look in Network tab of your browser and see that request comes from there it means that LoginKey is working. ApiKey works differently. There is no equivalent to loginapirally1 server with ApiKey.
If you are being prompted to supply login credentials when using LoginKey it means that LoginKey is not working. See "LoginKey Troublshooting" article.
Embedding custom AppSDK2 apps in 3rd party portals (running custom apps externally) is possible with ApiKey, and the supported scenario described in this guide is similar to the option (1) you mentioned in the end of your post. Loading entire Rally page or entire Rallynavigation is not a supported use case even though it is possible with LoginKey.
I started out with Angular and came across this code that should work, but it doesn't.
Angular is downloaded and added via the script tag and it is correct, others tutorials worked before.
I have tried everything but just doesnt seem to find out what's the problem. Started learning from the book AngularJS from O'Reilly.
<html ng-app="nameApp">
<head>
<title>Angular Training</title>
</head>
<body ng-controller="NameCtrl">
<ul>
<li ng-repeat="name in names"> {{ name }}
remove
</li>
</ul>
<form ng-submit="addName()">
<input type="text" ng-model="enteredName">
<input type="submit" value="add">
</form>
<script src='unzipped___AngularJS-1.3.12\angular-1.3.12\angular.min.js'></script>
<script>
var nameApp = angular.module('nameApp', []);
nameApp.controller('NameCtrl', function ($scope){
$scope.names = ['Larry','Curly', 'Moe'];
$scope.addName = function(){
$scope.names.push($scope.enteredName);
$scope.enteredName = '';
};
$scope.removeName = function(name){
var i = $scope.names.indexOf(name);
$scope.names.splice(i, 1);
};
});
</script>
</body>
</html>
https://jsfiddle.net/eqk5adc1/3/
https://jsfiddle.net/5qv2e2jm/
Try adding this
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
Based on comments, it sounds like you are likely running into security issues. Modern browsers can typically prevent loading external js files from the local file system for security reasons. This is dependent on the browser you use. For more information, this security concept is called the same-origin policy.
"this is a Javascript frameworks so in my opinion a server could be omitted..."
This is not necessarily true because of the aforementioned security concept. If you are using Firefox you can disable this security feature (though I would recommend only temporarily) using the following steps:
Navigate to about:config
In the search bar type security.fileuri.strict_origin_policy
Set this property to false.
These steps should allow local js files to be loaded in Firefox. In the end, it may be easier to simply setup a server or use a cheap cloud server (google, amazon, c9.io, etc.). Another option might be just using jsfiddle like you did above.
This is important for me as I have a PRN file which can be printed only through command prompt. And I want to delete that file after the print command is given.
So these 2 commands can be executed using batch file only.
And when I try to use activexobject in javascript, my firefox browsers doesnt run it.
<script>
MyObject = new ActiveXObject("WScript.Shell");
function Runbat()
{
MyObject.Run("\"D:\\abc.bat\"");
}
</script>
Together in a html page.
I've found this one and it seems working properly :)
<html>
<head>
<script language="JavaScript" type="text/javascript">
MyObject = new ActiveXObject("WScript.Shell")
function Runbat()
{
MyObject.Run("\"D:\\test.bat\"");
}
</script>
</head>
<body>
<h1>Run a Program</h1>
This script launch the file any bat File<p>
<button onclick="Runbat()">Run bat File</button>
</body>
</html>
Now I don't really know if you are already working with exaclty that solution, if so, and you are still facing this issue in firefox you may need to investigate a little bit more in browser security to know if that is even possible as of this post states that:
No, that would be a huge security breach. Imagine if someone could run
format c:
whenever you visted their website.