Getting and Setting localStorage ( Simple Score example )

I had a request to show an example of localStorage.

This example will show how to set and get a simple score that is persistent on window/browser close and open.

The Head file.

We can have code which is placed in the head file run straight away before the page loads.

Therefore it is an ideal place for any code that will get the stored score if it exists from the localStorage.

What we need to do in the Head.

First we need to check if the storage item exists using the getItem(storedItemName) function
We will be looking for a stored item named theScore.

If the storage item theScore exists, we can use it’s data to set the value of a global variable.
We will call the global variable window.score.

(In this example the data in the theScore item will be stored as a string. )

If the storage item theScore does not exist, we can use it’s none existence to set window.score value to 0.

The head’s get localStorage code in the head:

    if(localStorage.getItem('theScore')) {
     window.score =   localStorage.getItem("theScore"); //string 
     } else {
     window.score = 0;

Now we have something in the global variable window.score, we need to update the UI.

Updating the UI

Updating the UI and how and when it is done is up to you. But in this example I want to do it a soon as the page has loaded.

I have chosen to do this with a javascript (named setScoreUI ) that runs from on Scene Load. ( go to Scene inspector, click the + for the Scene Load actions and select run javascript and new function )

I am also going to use the same JS function which i have called setScoreUI to update the UI when a new score happens.

For simplicity I am using a Button to add to the score, the logic of adding to the score and UI in this example reflects that.

( Adding to your score on a real page will most likely involve a different mechanism and you will have to work out your own logic of how to add to the score. )

The Button will call the setScoreUI function from it’s on Mouse Click actions.

When the setScoreUI code runs

When the code runs from the Head we do not want to add to the score, we only want to set the UI to show the current window.score we set in there.

To make sure we are not scoring by mistake when the code runs from the Head , we simply check which element called the setScoreUI function.

The call from the Head is not an element object so the element argument in the setScoreUI function will be null.

So if the call came from the Head we bypass the score addition code and go straight to set the innerHTML of our score Element. (id scorePanel) to the current value of window.score

If the call came from the button element, we run the addition code.

Remember I said above that we will be storing the storage item theScore as a string, we do that in this case because that is simple what the innerHTML is.

We cannot add a string to a number and get a number, without first converting the window.score string value to a number.
There are a couple of ways we can do this. But we will use the JS Number() function to do it.

window.score = Number(window.score) + 1 ;  // Number() converts string  to number.

We than set the innerHTML of our score Element. (id scorePanel) to the new value of window.score .

The setScoreUI code:

var scorePanel = hypeDocument.getElementById('scorePanel');
	if (element ){
	window.score = Number(window.score) + 1 ; // Number() converts from  string  to number.
	scorePanel.innerHTML =  window.score;

Saving the score.

Saving the score would normally be done as soon as window.score has a new value.

You can do this in the same function but I have chosen to keep the save code separate from the UI changing code, because it makes it easier to adjust the UI code and the Save code without interfering with one or the other.
And keeps the example of saving to the localStorage item clean.

The save code is placed in a function named saveScore and is called right after the setScoreUI form the on Mouse Click actions for the score button

The * saveScore* code:

localStorage.setItem('theScore',  window.score);

Yep that is all it is.

We tell the localStorage to set the Item 'theScore’’'s value to the value of window.score.

In summery:

Your code to set a localStorage item is:

  localStorage.setItem(‘theScore’,  window.score);

Your code to get a localStorage item is:


Ever thing in between depends on what you want to do.

But there’s one more thing…

Removing the localStorage.

To remove our stored item from the localStorage we simply use


This will wipe the item and it will no longer exist.

You will need to update the window.score values and the UI.

We do this in a new function that in this example which is called from another button.

window.score = 0;
    	if(localStorage.getItem('theScore')) {
    	var scorePanel = hypeDocument.getElementById('scorePanel');
    scorePanel.innerHTML =  window.score;
    	 } (18.6 KB)


Thanks Mark, this is very helpful.

1 Like

Wow, thanks! just what I need.

1 Like

Hi, very good example, but is there anyway I can pass the Unique Id(in this case 'scorePanel') through the function as a parameter?

Since you have given the bare minimum info on your goal, indeed which function ?

I could just say YES.

But since I am in a good mood :smiley: , I will take a stab at what I think you may mean.

You have more than one panel and want to populate and retrieve the values for them without duplicating bundles of code.

Here are two examples.

The first is a very simple project that shows how to set and get more complex data in localStorage using JSON objects / Associated Arrays. (30.4 KB)

The second is an update to the above example with more than one panel. (17.7 KB)

Note the additional Attributes used with the buttons and class Names of he panels.

1 Like

Hi Mark, thank you for your answer and your good mood!
Alexandre question was really brief so I will try to detail it.

I have previously asked the forum about local storage and Jonathan's answer brought me to this thread.

We are making a questionnaire with written and multiple choice answers.
The answers have to be saved locally so the user may close it and complete it later.

It consists of 12 questions, some of them with subquestions.
Each question has either a few text fields or some lines with answers to be selected.
In the total there are around half a dozen text fields and 130 lines of answers.

Both the text fields and the lines are inside symbols.
The items to be saved are the written texts and the chosen lines status, defined by their timeline position.
If the timeline is at 0 the line is not selected and if it is at the end it is selected.
We need the functions to save and retrieve the texts and the timeline positions of the answers.

Can you help us with that?

Later on we will have to create a function that will copy all the answers to a summary but it is an issue for another thread.

Thank you very much! (852.4 KB)

1 Like

I have done this for scene 1 only.

There is a new function : setQ1() which sets up the localStorage.

We save the current scene, selected question ( we use the Timeline name stored in additional Attributes, see below )
Each Group Question element has been given an Addition Attribute key= question , value = question timeline name ( .i.e Q1 ), and textarea text.

The setQ1() function will run and store any new data when ;
on Scene load
on Scene unload,
The next/prev scene button is clicked ( just set on scene 1's next button in this example )
A Group Question (.i.e Questao11, Questao12 ) element is clicked.

The on Scene also has a on Scene javascript action to run the loadScene function.

This will populate the textAreas and run the correct timeline to show the last selected question.

Because the user may refresh/reload/ close the page I have added an on scene load javascript action which a function autoUpdate that try to auto save as they type in a textarea

The code is scene 1 centric but you should either be able to make it dynamic or create similar functions for each scene and save their data in the same localStorage array. (663.8 KB)


Thank you very much Mark!