Using Local Storage to set a class for user preference - javascript

Please see "Latest update" below - Niel S has found a local storage solution for the VIEW MODE part of this question - but I still need to find a solution to get local storage to work for the SORT BY function.
My question started off like:
Please take a look at my fiddle
As you can see:
1) SORT BY: I've got the option of sorting the child elements either by price or pax.
2) VIEW MODE: The child elements by default are viewed as a 3 column layout (Default View) ... and I've given the user the option of switching the view to a 1 column layout (Alt View) if they prefer.
Great, that all works 100% fine however my problem is that these choices or preferences can't be saved or carried throughout their entire session surfing my website. In other words, if the user decides to display the listings in:
A) Price from lowest to highest
B) Alt View
... and then click on page 2 (where there are more of these listings), the layout and order will all go back to normal thus making the user have to re-click on the preferences they had chosen before on the first page - which means that this facility is pretty stupid (if it cannot remember).
So I know local storage is the solution however I am battling to implement it with no success and that's probably because I am very new to it.
I've got other scripts that are using local storage and I am trying to copy what they did and try apply it to this.
Like for example, my attempt for the VIEW MODE user option was adding:
localStorage.setItem("viewmode", "alt");
So to complete my method, the code would look like this:
jQuery(document).ready(function() {
$('.order a.layout').on('click', function(e){
e.preventDefault();
if($(this).hasClass('active')) {
// do nothing if the clicked link is already active
return;
}
$('.order a.layout').removeClass('active');
$(this).addClass('active');
var clickid = $(this).attr('id');
$('.listings').fadeOut(240, function(){
if(clickid == 'thumbnails-list') {
$(this).addClass('alt');
localStorage.setItem("viewmode", "alt");
} else {
$(this).removeClass('alt');
}
$('.listings').fadeIn(200);
});
});
});
Which doesn't work.
That's just for the VIEW MODE part ... now setting localstorage for the SORT BY part seems a bit daunting / very higher grade and I've attempted a few feeble attempts but I know I'm not doing it right.
Is there a simple solution to apply local storage to both preference options?
I'd really appreciate some help / guidance and I can imagine this would be a great solution for others looking to do the same with their project.
UPDATE:
I've broken down the script to tackle just the VIEW MODE part of it all.
See this fiddle and the following javascript:
jQuery(document).ready(function() {
$('.order a.layout').on('click', function(e){
e.preventDefault();
if($(this).hasClass('active')) {
// do nothing if the clicked link is already active
return;
}
$('.order a.layout').removeClass('active');
$(this).addClass('active');
var clickid = $(this).attr('id');
$('.listings').fadeOut(240, function(){
if(clickid == 'thumbnails-list') {
$(this).addClass('alt');
localStorage.setItem("viewmode", "alt");
}
else {
$(this).removeClass('alt');
localStorage.setItem("viewmode", "default");
}
$('.listings').fadeIn(200);
});
});
});
Notice in the javascript above, I've created the setItem's:
if(clickid == 'thumbnails-list') {
$(this).addClass('alt');
localStorage.setItem("viewmode", "alt");
}
else {
$(this).removeClass('alt');
localStorage.setItem("viewmode", "default");
}
When I go on Chrome resources > local storage and test to see if these setItems are working, they are indeed.
My problem is that I am battling to do the getItem part which is doing my head in!
LATEST UPDATE (part 2):
Neil S has provided a great and simple solution for the VIEW MODE state! Works like a charm!
I am now trying to work on getting the SORT BY price or pax (see original / very first fiddle) to also use local storage however this is proving to be much harder than I thought:
Please see this fiddle of my attempt to use local storage for the sort by PRICE.
What makes this more complicated is the fact that the sort by can either go in ascending or descending order.
As you can see in the fiddle, I've done this (and I've done many other attempts but this looks most logical):
if (localStorage.getItem('sortby') == 'price') {
$(function() {
ratingAscending = true;
var sorted = $('.listings').sort(function(a,b) {
return (priceAscending ==
(convertToNumber($(a).find('span').html()) <
convertToNumber($(b).find('span').html()))) ? 1 : -1;
});
priceAscending = !priceAscending;
$('.results').append(sorted);
})
}
Nothing special here ... all I've done is replaced:
$('.container').on('click','.sortbyprice',function(){
with
$(function() {
... because the click function is obsolete now that it's a 'memory' thing.
Surely that should work?
I've tried this:
if (localStorage.getItem("sortby") == "price") {
// this is where the answer probably lies
$('.container .results').append(sorted);
}
and no success.
I just need to have local storage remember that the user had chose the preference SORT BY - price ... so that when the user clicks on page 2 ... the listings on that page are also sorted by price.

You don't have any code to load the localstorage value and apply the class to listings.
I've updated your fiddle: https://jsfiddle.net/n2o70xgg/2/
This is what I added:
if (localStorage.getItem('viewmode') == 'alt') {
$('.listings').addClass('alt');
}

Related

SessionStorage Navigation

Greets, so I I'm trying to learn jquery/javascript storage and ran into an issue where I am building a navigation that should remember and place you where you last were if you refresh the page (that's why i use sessionStorage rather then localStorage).
But I can't seem to change the sessionStorage variable to the new location, nor figure out a functional way to get the user back on refreshing the page.
This is what I currently have.
$(function() {
sessionStorage.setItem('position', '.first');
var location = sessionStorage.getItem('position');
$('li', this).click(function() {
cls = $(this).text();
if('.' + cls != location) {
$(location).slideToggle(400);
$('.' + cls).delay(400).slideToggle(400);
sessionStorage.setItem('position', '.' + cls)
console.log(location)
};
});
});
https://jsfiddle.net/Unkn0wn96/ndj9sqpe/
The code works in an very odd way, rather then how it's intended, including never changing the value when I console.log(location).
I made some further testing on this and found a 'more' working way in the was that the sessionStorage does change to something, yet it not being usefull.
https://jsfiddle.net/Unkn0wn96/nkbtykkr/
but yet, they elements don't toggle as they should, including that when I console log sessionStorage.position it returns NaN. Also for some odd reason I can't store sessionStorage.position within a variable, it just refuses to change its value. I have no clue why this is happening.
So I was finally able to solve my issue with sessionStorage, since there was not much of help I'd assume the information regarding the case was limited and so wish to share my solution. All thought it does not work fully as intended it does execute it's main function.
$(function() {
$('button').on('click', function() {
var msg = '.'+$(this).text();
localStorage.setItem('color', 'blue') //Default (does not matter since the if statement does not register)
if(msg != '.' + localStorage.color) { // DOES NOT REGISTER
if(localStorage.length > 0) {
localStorage.removeItem('color')
console.log('localStorage.length : ' + localStorage.length)
};
localStorage.setItem('color', msg)
console.log(localStorage.color)
} else {
console.log('cancelled')
}
});
});
https://jsfiddle.net/mdqjoz69/4/
So what I finally was able to achieve was to make a localStorage key change it's value regarding of what button you press.
What I failed to achieve was being able to check the stored data to not execute whenever you store something that have already been stored. There might be a work around for this. But since the code serves its main purpose I'll let it slide.

Easiest way of remembering user locale selection in HTML

I've been working on a website of mine for about a week now. I'm very good with HTML and CSS, but I'm still trying to wrap my head around Javascript, JQuery and PHP.
Basically, what I'm trying to do is create a way if remembering the users language and locale based on their selection on a language selection page. What I'd like (if possible), is for a user to select their flag on a /locale page and make that change the url of the homepage (ie. mysite.com/en-us). I'm going to be translating my website content via static pages, not active translation.
This only has to work for the homepage, not subsequent pages, however it would be awesome if it did work for pages under different directories too. You can view a live example of my newly constructed website here.
I'd prefer Javascript or JQuery, but honestly - when someone else is doing the hard part, I don't really have the right to be picky.
Thank everyone very much in advance for any assistance.
There's two ways to achieve this: Cookies or localStorage. The easiest one is localStorage:
Here's two plain Javascript functions. The first runs onbodyload and check if the previous language choice (stored in the localStorage) was Spanish. If not (or blank), the welcome appears in English.
When you click a button, it runs the second function which changes the welcome language plus stores the choice in the localStorage.
HTML
<button onclick="language('en')">english</button>
<button onclick="language('spa')">spanish</button>
<h1><span id=welcome>text</span></h1>
JAVASCRIPT
document.getElementsByTagName("body")[0].onload=function(){session()};
function session() {
var result = localStorage.getItem("session");
if (result === 'spa') {
document.getElementById("welcome").innerHTML = "Hola!";
} else {
document.getElementById("welcome").innerHTML = "Hello!";
}
}
function language(key) {
if (key === 'en') {
document.getElementById("welcome").innerHTML = "Hello!";
localStorage.setItem("session", "en");
} else if (key === 'spa') {
document.getElementById("welcome").innerHTML = "Hola!";
localStorage.setItem("session", "spa");
}
}
Codepen DEMO

Set user preference using local storage [duplicate]

Please see "Latest update" below - Niel S has found a local storage solution for the VIEW MODE part of this question - but I still need to find a solution to get local storage to work for the SORT BY function.
My question started off like:
Please take a look at my fiddle
As you can see:
1) SORT BY: I've got the option of sorting the child elements either by price or pax.
2) VIEW MODE: The child elements by default are viewed as a 3 column layout (Default View) ... and I've given the user the option of switching the view to a 1 column layout (Alt View) if they prefer.
Great, that all works 100% fine however my problem is that these choices or preferences can't be saved or carried throughout their entire session surfing my website. In other words, if the user decides to display the listings in:
A) Price from lowest to highest
B) Alt View
... and then click on page 2 (where there are more of these listings), the layout and order will all go back to normal thus making the user have to re-click on the preferences they had chosen before on the first page - which means that this facility is pretty stupid (if it cannot remember).
So I know local storage is the solution however I am battling to implement it with no success and that's probably because I am very new to it.
I've got other scripts that are using local storage and I am trying to copy what they did and try apply it to this.
Like for example, my attempt for the VIEW MODE user option was adding:
localStorage.setItem("viewmode", "alt");
So to complete my method, the code would look like this:
jQuery(document).ready(function() {
$('.order a.layout').on('click', function(e){
e.preventDefault();
if($(this).hasClass('active')) {
// do nothing if the clicked link is already active
return;
}
$('.order a.layout').removeClass('active');
$(this).addClass('active');
var clickid = $(this).attr('id');
$('.listings').fadeOut(240, function(){
if(clickid == 'thumbnails-list') {
$(this).addClass('alt');
localStorage.setItem("viewmode", "alt");
} else {
$(this).removeClass('alt');
}
$('.listings').fadeIn(200);
});
});
});
Which doesn't work.
That's just for the VIEW MODE part ... now setting localstorage for the SORT BY part seems a bit daunting / very higher grade and I've attempted a few feeble attempts but I know I'm not doing it right.
Is there a simple solution to apply local storage to both preference options?
I'd really appreciate some help / guidance and I can imagine this would be a great solution for others looking to do the same with their project.
UPDATE:
I've broken down the script to tackle just the VIEW MODE part of it all.
See this fiddle and the following javascript:
jQuery(document).ready(function() {
$('.order a.layout').on('click', function(e){
e.preventDefault();
if($(this).hasClass('active')) {
// do nothing if the clicked link is already active
return;
}
$('.order a.layout').removeClass('active');
$(this).addClass('active');
var clickid = $(this).attr('id');
$('.listings').fadeOut(240, function(){
if(clickid == 'thumbnails-list') {
$(this).addClass('alt');
localStorage.setItem("viewmode", "alt");
}
else {
$(this).removeClass('alt');
localStorage.setItem("viewmode", "default");
}
$('.listings').fadeIn(200);
});
});
});
Notice in the javascript above, I've created the setItem's:
if(clickid == 'thumbnails-list') {
$(this).addClass('alt');
localStorage.setItem("viewmode", "alt");
}
else {
$(this).removeClass('alt');
localStorage.setItem("viewmode", "default");
}
When I go on Chrome resources > local storage and test to see if these setItems are working, they are indeed.
My problem is that I am battling to do the getItem part which is doing my head in!
LATEST UPDATE (part 2):
Neil S has provided a great and simple solution for the VIEW MODE state! Works like a charm!
I am now trying to work on getting the SORT BY price or pax (see original / very first fiddle) to also use local storage however this is proving to be much harder than I thought:
Please see this fiddle of my attempt to use local storage for the sort by PRICE.
What makes this more complicated is the fact that the sort by can either go in ascending or descending order.
As you can see in the fiddle, I've done this (and I've done many other attempts but this looks most logical):
if (localStorage.getItem('sortby') == 'price') {
$(function() {
ratingAscending = true;
var sorted = $('.listings').sort(function(a,b) {
return (priceAscending ==
(convertToNumber($(a).find('span').html()) <
convertToNumber($(b).find('span').html()))) ? 1 : -1;
});
priceAscending = !priceAscending;
$('.results').append(sorted);
})
}
Nothing special here ... all I've done is replaced:
$('.container').on('click','.sortbyprice',function(){
with
$(function() {
... because the click function is obsolete now that it's a 'memory' thing.
Surely that should work?
I've tried this:
if (localStorage.getItem("sortby") == "price") {
// this is where the answer probably lies
$('.container .results').append(sorted);
}
and no success.
I just need to have local storage remember that the user had chose the preference SORT BY - price ... so that when the user clicks on page 2 ... the listings on that page are also sorted by price.
You don't have any code to load the localstorage value and apply the class to listings.
I've updated your fiddle: https://jsfiddle.net/n2o70xgg/2/
This is what I added:
if (localStorage.getItem('viewmode') == 'alt') {
$('.listings').addClass('alt');
}

Input objects not shared across html files

I'm using jsPsych in behavioral research. The developer of that library is very helpful, yet also busy, so I wanted to try and see if the stack overflow community could help me out with a more general js problem :)
In the instance where I'm getting issues, I push objects into an empty array to update the site after input. In this particular case, I use a script that allows me to use external html pages. My problem is, that, while this function here works in order to correctly display a java prompt when assessing a checkbox
var check_consent = function(elem) {
if ($('#consent_checkbox').is(':checked')) {
return true;
}
else {
alert("If you wish to participate, you must check the box next to the statement 'I agree to participate in this study.'");
return false;
}
return false;
};
this here doesn't work in order to assess a text box
var inp = $("#ctry_box").val();
var check_sociodemo = function(elem) {
if ($.trim(inp).length > 0) {
return true;
}
else {
alert("Please fill out the form.");
return false;
}
return false;
};
More specifically, the prompt does actually work, but no matter what you type into "ctry_box", you can't continue the page and the prompt is shown no matter what the input.
Further, the developer set "data" as a object property designed to store data in accordance with individual variable choices. Regarding the same html files, I would like to gather the input from another text box like this
var sociodemo_block = {
type: 'html',
pages: [{url: "text/sociodemo.html", cont_btn: "end", check_fn: check_sociodemo}],
data: [{age: age_box.value}],
force_refresh: true
If I run this, the console tells me that age_box is not defined. Yet again, #consent_checkbox did work. Am I missing something fundamentally here or are the variables simply not shared across the files properly?
I'm very thankful for any help!

Dynamically loading a database based on user text input

I have an autocomplete widget which needs to return options from a database of objects.
On doing so, once the user selects an item the widget will populate other hidden textfields with values from the particular object they chose. - All of this works and has been used on previous projects
However this particular database is far too big (44k+ objects, filesize is several mb and has taken far too long to load in practice) so we've tried various ways of splitting it up. So far the best has been by first letter of the object label.
As a result I'm trying to create a function which tracks the users input into a textfield and returns the first letter. This is then used to AJAX a file of that name (e.g. a.js).
That said I've never had much luck trying to track user input at this level and normally find that it takes a couple keystrokes for everything to get working when I'm trying to get it done on the first keystroke. Does anyone have any advice on a better way of going about this objective? Or why the process doesn't work straight away?
Here is my current non-working code to track the user input - it's used on page load:
function startupp(){
console.log("starting");
$("#_Q0_Q0_Q0").on("keyup", function(){
console.log("further starting!");
if($("#_Q0_Q0_Q0").val().length == 1){
console.log("more starting");
countryChange(($("#_Q0_Q0_Q0").val()[0]).toUpperCase());
}
else{
console.log("over or under");
}
});
}
And an example of the data (dummy values):
tags=[
{
label:"label",
code:"1",
refnum:"555555",
la:"888",
DCSF:"4444",
type:"Not applicable",
status:"Open",
UR:"1",
gRegion:"North West"
},
....
];
edit: fixes applied:
Changed startupp from .change(function) to .on("keyup", function) - keydown could also be used, this is personal preference for me.
Changed the autocomplete settings to have minLength: 4, - as the data starts loading from the first letter this gives it the few extra split ms to load the data before offering options and also cuts down how much data needs to be shown (helps for a couple of specific instances).
Changed how the source is gathered by changing the autocomplete setting to the following:
source: function(request, response) {
var results = $.ui.autocomplete.filter(tags, request.term);
response(results.slice(0, 20));
},
where tags is the array with the data.
all seems to be working now.
You should bind to keydown event:
function startupp(){
console.log("starting");
$("#_Q0_Q0_Q0").keydown(function(){
console.log("further starting!");
if($(this).length() == 1){
console.log("more starting");
countryChange(($(this).val()[0]).toUpperCase());
}
else{
console.log("over or under");
}
});
}

Categories