1

I have some problem with the stateless nature of .NET MVC framework.

I have some HTML like

<ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
    <li>6</li>
    <li>7</li>
    <li>8</li>
    <li>9</li>
</ul>
<button id="btnShowMore">Show More</button>
<a href="www.google.com">Google</a>

and my javascript goes like

var maxDisplay = 5;
var unit = 5;
$("li").slice(maxDisplay).hide();
if ($("li").length <= maxDisplay) $('#btnShowMore').hide();
$('#btnShowMore').click(function () {
    maxDisplay += unit;
    $("li").slice(0, maxDisplay - 1).show();
    if ($("li").length <= maxDisplay) $('#btnShowMore').hide();
});

Now if I expand my list, navigate to google, and click back button in my browser, the list would forget what I did and shows only the first 5 list item, which is not what I want.

I thought of some options:

  1. cookie. not quite what I want because there are lots of pages like this, and I would need cookie for each of them

  2. manipulate url a bit, like taking advantage of window.location.hash. also not good, because that would be another page

Is there some conventional way to do this?

Thanks in advance


UPDATE:

seems like no more solutions coming out. I'd definitely prefer localStorage over cookie as there's no need to transfer this variable between client and server, but there needs a check whether the page is first load (clear cached variable and show 5 items) or load from navigate back(read cache and show cached number of items).

maybe I should go with hash...

5
  • 3
    Why is the hash not good? It's a great way to save state. Commented Feb 11, 2013 at 21:42
  • 2
    HTML itself is stateless, not .NET mvc in particular. When you press "back" in your browser, generally any content is re-requested, and re-displayed. As Ron said, you can always save state in your hashtag, which will create a "new" url, and enter it into the brower's history. On page load you would check if your hash is a certain value, and execute an appropriate script Commented Feb 11, 2013 at 21:43
  • 1
    Then you have a problem with HTTP itself... Commented Feb 11, 2013 at 21:46
  • @RonGilchrist I might be wrong here, but reason I don't like hash is it leaves literally a same page in history. say I'm navigate from urlA to urlB, I expand list, I'm at urlB#expanded. then I click back, I'm at urlB, not urlA. not desirable. Commented Feb 11, 2013 at 21:55
  • Try this JavaScript Session Variables library (thomasfrank.se/sessionvars.html) , which basically stores the data in windows object. This also works with older browsers. Commented Feb 11, 2013 at 21:58

1 Answer 1

3

You could always use localStorage to persist your application state. And have your script adapted so that it reads and writes to it directly instead.

Here are a couple of functions I commonly use to read and write from the localStorage

function setStorageItem(key, value) {
    var localStorage = window.localStorage;
    if (localStorage) {
        try {
            localStorage.setItem(key, window.JSON.stringify(value));
        } catch (e) {
        }
    }
    return !!localStorage;
}

function getStorageItem(key, defaultValue) {
    var localStorage = window.localStorage;
    if (localStorage) {
        var value = localStorage.getItem(key);
        if (value) {
            return $.parseJSON(value);
        }
    }
    return defaultValue || undefined;
}

Your code would be:

var maxDisplay = getStorageItem('maxDisplay', 5),
    unit = 5,
    more = $('#btnShowMore');

$("li").slice(maxDisplay).hide();

if ($("li").length <= maxDisplay){
    more.hide();
}

more.click(function () {
    maxDisplay += unit;

    setStorageItem('maxDisplay', maxDisplay); // remember it.

    $("li").slice(0, maxDisplay - 1).show();

    if ($("li").length <= maxDisplay){
        more.hide();
    }
});

If localStorage isn't working, your code will work the same, and if it is, it'll remember the maxDisplay property.

Update

In case you insist on using cookies:

function setCookie(key, value, expires) {
    var defaults = {
        path: '/',
        expires: 1000 * 60 * 60 * 6 * 24 * 30 // 6 months
    };
    var date = new Date();
    var offset = expires || defaults.expires;
    date.setTime(date.getTime() + offset);
    var json = window.JSON.stringify(value);
    var cookie = '{0}={1}; expires={2}; path={3}'.format(key, json, date.toGMTString(), defaults.path);
    document.cookie = cookie;
}

function getCookie(key, defaultValue) {
    var identifier = '{0}='.format(key);
    var cookies = document.cookie.split(';');
    for (var i = 0; i < cookies.length; i++) {
        var cookie = cookies[i];
        while (cookie.charAt(0) == ' ') {
            cookie = cookie.substring(1, cookie.length);
        }
        if (cookie.indexOf(identifier) == 0) {
            var value = cookie.substring(identifier.length, cookie.length);
            return $.parseJSON(value);
        }
    }
    return defaultValue;
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.