Web Contact Picker API Not working in PWA android Shell - javascript

I'm not sure if my title explains my problem well.
I have a web application that should allow users to pick contacts from their phone book and add them to their account as emergency contacts.
I came across an API on https://contact-picker.glitch.me/.
The API does not work on desktop, it's not meant to. That's ok, because my web application is for mobile.
I run some tests in chrome for android and the API works very well without any problems.
MY PROBLEM:
I compiled the web application as an android mobile app on several websites that offer this service such as https://gonative.io, https://www.swing2app.com/, and even https://appsgeyser.com/.
The APKs work fine except for the contact picker API. It does not respond when clicked on, despite it being compatible. And when click a second time this is the error I get:
InvalidStateError: Failed to execute 'select' on 'ContactsManager': Contacts Picker is already in use.
I'm not sure how to go about this. I would appreciate any information or help as to how to resolve this problem. Thank you.
Below is my code if it will help. It's just the necessary bit that calls the contact picker. Nothing is processed after that.
`
< !DOCTYPE html >
<html>
<head></head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, minimal-ui, viewport-fit=cover">
<body>
<h2>CONTACT PICKER API</h2>
<p id="requireHTTPS" class="hidden"></p>
<p id="notSupported"></p>
<input type="checkbox" checked hidden id="multiple" />
<input type="checkbox" checked hidden id="name" />
<input type="checkbox" id="email" hidden />
<input type="checkbox" checked hidden id="tel" />
<input type="checkbox" hidden id="address" />
<input type="checkbox" hidden id="icon" />
<!-- END -------- HIDDEN FORM ELEMENTS FOR JS - KEEP OUT OF FROM SUBMIT -->
<button id="butRequest" type="button" class="btn btn-sm btn-danger light" disabled>
Select contacts
</button>
<form action="#" method="post">
<p><textarea cols="80" rows="5" id="demo" name="contacts"></textarea></p>
<button type="submit" name="add_contacts">Add Contacts</button>
</form>
<script>
const butReq = document.getElementById('butRequest');
butReq.addEventListener('click', getContacts);
const cbMultiple = document.getElementById('multiple');
const cbName = document.getElementById('name');
const cbEmail = document.getElementById('email');
const cbTel = document.getElementById('tel');
const cbAddress = document.getElementById('address');
const cbIcon = document.getElementById('icon');
const ulResults = document.getElementById('results');
const preResults = document.getElementById('rawResults');
const supported = ('contacts' in navigator && 'ContactsManager' in window);
if (supported) {
const divNotSupported = document.getElementById('notSupported');
divNotSupported.classList.toggle('hidden', true);
butReq.removeAttribute('disabled');
checkProperties();
}
async function checkProperties() {
const supportedProperties = await navigator.contacts.getProperties();
if (supportedProperties.includes('name')) {
enableProp(cbName);
}
if (supportedProperties.includes('email')) {
enableProp(cbEmail);
}
if (supportedProperties.includes('tel')) {
enableProp(cbTel);
}
if (supportedProperties.includes('address')) {
enableProp(cbAddress);
}
if (supportedProperties.includes('icon')) {
enableProp(cbIcon);
}
}
async function getContacts() {
const props = [];
if (cbName.checked) props.push('name');
if (cbEmail.checked) props.push('email');
if (cbTel.checked) props.push('tel');
if (cbAddress.checked) props.push('address');
if (cbIcon.checked) props.push('icon');
const opts = {
multiple: cbMultiple.checked
};
try {
const contacts = await navigator.contacts.select(props, opts);
handleResults(contacts);
} catch (ex) {
ulResults.classList.toggle('error', true);
ulResults.classList.toggle('success', false);
ulResults.innerText = ex.toString();
}
}
function handleResults(contacts) {
ulResults.classList.toggle('success', true);
ulResults.classList.toggle('error', false);
ulResults.innerHTML = '';
renderResults(contacts);
}
function enableProp(cbox) {
cbox.removeAttribute('disabled');
//cbox.setAttribute('checked', 'checked');
}
function renderResults(contacts) {
contacts.forEach((contact) => {
const lines = [];
if (contact.name) lines.push(`${contact.name}`);
if (contact.tel) lines.push(`${contact.tel}`);
lines.push(`${JSON.stringify(contact)}`);
const li = document.createElement('li');
li.innerHTML = lines.join(',');
//li.disabled= true;
var counter = 1;
li.setAttribute('name', 'contact_' + counter)
ulResults.appendChild(li);
counter = counter + 1;
});
const strContacts = JSON.stringify(contacts, null, 1);
//alert(strContacts);
document.getElementById("demo").innerHTML = strContacts;
}
</script>
</body>
</html>
`
NOTE THAT:
I've tried the same script in browser and it works well.
I've also tried having the contact picker bit of the application to open into chrome browser itself bit it keeps opening in-app. I did this by adding "target='_blank'' to the html element.
Thank you in advance.

