Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Saving user's selection when refreshing the page

I currently have a page that displays data for different teams.

I have some data that the user can click on to make it an "on" or "off" state, showing a different icon for each. It's basically like a checklist, just without the physical checkboxes.

I would like to remember which of the "checkboxes" have been ticked, even after the user refreshes the page or closes the browser and returns later.

I have heard that localStorage is a good option, but I'm not sure how to use it in a situation like mine.

Currently I have this code:

team1 = {
    "information1": {
        "name": "tom",
        "age": "34"
    },
    "information2": {
        "name": "bob",
        "age": "20"
    },
};

team2 = {
    "information1": {
        "name": "betsy",
        "age": "27"
    },
    "information2": {
        "name": "brian",
        "age": "10"
    },
};

$(document).ready(function() {

    $("#displayObject1").on("click", function() {
        switchData(team1);
    });

    $("#displayObject2").on("click", function() {
        switchData(team2);
    });
    $("#table").on("click", ".on", function() {
        $(this).removeClass("on");
        $(this).addClass("off");
    });
    $("#table").on("click", ".off", function() {
        $(this).addClass("on");
        $(this).removeClass("off");
    });
}); 


function switchData(object) {
    $("#table").contents("div").remove();
    if (!('rows' in object)) {
        var rows = [];
        Object.keys(object).forEach(function (key) {
            if (key != 'rows') {
                rows.push($('<div class="row on">' + object[key].name + '</div>'));
            }
        });
        object.rows = rows;
    }
    object.rows.forEach(function (row) {
        $('#table').append(row);
    });
}

This makes rows to represent a team. The rows are retained with their color highlighting when the user looks at different teams during a browser session.

This is my HTML:

<div id="displayObject1">
    <span>Display object 1</span>
</div>
<div><hr></div>
<div id="displayObject2">
    <span>Display object 2</span>
</div>
<div id="table">
</div>

And some CSS to show which list items are "on" and "off".

.on {
  background-color: green;
}
.off {
  background-color: red;
}

How can the page remember the color highlighting?

like image 270
follmer Avatar asked Sep 26 '22 20:09

follmer


1 Answers

If you want to use local storage to make the state of the team listings persist across browser sessions, you have to maintain a logical representation of the state and save it as a string whenever the state changes.

JSON.stringify lets you encode a JavaScript object in a JSON string. For example, you can call a function like the following whenever you modify a global object named pageState:

function savePageState() {
  localStorage.setItem('pageState', JSON.stringify(pageState));
}

To retrieve the page state on page load, you can do something like this:

pageState = JSON.parse(localStorage.getItem('pageState'));
if (pageState === null) {
  pageState = {
    teams: teams
  };
  savePageState();
} else {
  teams = pageState.teams;
}

If pageState wasn't saved in a previous session, it is now created and saved to local storage. Otherwise, we consult pageState for data that we can use to restore the previous appearance of the team listings.

This code sample works on the assumption that the global object teams contains information relevant to the page state. You can add further properties to the page-state object to store more information. For example, to remember which team is currently displayed, you could do:

pageState.showTeam = teamName;

Then you can consult pageState.showTeam when you're initializing the page contents, perhaps like this:

if (teamName == pageState.showTeam) {
  showTeam(teamName);
  $(label).addClass('selected');
}

I have made a page that demonstrates this approach. I can't include it in my answer as a snippet because localStorage is sandboxed, but you can access the page here:

http://michaellaszlo.com/so/click-rows/

I've reorganized your team data to enable dynamic page initialization. Now each team object contains an array of person objects.

When the user clicks on a team member's name, the CSS class selected is toggled on the HTML element and the corresponding person object is updated by toggling its selected property:

function memberClick() {
  $(this).toggleClass('selected');
  this.person.selected = (this.person.selected ? false : true);
  savePageState();
};

The showTeam function checks a person's selected property when it's building its HTML representation, and adds the CSS class selected if appropriate. This is what makes it possible to restore the visual appearance of the page from the last session.

like image 67
Michael Laszlo Avatar answered Oct 04 '22 21:10

Michael Laszlo