I am developing an HTML/JS/CSS app and would like to share it with file base. So I and my team can use it with a local HTML file (file://xxx.html). I have two separate pages (HTML files), one a shopping list and another a pantry. I want to add/mark off things from my shopping list as "bought" which will then fill up the list of items in my pantry.
I have attempted using localstorage but that seems to be domain-based and does not work well between the two files. I am looking for offline solutions as well that must keep the items added to either list saved after closing and reopening the file.
There is no storage associated with file:// URLs. If you can set up a simple local server, or host it on one of the various services with a free tier, that would probably be best.
To do it with just a file, you'll have to have the user explicitly load and save the file:
input type="file" element.This isn't great user experience, of course.
Something along these lines (CodeSandbox link — sadly, Stack Snippets don't allow download):
<div>
<label>
Load list:
<input id="file-load" type="file" />
</label>
</div>
<input id="btn-save" type="button" value="Save List" />
<ul id="list"></ul>
<div>
<label>
Add:
<input id="item-text" type="text" width="20" />
</label>
<input id="btn-add" type="button" value="Add" />
</div>
const listElement = document.getElementById("list");
const fileInput = document.getElementById("file-load");
const saveButton = document.getElementById("btn-save");
const addButton = document.getElementById("btn-add");
const itemText = document.getElementById("item-text");
function addListItem(text) {
const li = document.createElement("li");
li.textContent = text;
listElement.appendChild(li);
}
fileInput.addEventListener("change", (e) => {
e.currentTarget.files[0].text()
.then(json => {
const list = JSON.parse(json);
for (const element of list) {
addListItem(element);
}
})
.catch(error => {
alert("Error loading list file!");
});
});
saveButton.addEventListener("click", () => {
const list = Array.from(
listElement.children,
li => li.textContent
);
const json = JSON.stringify(list);
const blob = new Blob([json], {
type: "application/json"
});
const objUrl = URL.createObjectURL(blob);
const link = document.createElement("a");
link.download = "list.json";
link.href = objUrl;
document.body.appendChild(link);
link.click();
setTimeout(() => { // Older Firefox needed this
document.body.removeChild(link);
}, 100);
});
addButton.addEventListener("click", () => {
const text = itemText.value.trim();
if (text) {
addListItem(text);
}
itemText.value = "";
itemText.focus();
});
That's just maintaining a list of strings, but you can make it a list of objects instead, so you can have your checked flag, etc.)