I'm creating a small Windows Sidebar Gadget for taking notes in a simple textarea
.
I have, as usual, a gadget.xml
manifest file and a .html
file, see below.
How is it possible to read some data / save some data in a Gadget?
I know this is usually impossible with JavaScript only (note: using localstorage
is not possible because I want persistance of data), so how to save/read data inside a Windows Gadget
?
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Unicode" />
<title>NeverForget</title>
<style type="text/css">
body
{
margin: 0;
width: 300px;
height: 200px;
background-color: transparent;
}
#gadgetContent
{
width: 100%;
height: 100%;
overflow: hidden;
border: none;
background-color: transparent;
}
</style>
<script type="text/jscript" language="jscript">
function init() {
// how to load notes from a file here on startup?
}
window.onkeydown = function () {
// how to save data to file?
}
</script>
</head>
<body onload="init()">
<textarea id="gadgetContent">Bonjour</textarea>
</body>
</html>
Try one of these:
There are the inbuilt methods of the System.Gadget.Settings object which can be used to to read/write from the Settings.ini file (stored in C:\Users\[user]\AppData\Local\Microsoft\Windows Sidebar) but this information will be lost if the gadget is closed or uninstalled.
Use the FileSystemObject to create or read or write folders/files anywhere. Limitation: file can only be saved as unicode or ascii.
Use an ADO Stream object to create or read or write files anywhere. Limitation: can't create folders - must be used in conjunction with the FileSystemObject. Advantage: can use any codepage that exists on your computer.
Since I like saving text files with utf-8 the example below uses the third method but you may well decide to dispense with some of the error handling. (NB - this example is based on a script published by Andrew Urquhart)
Fortunately the sidebar is able to use knownfolders and knownfolderpaths so finding the path to your documents folder for example is as easy as
var docs = System.Shell.knownFolderPath("Documents");
Remember that the backslash is an escape character in javascript so that paths in strings must have their backslashes doubled.
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>NeverForget</title>
<style type="text/css">
<!--
body {margin:0;width:300px;height:200px;background-color:transparent;padding:10px;}
#gadgetContent {width:280px;height:144px;overflow:auto;border:1px solid black;background-color:#eee;}
button {margin-left:66px;margin-top:10px;}
#message {display:none;width:280px;height:180px;position:absolute;top:10px;left:10px;background-color:#eee;border:1px solid red;}
#messageContent {width:278px;height:144px;word-wrap:break-word;overflow-y:auto;}
#newButton {position:absolute;bottom:10px;left:54px;}
-->
</style>
<script type="text/jscript">
//globals
var myFolderPath=System.Shell.knownFolderPath("Documents")+"\\myFiles";
//end globals
function showMessage(msg){
message.style.display="block";
messageContent.innerText=msg;
}
function closeMessage(){
message.style.display="none";
messageContent.innerText="";
}
function loadFile(strAbsoluteFilePath, strCharSet){
var adReadAll=-1, adReadLine=-2, strFileContents="", objStream=new ActiveXObject("ADODB.Stream"), fso=new ActiveXObject("Scripting.FileSystemObject");
try{
if(!strAbsoluteFilePath){
throw new Error(1, "Required parameter \"strAbsoluteFilePath\" was not defined");
}
if(!strCharSet){
throw new Error(2, "Required parameter \"strCharSet\" was not defined");
}
if(!fso.FolderExists(myFolderPath)){
throw new Error(3, "Folder \""+myFolderPath+"\" does not exist");
}
objStream.Open();
try{
objStream.CharSet=strCharSet;
objStream.LoadFromFile(strAbsoluteFilePath);
strFileContents=objStream.ReadText(adReadAll);
gadgetContent.innerText=strFileContents;
}
catch(err){
throw new Error(err.number, "Loading failed:\r\n" + err.description);
}
finally{
objStream.Close(); // Always close the stream regardless of what happens
objStream=null;
fso=null;
}
}
catch(err){
showMessage("Function loadFile() failed with parameters strAbsoluteFilePath=\"" + strAbsoluteFilePath + "\", strCharSet=\"" + strCharSet + "\". Message=\r\n" + err.description+"\r\nError Number: "+err.number);
}
}
function saveFile(strAbsoluteFilePath, strCharSet, strFileContents, blnOverwrite){
var adSaveCreateNotExist=1, adSaveCreateOverWrite=2, objStream = new ActiveXObject("ADODB.Stream"), fso=new ActiveXObject("Scripting.FileSystemObject");
try{
if(!strAbsoluteFilePath){
throw new Error(1, "Required parameter \"strAbsoluteFilePath\" was not defined");
}
if(!strCharSet){
throw new Error(2, "Required parameter \"strCharSet\" was not defined");
}
if(typeof strFileContents != "string"){
throw new Error(3, "Required parameter \"strFileContents\" was not a string");
}
if(!fso.FolderExists(myFolderPath)){
fso.CreateFolder(myFolderPath);
}
objStream.Open();
try{
objStream.CharSet=strCharSet;
objStream.WriteText(strFileContents);
objStream.SaveToFile(strAbsoluteFilePath, (blnOverwrite ? adSaveCreateOverWrite : adSaveCreateNotExist));
return true;
}
catch(err){
throw new Error(err.number, "SaveToFile failed:\r\n" + err.description);
}
finally{
objStream.Close(); // Always close the stream regardless of what happens
objStream=null;
fso=null;
}
return false;
}
catch(err){
showMessage("Function saveFile() failed with parameters strAbsoluteFilePath=\"" + strAbsoluteFilePath + "\", strCharSet=\"" + strCharSet + "\", strFileContents=\"" + strFileContents + "\", blnOverwrite=\"" + blnOverwrite + "\". Message=\r\n" + err.description+"\r\nError Number: "+err.number);
}
}
function init(){
loadButton.onclick=function(){loadFile(myFolderPath+"\\myFile.txt","utf-8");};
saveButton.onclick=function(){saveFile(myFolderPath+"\\myFile.txt", "utf-8", gadgetContent.innerText, true);};
closeButton.onclick=closeMessage;
}
</script>
</head>
<body onload="init()">
<textarea id="gadgetContent">Bonjour</textarea>
<div id="message">
<div id="messageContent"></div>
<div id="newButton"><button id="closeButton">Close</button></div>
</div>
<button id="loadButton">Load</button><button id="saveButton">Save</button>
</body>
</html>