As you might know from my previous posts, I am developing a chrome extension. I have a button that toggles the extension on & off, and this button's state is saved when you click out of the extension. You can see the code for this below:
popup.html
<!DOCTYPE html>
<html>
<head>
<link rel="StyleSheet" type="text/css" href="style_popup.css"/>
<script type="text/javascript" src="popup.js"></script>
</head>
<body>
<div class="navbar">
View My Dashboard
</div>
<h1 class="center">[Title]</h1>
<button id="buttonclick" class="button">Enable Control</button>
<br> <img src="green_circle.PNG" height="140" width="150" id="centerimage"> <br>
<p class="center" id="status"> [Title] is running! </p>
</body>
</html>
popup.js
let changeColor = document.getElementById('changeColor');
chrome.storage.sync.get('color', function(data) {
changeColor.style.backgroundColor = data.color;
changeColor.setAttribute('value', data.color);
});
document.addEventListener('DOMContentLoaded', function() {
var link = document.getElementById('buttonclick');
// onClick's logic below:
link.addEventListener('click', function() {
handler();
});
});
function handler()
{
chrome.storage.local.get({count: 0}, function (result) {
var count = result.count;
var buttonState = document.getElementById('buttonclick');
var imageState = document.getElementById('centerimage');
var status = document.getElementById('status');
if (count == 0) {
buttonState.style.backgroundColor = "#75ad0a";
buttonState.innerHTML = "Enabled";
imageState.src = "green_circle.PNG";
status.innerHTML = "[Title] is running!"
count = 1;
}
else {
buttonState.style.backgroundColor = "#AA2B0E";
buttonState.innerHTML = "Disabled";
imageState.src = "red_circle.png";
status.innerHTML = "[Title] is not running!"
count = 0;
}
chrome.storage.local.set({count: count});
});
}
However, I am running into a bit of a pickle. I want to make it such that if a user were to click the button (thereby disabling the extension), exit the chrome extension, and then click back into it, it would still show as disabled. With my current case, however, it will just display the "Enable Control" and "[Title] is running" every time they open the extension UNTIL the user clicks the button. In other words, it would be reset & and I want the state to be preserved. As you can see from my popup.js, I've already written code that saves the state of a variable, but I am unsure how to actually make the state be preserved in the HTML. I would greatly appreciate any help, thanks!
Related
I am currently attempting to learn Javascript and starting with a very basic incremental game where you click a button and it increases. I implemented a save button that properly saves to local storage, however upon refresh, it gets reset.
This is the local storage after hitting save, however, it gets reset to 0 when the page is refreshed.
I wanted to implement save functionality in the following way (see loadGame() and saveGame()):
// JavaScript Document
var saveState = {
food: 0
};
var GlobalFood = 0;
window.onunload = saveGame();
window.onload = loadGame();
function loadGame(){
var loadSaveStateString = localStorage.getItem('saveState');
saveState = JSON.parse(loadSaveStateString);
}
function saveGame(){
var saveStateString = JSON.stringify(saveState);
localStorage.setItem('saveState', saveStateString);
}
function tutorialFoodBtnFunc() {
var fVal = document.getElementById("GlobalFood");
GlobalFood++;
fVal.innerHTML = GlobalFood;
saveState['food'] = GlobalFood;
}
function tutorialFoodBtnFunc2() {
var fVal = document.getElementById("GlobalFood");
if(GlobalFood < 1)
{
var foodError = document.getElementById("foodErrorText");
foodError.classList.add("fade-in");
setTimeout(function (){
foodError.classList.remove("fade-in");
}, 2000)
}
else
{
GlobalFood--;
fVal.innerHTML = GlobalFood;
saveState.food = GlobalFood;
}
}
Here's my HTML as well if it's relevant:
<html>
<head>
<meta charset="utf-8">
<title>Wilderness</title>
<link rel="stylesheet" href="styling/tutorial.css">
<script src="js/main.js"></script>
</head>
<div id="page-wrapper">
<body>
<div id="nav">
<p class="GlobalVals">Foodstuffs: </p><span class="GlobalVals" id = "GlobalFood">0</span>
</div>
<div id="tutorialBody">
<button id="tutorialFoodBtn" onclick="tutorialFoodBtnFunc()">Gather Berries</button>
<button id="tutorialFoodBtn2" onclick="tutorialFoodBtnFunc2()">Eat Berries</button>
<p id="foodErrorText">You have no berries!!!</p>
<button id="tutorialFoodBtn2" onclick="saveGame()">Save!!</button>
</div>
</body>
</div>
</html>
First of all, onunload and onload should reference a function. (What you did is execute the function)
window.onunload = saveGame;
window.onload = loadGame;
Then, your code is properly loading the saveState, but you're not assigning it to your GlobalFood variable.
function loadGame(){
var loadSaveStateString = localStorage.getItem('saveState');
saveState = JSON.parse(loadSaveStateString);
GlobalFood = saveState.food;
var fVal = document.getElementById("GlobalFood");
fVal.innerHTML = GlobalFood;
}
I am working on the tablet's display of a Pepper robot; I have a functional HTML index page comprising a list of questions—each question redirects to its respective HTML when clicked on—, 2 volume buttons and 2 other buttons—one that pops up an instruction image and the other one that closes the index page and gets back to the splash screen, which when clicked upon, reveals the index page. So far everything is working. The issue is that when I click a question—I get redirected to its HTML page, but then I get stuck there, as neither the 2 volume buttons nor the 2 other buttons work;
I made sure to include the following in each HTML page:
<script type="text/javascript" src="/libs/qimessaging/2/qimessaging.js"></script>
<script type="text/javascript" src="faq.js"></script>
I also reused the same JavaScript functions that worked for the index page.
I commented out some line:
btnPrevious.addEventListener('click', goToPreviousPage);
because I noticed it prevented the splash screen from disappearing when clicked on—i.e., the visibility attribute stays on visible instead of switching to hidden thus revealing the index page, but still, the 3 remaining buttons don't work anyway.
Here is my faq.js code:
/* global QiSession */
var serviceName = 'ADFAQ';
var volumeUpEvent = serviceName + '/VolumeUp';
var volumeDownEvent = serviceName + '/VolumeDown';
var volumeData = serviceName + '/Volume';
/* Clickable buttons */
var btnReturn = document.getElementById('return');
var btnHelp = document.getElementById('call_help');
var btnPrevious = document.getElementById('previous_page');
var btnVolUp = document.getElementById('volume-up');
var btnVolDown = document.getElementById('volume-down');
/* Help image and splash screen */
var helper = document.getElementById('helper');
var img = document.getElementById('click_on_me');
var memory;
var volume;
var audioDevice;
QiSession(connected, disconnected);
function connected (s) {
console.log('QiSession connected');
var questions = document.getElementById('questions');
/* Associating buttons to their respective functions */
btnHelp.addEventListener('click', showHelper);
btnReturn.addEventListener('click', closeQuestions);
//btnPrevious.addEventListener('click', goToPreviousPage);
btnVolUp.addEventListener('click', raiseVolume);
btnVolDown.addEventListener('click', lowerVolume);
img.addEventListener('click', loadQuestions);
questions.addEventListener('click', clickOnQuestion);
s.service('ALMemory').then(function (m) {
m.subscriber(serviceName + '/DialogEnded').then(function (subscriber) {
subscriber.signal.connect(hideQuestions);
});
m.subscriber(serviceName + '/Pepper').then(function (subscriber) {
subscriber.signal.connect(displayPepperHTML)
});
m.subscriber(serviceName + '/RaiseVolume').then(function (subscriber) {
subscriber.signal.connect(raiseVolume);
});
m.subscriber(serviceName + '/LowerVolume').then(function (subscriber) {
subscriber.signal.connect(lowerVolume);
});
memory = m;
});
s.service('ALAudioDevice').then(function (a) {
a.getOutputVolume().then(assignVolume);
audioDevice = a
});
}
function disconnected () {
console.log('QiSession disconnected');
}
function assignVolume(value){
volume = value;
}
function raiseVolume (event) {
var changed = 0;
if(volume < 100) {
volume = Math.min(volume + 5, 100);
audioDevice.setOutputVolume(volume);
changed = 1;
}
memory.insertData(volumeData, volume);
memory.raiseEvent(volumeUpEvent, changed);
}
function lowerVolume (event) {
var changed = 0;
if(volume > 30) {
volume = Math.max(volume - 5, 0);
audioDevice.setOutputVolume(volume);
changed = 1;
}
memory.insertData(volumeData, volume);
memory.raiseEvent(volumeDownEvent, changed);
}
function showHelper (event) {
if (btnHelp.innerHTML === '?') {
helper.style.opacity = '1';
helper.style.zIndex = '1';
btnHelp.innerHTML = '←';
} else {
helper.style.opacity = '0';
helper.style.zIndex = '-1';
btnHelp.innerHTML = '?';
}
btnHelp.blur();
}
function loadQuestions (event) {
memory.raiseEvent(serviceName + '/LoadQuestions', 1);
img.style.visibility = 'hidden';
}
function goToPreviousPage () {
window.location.href = "index.html";
}
function displayPepperHTML() {
window.location.href = "pepper.html";
}
function closeQuestions (event) {
if(location.href != "index.html")
{window.location.href = "index.html";}
memory.raiseEvent(serviceName + '/CloseQuestions', 1);
btnReturn.blur();
}
function hideQuestions (data) {
if (data !== 0) {
img.style.visibility = 'visible';
helper.style.opacity = '0';
btnHelp.innerHTML = '?';
}
}
function clickOnQuestion (event) {
memory.raiseEvent(serviceName + '/' + event.target.id, 1);
}
Here is my non-functioning pepper.html code:
<!DOCTYPE html>
<html lang="fr">
<head>
<title>Pepper</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=1280, user-scalable=no" />
<link type="text/css" rel="stylesheet" href="css/style.css" />
<link type="text/css" rel="stylesheet" href="css/faq.css" />
</head>
<body>
<header>
<h1>Bla bla bla</h1>
<span class="buttons">
<button id="previous_page" class="button-help"> ← </button>
<button id="return" class="button-return">X</button>
</span>
<div id="helper" class="pop-up">
<img src="img/interactionscreen_frf.png" alt="Bla bla bla">
</div>
</header>
<ul id="questions">
<p>
Bla bla bla
</p>
<div class="volume-part">
<div id="volume-up" class="Click-me">+</div>
<img src="img/speaker.png" alt="Bla bla bla" style="vertical-align: middle;">
<div id="volume-down" class="Click-me">-</div>
</div>
</ul>
<script type="text/javascript" src="/libs/qimessaging/2/qimessaging.js"></script>
<script type="text/javascript" src="faq.js"></script>
</body>
</html>
Thank you for your help.
I am expecting the pepper.html page to respond to both the volume and ← and X buttons, as the index.html should, since they use the exact same Javascript.
I was able to find some workaround: creating one JavaScript file for each HTML page, this is redundant and non-optimal I know, but at least it works.
This also made me realize that the commented-out line was blocking the program because the index.html page doesn't use the previous_page button, that's what led me to make a JS file for each HTML page.
If anybody has any other suggestions I am all ears.
Edit: I reduced the number of JS scripts to only 2. One for the index.html and the other for the identically-structured html pages of the other questions.
So this code selects random image whenever a person loads my website, how can I change the code so that images are selected sequentially from first to last everytime a person loads the website and then again resets to first image when the counter reaches the end?
P.s- The code works fine on hosting server, here it gives an error i don't know why.
window.onload = choosePic;
var myPix = new Array("https://i.imgur.com/LHtVLbh.jpg", "https://i.imgur.com/2YHazkp.png", "https://i.imgur.com/Uscmgqx.jpg");
function choosePic() {
var randomNum = Math.floor(Math.random() * myPix.length);
document.getElementById("myPicture").src = myPix[randomNum];
}
<!DOCTYPE html>
<html>
<head>
<title>Random Image</title>
<script src="thumb.js"></script>
</head>
<body>
<img src="images/spacer.gif" id="myPicture" alt="some image">
</body>
</html>
You can use localstorage to achieve this. When the user enters the website, you can do something like:
var pictureIndex = localstorage.getItem("pictureIndex");
But since it may be the user's first visit, it would be better to have:
var pictureIndex = localstorage.getItem("pictureIndex") || 0;
Then, you just increment the pictureIndex and perform a modulo operation (for the case when this is the last image)
pictureIndex = (pictureIndex + 1) % myPix.length;
To save this index, you can use
localStorage.setItem('pictureIndex', pictureIndex);
Next time when the user refreshes the page (or comes back), he will get the next picture in your array.
The final code should look like this:
window.onload = choosePic;
var myPix = new Array("https://i.imgur.com/LHtVLbh.jpg", "https://i.imgur.com/2YHazkp.png", "https://i.imgur.com/Uscmgqx.jpg");
function choosePic() {
var pictureIndex = window.localStorage.getItem("pictureIndex") || 0;
pictureIndex = (pictureIndex + 1) % myPix.length;
window.localStorage.setItem("pictureIndex", pictureIndex);
document.getElementById("imgid").innerHTML = pictureIndex;
document.getElementById("myPicture").src = myPix[pictureIndex];
}
<!DOCTYPE html>
<html>
<head>
<title>Random Image</title>
<script src="thumb.js"></script>
</head>
<body>
Press "Run" multiple times to cycle through the images.
Currently showing: <span id="imgid"></span>
<img src="images/spacer.gif" id="myPicture" alt="some image">
</body>
</html>
Note that the above code might not work here (but you can test it locally) due to some security restrictions from jsfiddle. A working version can be accessed >here<
function choosePic() {
var local_item = 0;
if(localStorage.getItem('pic_key')){
local_item = parseInt(intvlocalStorage.getItem('pic_key'));
}
if(local_item >= myPix.length){
local_item = 0;
}
localStorage.setItem('pic_key', local_item + 1);
document.getElementById("myPicture").src = myPix[local_item];
}
You can use LocalStorage to achieve this. When the user enters the website, you can store the key and increment it.
Use local storage to save the data you need [e.g. visited = 3(3rd time the same person visited your website)]
Your js code can be implemented like this:
window.onload = choosePic;
var myPix = new Array("https://i.imgur.com/LHtVLbh.jpg", "https://i.imgur.com/2YHazkp.png", "https://i.imgur.com/Uscmgqx.jpg");
function choosePic() {
if (localStorage.getItem('visited') == null)
{
document.getElementById("myPicture").src = myPix[0];
localStorage.setItem('visited', 1);
}
else if (localStorage.getItem('visited') >= myPix.length)
{
localStorage.setItem('visited', 0);
document.getElementById("myPicture").src = myPix[localStorage.getItem('visited')];
}
else
{
document.getElementById("myPicture").src = myPix[localStorage.getItem('visited')];
localStorage.setItem('visited', localStorage.getItem('visited') + 1);
}
}
Right now I have a click button (or a "like" button that's an image heart called .download png) that only displays the click button result number counter when you click on it. I'm trying to get the button to display the result all the time, not just when you click on it, but still up the counter by one when clicked on. Here's the code I have so far in the header:
<script>
function clickCounter() {
if(typeof(Storage) !== "undefined") {
if (localStorage.firstButtonCount) {
localStorage.firstButtonCount = Number(localStorage.firstButtonCount)+1;
} else {
localStorage.firstButtonCount = 1;
}
document.getElementById("result").innerHTML = localStorage.firstButtonCount;
} else {
document.getElementById("result").innerHTML = "Sorry, your browser does not support web storage...";
}
}
</script>
And then the body code:
<p>
<button type="button" onclick="clickCounter()">
<div class="number" id="result"></div>
<img src="download.png" width="50px" height="auto class="clickCounter()" type="button alt="Like"/>
</button>
</p>
I'm not sure what I'm doing wrong but if anyone could show me how to display the result at all times that would be awesome!
Please note :
To get a value in localStorage , you use the method getItem.
To add a value in localStorage , you use the method setItem.
Refer to this article for more https://www.taniarascia.com/how-to-use-local-storage-with-javascript/
Replace your code with this one below :
<!DOCTYPE html>
<html lang="pt-br">
<meta charset="utf-8" />
<head>
<title>Vote</title>
</head>
<body>
<p>
<button type="button" onclick="clickCounter()">
<div class="number" id="result"></div>
<img src="https://cdn4.iconfinder.com/data/icons/like-18/32/459-01-512.png" width="50px" height="auto" type="button" alt="Like" />
</button>
</p>
<script type="text/javascript">
var resultElement = document.getElementById('result');
function updateResult() {
resultElement.innerText = parseInt(localStorage.getItem('firstButtonCount')) || 0;;
}
function vote() {
// body...
newCount = parseInt(localStorage.getItem('firstButtonCount')) + 1 || 0 + 1;
localStorage.setItem('firstButtonCount', newCount);
}
function clickCounter() {
if (typeof(Storage) !== "undefined") {
/*
to get a value in localStorage , you use the method getItem
to add a value in localStorage , you use the method setItem
*/
vote();
updateResult();
} else {
document.getElementById("result").innerHTML = "Sorry, your browser does not support web storage...";
}
}
updateResult();
</script>
</body>
</html>
I have made a snippet example for you, beacause of security violations I can't use the local storage feature, but you can enable it on your local development framework and discard the global counter.
var _globalCounter = 0;
document.getElementById("result").innerHTML = _globalCounter;
function clickCounter()
{
_globalCounter++;
document.getElementById("result").innerHTML = _globalCounter;
// This don't work on snippet because security violation,
// but it should work on you local development framework.
/*
if (typeof(Storage) === "undefined")
{
alert("Browser don't support local storage");
return;
}
var count = Number(localStorage.getItem("firstButtonCount"));
if (count && count > 0)
{
count++;
localStorage.setItem("firstButtonCount", count);
}
else
{
localStorage.setItem("firstButtonCount", 1);
}
document.getElementById("result").innerHTML = localStorage.getItem("firstButtonCount");
*/
}
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.4.1/css/all.css" integrity="sha384-5sAR7xN1Nv6T6+dT2mhtzEpVJvfS3NScPQTrOxhwjIuvcA67KV2R5Jz6kr4abQsz" crossorigin="anonymous">
<button type="button" onclick="clickCounter()">
<i class="far fa-2x fa-thumbs-up"></i>
<spam class="number" id="result"></spam>
</button>
I have found the below code to check the count of times the button has been clicked. However, I would like the button to redirect to an URL once it is clicked and update the click count.
<html>
<head>
<title>Increment count when button is clicked</title>
</head>
<body>
<input type="button" value="Count" id="countButton" />
<p>The button was pressed <span id="displayCount">0</span> times.</p>
<script type="text/javascript">
var count = 0;
var button = document.getElementById("countButton");
var display = document.getElementById("displayCount");
button.onclick = function(){
count++;
display.innerHTML = count;
}
</script>
</body>
</html>
button.onclick = function(){
count++;
display.innerHTML = count;
window.location = "http://jonathanmh.com";
}
This would do the trick, but nobody would ever see the number, because it simply goes away, after the user is redirected to another page. If you want to save the number for other users to see, you need to save it on the server and preferably in a database.
To achieve that you need to store click count in cookie or localStorage (or anywhere else where your data persists):
var button = document.getElementById("countButton");
var display = document.getElementById("displayCount");
button.onclick = function(){
if (isNaN(localStorage.yourCounter))
localStorage.yourCounter = 0;
localStorage.yourCounter++;
display.innerHTML = localStorage.yourCounter;
window.location = 'http://jsfiddle.net/'
}