Related

Setting a value in html using buttons generated from an Apps Script / javascript array

I am trying to piece together a Google Apps script for a touchscreen clocking in system, and that involves generating some buttons from an array taken from a spreadsheet, but I'm getting a bit lost working out how to get the script to document which of these automatically generated buttons has been pressed.
Basically, I am using a modified version of this script (https://www.youtube.com/watch?v=KGhGWuTjJwc) - I need it to work with a touch screen.
I have got a version of the script given in the video above working. But because the web app must work on a touch screen I need to be able to generate buttons for the input of staff ID and PIN to replace the text boxes.
To do this I am pulling in an array from a Google Sheet that contains all staff initials needed to log in, as well as adding a numeric keypad to enter a PIN.
I have (sort of) successfully borrowed a keypad from here:https://github.com/ProgrammingHero1/batch5-pin-matcher-solution but I am stuck trying to get use buttons for the staff ID input.
I have managed to generate the buttons from the spreadsheet array, using a modified version of this Create an array of buttons from Javascript array but I can't work out how to set staffid to match whichever of the auto-generated buttons was pressed last. Currently those buttons don't do anything.
If anyone can help guide me the last step of the way so that staffid is set using the buttons and not using the text box that would be very much appreciated.
Below is the code I am using. I am aware that it is a dog's breakfast - that's because I am hacking it together from various sources working at (well, realistically well beyond) the limits of my understanding!
Anyway, here is the HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<!-- Metro 4 -->
<link rel="stylesheet" href="https://cdn.metroui.org.ua/v4/css/metro-all.min.css">
<style>
.main-box {
max-width:500px;
}
.error-message {
background:red;
color:white
padding: 1000px;
border-radius: 1000px;
}
</style>
</head>
<body>
<div class="container">
<div class="container d-flex flex-justify-center pt-9">
<div data-role="panel" class="main-box">
<form id="main-form">
<div class="form-group">
<input type="text" data-role="input" data-prepend="Staff ID" id="staffid">
<div class="form-group">
</div>
<div class="form-group">
<button id="start-work" class="button success" type="submit" data-action="Start work">Start work</button>
<button id="finish-work" class="button success" type="submit" data-action="Finish work">Finish work</button>
<button id="start-break" class="button success" type="submit" data-action="Start break">Start break</button>
<button id="finish-break" class="button success" type="submit" data-action="Finish break">Finish break</button>
<div class="input-section half-width">
<input id="typed-numbers" class="form-control" type="text">
<div class="numbers">
<div id="key-pad" class="calc-body">
<div class="calc-button-row">
<div class="button">7</div>
<div class="button">8</div>
<div class="button">9</div>
</div>
<div class="calc-button-row">
<div class="button">4</div>
<div class="button">5</div>
<div class="button">6</div>
</div>
<div class="calc-button-row">
<div class="button">1</div>
<div class="button">2</div>
<div class="button">3</div>
</div>
<div class="calc-button-row">
<div class="button"><</div>
<div class="button">0</div>
<div class="button">C</div>
</div>
</div>
</div>
</div>
</div>
</form>
<div id="message" class="d-none error-message mt4">
Error!!
</div>
</div>
</div>
</body>
<!-- Metro 4 -->
<script src="https://cdn.metroui.org.ua/v4/js/metro.min.js"></script>
<script>
const TSPwebapp = {}
TSPwebapp.onLoad = function(){
TSPwebapp.form = document.getElementById("main-form")
TSPwebapp.staffidInput = document.getElementById("staffid")
TSPwebapp.pinInput = document.getElementById("typed-numbers")
TSPwebapp.startWorkButton = document.getElementById("start-work")
TSPwebapp.finishWorkButton = document.getElementById("finish-work")
TSPwebapp.startBreakButton = document.getElementById("start-break")
TSPwebapp.finishBreakButton = document.getElementById("finish-break")
TSPwebapp.message = document.getElementById("message")
TSPwebapp.form.addEventListener("submit",TSPwebapp.onSubmit)
TSPwebapp.startWorkButton.addEventListener("click",TSPwebapp.startFinishWork)
TSPwebapp.finishWorkButton.addEventListener("click",TSPwebapp.startFinishWork)
TSPwebapp.startBreakButton.addEventListener("click",TSPwebapp.startFinishBreak)
TSPwebapp.finishBreakButton.addEventListener("click",TSPwebapp.startFinishBreak)
} // TSPwebapp.onLoad function
TSPwebapp.onSubmit= function(e){
e.preventDefault()
} // TSPwebapp.onSubmit function
TSPwebapp.startFinishWork = function(e){
const payload = {
staffid: TSPwebapp.staffidInput.value,
pin: TSPwebapp.pinInput.value,
action: e.target.dataset.action
}
google.script.run.withSuccessHandler(() => {
TSPwebapp.staffidInput.value = ""
TSPwebapp.pinInput.value = ""
} ).withFailureHandler(() => {
TSPwebapp.message.classList.remove("d-none")
setTimeout(() => {TSPwebapp.message.classList.add("d-none")},5000)
}).startFinishWork(payload)
} // TSPwebapp.startFinishWork function
TSPwebapp.startFinishBreak = function(e){
const payload = {
staffid: TSPwebapp.staffidInput.value,
pin: TSPwebapp.pinInput.value,
action: e.target.dataset.action
}
google.script.run.withSuccessHandler(() => {
TSPwebapp.staffidInput.value = ""
TSPwebapp.pinInput.value = ""
} ).withFailureHandler(() => {
TSPwebapp.message.classList.remove("d-none")
setTimeout(() => {TSPwebapp.message.classList.add("d-none")},5000)
}).startFinishBreak(payload)
} // TSPwebapp.startFinishBreak function
</script>
<script>
document.getElementById('key-pad').addEventListener('click', function (event) {
const number = event.target.innerText;
const calcInput = document.getElementById('typed-numbers');
if (isNaN(number)) {
if (number == 'C') {
calcInput.value = '';
}
}
else {
const previousNumber = calcInput.value;
const newNumber = previousNumber + number;
calcInput.value = newNumber;
}
});
</script>
<script>
document.addEventListener("DOMContentLoaded",TSPwebapp.onLoad)
document.addEventListener("DOMContentLoaded",function(){
google.script.run.withSuccessHandler(printBtn).useDataRange();
});
function printBtn(staffData) {
for (var i = 0; i < staffData.length; i++) {
var btn = document.createElement("button");
var t = document.createTextNode(staffData[i]);
btn.appendChild(t);
document.body.appendChild(btn);
}
}
window.onload = printBtn();
</script>
</body>
</html>
Here is the Google Apps Script code:
function doGet(e) {
Logger.log(e);
return HtmlService.createHtmlOutputFromFile("form");
}
function useDataRange () {
const ss = SpreadsheetApp.getActiveSpreadsheet()
const wsStaff = ss.getSheetByName("Staff")
const staffData = wsStaff.getRange(2,2,wsStaff.getLastRow()-1,1).getValues()
Logger.log(staffData)
return staffData;
}
function startFinishBreak(payload){
console.log(payload)
if (!["Start work","Finish work","Start break","Finish break"].includes(payload.action)){
throw new Error("Sign in or sign out failed")
return
}
console.log("Initial check passed")
const ss = SpreadsheetApp.getActiveSpreadsheet()
const wsBreakData = ss.getSheetByName("Break data")
const wsStaff = ss.getSheetByName("Staff")
const staffData = wsStaff.getRange(2,2,wsStaff.getLastRow()-1,3).getValues()
const matchingStaff = staffData.filter(r => r[0].toString() === payload.staffid && r[2].toString() === payload.pin)
if(matchingStaff.length !== 1){
throw new Error("Sign in or sign out failed")
return
}
const idsData = wsBreakData.getRange(2,2,wsBreakData.getLastRow()-1,3).getValues()
console.log(idsData)
const matchingIdsData = idsData.filter(r => r[0].toString() === payload.staffid)
console.log(matchingIdsData)
const latestAction = matchingIdsData.length === 0 ? "Finish break" : matchingIdsData[matchingIdsData.length-1][2]
if (latestAction === payload.action){
throw new Error("Sign in or sign out failed")
return
}
wsBreakData.appendRow([new Date(),payload.staffid,payload.pin,payload.action])
}
function startFinishWork(payload){
console.log(payload)
if (!["Start work","Finish work","Start break","Finish break"].includes(payload.action)){
throw new Error("Sign in or sign out failed")
return
}
console.log("Initial check passed")
const ss = SpreadsheetApp.getActiveSpreadsheet()
const wsWorkData = ss.getSheetByName("Work data")
const wsStaff = ss.getSheetByName("Staff")
const staffData = wsStaff.getRange(2,2,wsStaff.getLastRow()-1,3).getValues()
const matchingStaff = staffData.filter(r => r[0].toString() === payload.staffid && r[2].toString() === payload.pin)
if(matchingStaff.length !== 1){
throw new Error("Sign in or sign out failed")
return
}
const idsData = wsWorkData.getRange(2,2,wsWorkData.getLastRow()-1,3).getValues()
console.log(idsData)
const matchingIdsData = idsData.filter(r => r[0].toString() === payload.staffid)
console.log(matchingIdsData)
const latestAction = matchingIdsData.length === 0 ? "Finish work" : matchingIdsData[matchingIdsData.length-1][2]
if (latestAction === payload.action){
throw new Error("Sign in or sign out failed")
return
}
wsWorkData.appendRow([new Date(),payload.staffid,payload.pin,payload.action])
}
I hope this description all more or less makes sense - I am trying something a way beyond by current capabilities but I do need to get this task done and hopefully I'm learning in the process.
You need to add a value and event listener to each button. Then you can use the value to determine which button was pressed.
I have updated my script to address the comments below.
First add a new division.
<div id="staffButtons">
</div>
<div id="message" class="d-none error-message mt4">
Next make some changes to original script as shown.
function printBtn(staffData) {
let div = document.getElementById("staffButtons"); // add this
for (var i = 0; i < staffData.length; i++) {
var btn = document.createElement("button");
var t = document.createTextNode(staffData[i]);
btn.value = staffData[i]
btn.addEventListner("click",buttonClick);
btn.appendChild(t);
div.appendChild(btn); // change this
}
}
function buttonClick() {
document.getElementById("staffid") = this.value;
}
Reference
addEventListener

localStorage not working properly/localStorage overwriting itself

I'm attempting to create a simple to-do list and I've encountered two problems:
After refreshing the page, all the created elements are no longer visible on the page despite being in local storage.
After refreshing the page and submitting new values to the input, localStorage overwrites itself.
Despite that, the items displayed from the input fields are from the previous localStorage, which no longer exists (I really hope this makes sense).
const inputEl = document.getElementById("inputEl")
const submitBtn = document.getElementById("submit")
const clearBtn = document.getElementById("clearBtn")
const todoListContainer = document.getElementById("todoList")
const taskContainer = document.querySelector(".task")
const cancelBtn = document.querySelector(".cancelBtn")
const doneBtn = document.querySelector(".doneBtn")
const errorMsg = document.querySelector(".error")
let localStorageContent = localStorage.getItem("tasks")
let tasksItem = JSON.parse(localStorageContent)
let tasks = []
function createTask() {
if (inputEl.value.length != 0) {
const newDiv = document.createElement("div")
newDiv.classList.add("task")
const newParagraph = document.createElement("p")
const newCancelBtn = document.createElement("button")
newCancelBtn.classList.add("cancelBtn")
newCancelBtn.textContent = "X"
const newDoneBtn = document.createElement("button")
newDoneBtn.classList.add("doneBtn")
newDoneBtn.textContent = "Done"
todoListContainer.appendChild(newDiv)
newDiv.appendChild(newParagraph)
newDiv.appendChild(newCancelBtn)
newDiv.appendChild(newDoneBtn)
//^^ Creating a container for a new task, with all its elements and assigning the classes^^
tasks.push(inputEl.value)
inputEl.value = ""
for (let i = 0; i < tasks.length; i++) {
localStorage.setItem("tasks", JSON.stringify(tasks))
newParagraph.textContent = JSON.parse(localStorageContent)[i]
}
errorMsg.textContent = ""
} else {
errorMsg.textContent = "You have to type something in!"
errorMsg.classList.toggle("visibility")
}
}
submitBtn.addEventListener("click", () => {
createTask()
})
clearBtn.addEventListener("click", () => {
localStorage.clear()
})
HTML code below:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="/style.css">
<script src="/script.js" defer></script>
<title>To-do list</title>
</head>
<body>
<h2 class="error visibility"></h2>
<div id="todoList">
<h1>To-Do List</h1>
<input type="text" name="" id="inputEl" placeholder="Add an item!">
<button type="submitBtn" id="submit">Submit</button>
<button id="clearBtn">Clear list</button>
<div class="task">
</div>
</div>
</body>
</html>
After refreshing the page, all the created elements are no longer visible on the page despite being in local storage
That is because you are rendering the HTML only after the click event and not on page load. To render the HTML for existing tasks stored in the localStorage you have to write a code that loops over your existing tasks in the tasksItem and applies the rendering logic to it.
I would suggest splitting the rendering code from your createTask() function and create a new function for it (for example renderTask()), then you can use it inside a loop on page load and also call the function once a new task is created in the createTask() function.
window.addEventListener('load', (event) => {
// Your read, loop and render logic goes here
})
After refreshing the page and submitting new values to the input, localStorage overwrites itself.
That's because you are actually overriding the tasks in the localStorage. To keep existing tasks, you have to use your tasksItem variable instead of the blank tasks array to create your tasks in and save them to the localStorage.
So, instead of:
tasks.push(inputEl.value)
You would use:
tasksItem.push(inputEl.value)
The same goes for:
for (let i = 0; i < tasksItem.length; i++) {
localStorage.setItem("tasks", JSON.stringify(tasksItem))
// …
}

How to implement custom Tensorflow.js models into webpage?

I would like to create a website that can classify different types of cars. I have managed to get the website working to use the mobile net model, but I would like to use a custom model that I trained in google colab and then converted into javascript. Does anyone know how I could achieve this?
Here is the javascript code:
// Defining Variables
const webcamElement = document.getElementById('webcam');
let net;
var webcamrunning = false; // Flag, indicates if webcam-prediction is running or not
var bw = document.getElementById('butwebcam')
var bi = document.getElementById('butimage')
// App that predicts image
async function app() {
console.log('Loading mobilenet..');
const uploadJSONInput = document.getElementById('upload-json');
const model = await tf.loadLayersModel(tf.io.browserFiles([uploadJSONInput.files[0]]));
// Check if model loaded, if not, load it.
if (net == undefined)
{bi.innerHTML = 'Wait for Initiation...';
net = await model.load();
console.log('Sucessfully loaded model');
bi.innerHTML = 'Predict'}
else {console.log('Model already loaded')};
// Make a prediction through the model on our image.
const imgEl = document.getElementById('output');
const result = await net.classify(imgEl);
document.getElementById('console_pic').innerText =
`Prediction: ${result[0].className}
Probability: ${Math.round(result[0].probability*100)} %
`;
}
// Function that activates (starts webcam app) and deactivates the Webcam-Prediction
function start_webcam(){
if (webcamrunning == false)
{app_webcam();
}
else {webcamrunning = false;
bw.innerHTML = 'Activate Predicting';
};
};
// Setup Webcam
async function setupWebcam() {
return new Promise((resolve, reject) => {
const navigatorAny = navigator;
navigator.getUserMedia = navigator.getUserMedia ||
navigatorAny.webkitGetUserMedia || navigatorAny.mozGetUserMedia ||
navigatorAny.msGetUserMedia;
if (navigator.getUserMedia) {
navigator.getUserMedia({video: true},
stream => {
webcamElement.srcObject = stream;
webcamElement.addEventListener('loadeddata', () => resolve(), false);
},
error => reject());
} else {
reject();
}
});
}
// Webcam application
async function app_webcam() {
console.log('Loading mobilenet..');
// Check if model loaded, if not, load it.
if (net == undefined)
{bw.innerHTML = 'Wait for Initiation...';
net = await mobilenet.load();
console.log('Sucessfully loaded model');}
else {console.log('Model already loaded')};
await setupWebcam();
webcamrunning =true;
bw.innerHTML = 'Stop Predicting';
while (webcamrunning) {
const result = await net.classify(webcamElement);
document.getElementById('console_vid').innerText =
`Prediction: ${result[0].className}
Probability: ${Math.round(result[0].probability*100)} %
`;
// Give some breathing room by waiting for the next animation frame to
// fire.
await tf.nextFrame();
}
}
;
Here is the html code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel='stylesheet' href='styles.css'/>
<input type="file" id="upload-json" src="C:\Users\USER\Desktop\ImageClassifier-master\model\model.json"/>
<!-- Load the latest version of TensorFlow.js -->
<script src="https://unpkg.com/#tensorflow/tfjs"></script>
<script src="https://unpkg.com/#tensorflow-models/mobilenet"></script>
<title> Image Classifier with MobileNet </title>
</head>
<body>
<img style='margin-top: -6px; z-index: 19;' id="header" height ="320">
<h1 style='margin-top: -35px'> What car is that?</h1>
<br>
<hr/>
<br>
<em> <strong> </strong> </em>
<br>
<br>
<hr/>
<br>
<h2> Upload your own Picture</h2>
<!-- Upload Function with File Preview -->
<input type="file" accept=".png, .jpg, .jpeg" height="200"
onchange="document.getElementById('output').src = window.URL.createObjectURL(this.files[0])">
<!-- Predict button, calls predict function in Javascript -->
<button id="butimage" onclick="app()"> Predict! </button>
<!-- Window for Picture Preview -->
<div class = "window">
<span class="helper"></span>
<img class="center" id="output" alt="your image" src = "img/example.jpg" />
</div>
<div class = "result" id="console_pic">Result</div>
<br>
<hr/>
<br>
<br>
<br>
<br>
<script src="index.js"></script>
</body>
</html>

How to make a not bootable counter when refreshing the web page?

I want to make a counter remains dynamic and non-bootable when updating
web page,
here is my code the problem is that when I refresh the page the counter(setTimeout) will count again from zero to 5 I want it to count from the last value before
the refresh
<html>
<head>
<meta charset="utf-8"/>
<title>Insert title here</title>
</head>
<script type="text/javascript">
setTimeout(function(){document.getElementById("tm").style.display='block'},
5000);
</script>
<body>
<form id="customer" action="/htmlvalidation" method="post">
<div>
<label>Time</label>
<input id="tm" type="text" style="display: none;"/>
</div>
<div>
<button type="submit">Add Customer</button>
</div>
</form>
</body>
</html>
thank you
You will have to manually store the counter value in the client's browser; by default, browsers will not retain any of a webpage's state when it is closed (or refreshed). For example, you may use the localStorage API:
const STORAGE_KEY = 'counter';
const TARGET_ELEMENT_ID = 'counter-div';
const INTERVAL = 1000;
const INC = 1;
// Notice the '+' below to make sure val is a number.
let val = +localStorage.getItem(STORAGE_KEY) || 0;
document.getElementById(TARGET_ELEMENT_ID).innerHTML = val;
setInterval(() => {
val += INC;
localStorage.setItem(STORAGE_KEY, val);
document.getElementById(TARGET_ELEMENT_ID).innerHTML = val;
}, INTERVAL);
Here is a working example on codepen (it seems stackoverflow's snippets do not support localStorage).
(I didn't use your snippet because I wasn't sure what you were trying to do).
You could store the last timer iteration using localStorage before the user closes or navigates away from the tab, and resume when needed.
More about localStorage

Save Button-Click Count in localStorage in javascript

I made a button click counter for a website using some JavaScript.
The counter works well, but now I'm stuck in making the saving of the count. You know, if I click the button 3 times, the text says 3 Times. But I want to save that value so if the user refreshes the page, it should display 3 Times again.
I knew of using localStorage, I followed a simple tutorial and applied it to my code, but it does not seem to be working. When I run the page in Microsoft Edge and see the Debug page (F12), the console throws an error that says: Unable to get property 'getItem' of undefined or null reference. I searched in other posts but no one of these could solve my problem. It seems to be stuck when retrieving the value in localStorage.
This is my code:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Increment count when button is clicked</title>
</head>
<body>
<input type="button" value="Registrar" id="countButton" />
<input id="ocityField" type="text" value="" placeholder="Ciudad de Origen"/>
<input id="cityField" type="text" value="" placeholder="Ciudad de participación"/>
<input id="name" type="text" value="" placeholder="Nombre"/>
<p>Personas Registradas: <span id="displayCount">0</span></p>
<script type="text/javascript">
var count = 0;
var button = document.getElementById("countButton");
var display = document.getElementById("displayCount");
var textbox = document.getElementById("ocityField");
var textboxa = document.getElementById("cityField");
var textboxb = document.getElementById("name");
if(window.localStorage.getItem('count')){
var savedcount = window.localStorage.getItem('count');
count = window.localStorage.getItem('count');
}else{
count = 0;
}
display.innerHTML = count;
button.onclick = function(){
var mystring = textbox.value;
var mystring2 = textboxa.value;
var mystring3 = textboxb.value;
if(!mystring.match(/\S/) || !mystring2.match(/\S/) || !mystring3.match(/\S/)) {
alert ('Empty value is not allowed');
return false;
} else {
count++;
window.localStorage.setItem('count', count);
display.innerHTML = count;
textbox.value = "";
textboxa.value = "";
textboxb.value = "";
return true;
}
}
</script>
</body>
</html>
I tried using window.localStorage and just localStorage but no one did work.
May be that you use the IE browser does not support localStorage,The code can run in Chrome49.
Can I Use localStorage, here you can check what browser supports localStorage with version numbers.
Alternate way to store data on client side is cookies if localStorage doesn't supported by browser.
You can also use third party plugins like Modernizer, to check whether browser supports or not.
Modernizr.localstorage if it evaluate to true the browser supports localStorage.
Following example demonstrates localStorage and cookies depending on browser compatibility. uses Modernizer and jQuery
codepen

Categories