11

Currently as I'm displaying different elements with jQuery, I'm re-creating them from scratch and adding them to the page.

I've come to a point where I want the user to be able to check a box on one element, then click a button to see some different information, then be able to switch back and see the earlier box still checked.

Since I'm currently making new elements each time the user switches, this isn't possible in a straightforward manner.

I'm wondering whether it's better to redraw the elements or to modify the CSS display property.

I could see why it would be helpful to hide elements but I'm not sure it's necessary to keep ~150 elements on the screen and just have them not displayed.

This is what I have so far:

https://jsfiddle.net/W4Km8/7767/

This code changes the color of information rows:

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

The problem is that if you look at another set of information rows and then come back, the row colors are reset.

Michael Laszlo
  • 12,009
  • 2
  • 29
  • 47
follmer
  • 1,050
  • 3
  • 14
  • 31
  • If the data is being retrieved from the backend and you are dealing with the visibility of the elements then end user will never get the updated data until he refreshes the page. Even though the data is static, it will be painful to maintain the track of the elements properties or visibility. A nice little example of what you are trying to achieve would help! – Rayon Dec 24 '15 at 07:02
  • `display : none / display : block` could be one solution. If each element belong to one object from the array then you can store the updated properties of the element as a keys f the objects and every time you are creating them in loop, you can make use of those properties to create the element. – Rayon Dec 24 '15 at 07:56

1 Answers1

1

I recommend that you generate the information rows on demand, i.e., when the user clicks on a label for the first time. That way, you don't waste resources making HTML elements when the page loads. Once the rows have been created for a particular item, you can swap them out of the display container and they'll retain the highlighting they've acquired from user clicks.

I have rewritten your switchData function so that it checks for a rows property in object. If it doesn't exist, the HTML rows are created and pushed into an array, which is then added as a new property of object. On subsequent calls to switchData, we can use object.rows immediately.

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);
    });
}

The following snippet demonstrates this approach. Apart from the modified switchData function and a few styling changes, everything is the same as in your fiddle.

var team1 = {
 "information1": {
  "name": "Giuseppe",
  "age": "34"
 },
 "information2": {
  "name": "Rodolfo",
  "age": "20"
 },
};

var team2 = {
 "information1": {
  "name": "Alice",
  "age": "27"
 },
 "information2": {
  "name": "Jane",
  "age": "40"
 },
};

$(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);
    });
}
body {
  font-family: sans-serif;
}
div, span {
  cursor: pointer;
}
#table {
  margin-top: 5px;
}
.row {
  padding: 5px 10px;
  border-top: 1px solid #fff;
  color: #fff;
}
.on {
  background-color: green;
}
.off {
  background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="displayObject1">
  <span class="clickable">Display object 1</span>
</div>
<div>
  <hr>
</div>
<div id="displayObject2">
  <span class="clickable">Display object 2</span>
</div>
<div id="table">
</div>
Michael Laszlo
  • 12,009
  • 2
  • 29
  • 47
  • Awesome, I will check it out when I get a better chance, and will accept your answer if it works. But this looks very good, thank you! – follmer Dec 24 '15 at 20:28
  • Sorry for another question, but would it be possible to incorporate this to use cookies to remember the options on a page refresh? I know of cookies but have never used them before and don't know how much work it'd take. – follmer Dec 24 '15 at 20:40
  • In theory you could use a cookie to store the page state, but cookies are really meant for communication with the server. The idea is that the cookie stores a session ID, which the server uses as a key to look up the session data in a database. A simpler approach is to store the page state in the browser's [local storage](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage). I can help you with that, but it's a new topic and it would be better answered in a new question. If you're happy with my answer to the current question, please upvote and accept my answer. – Michael Laszlo Dec 24 '15 at 23:27
  • Great! Accepted and upvoted your answer. Would you might taking me through how I would store the page state? I would really appreciate it! Also, would saving the page state be unique to every user? That is what I need. – follmer Dec 25 '15 at 00:03
  • Whenever the user modifies the page, you have to encode the page state in a string and call [`localStorage.setItem`](https://developer.mozilla.org/en-US/docs/Web/API/Storage/setItem) to save the string. When the page loads, you call [`localStorage.getItem`](https://developer.mozilla.org/en-US/docs/Web/API/Storage/getItem) and decode the page state from the string. There isn't a fixed way to encode page state. I can show you a possible approach if you post a new question. And yes, the browser's `localStorage` data is unique to the user. It's local. – Michael Laszlo Dec 25 '15 at 00:28
  • Perfect. I'll write up a new question and link you to it when it's up. – follmer Dec 25 '15 at 00:41
  • The new question: http://stackoverflow.com/questions/34459175/saving-users-selection-when-refreshing-the-page – follmer Dec 25 '15 at 00:54