SessionStorage Navigation - javascript

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.

Related

Google Tag Manager - Count amount of pageviews

I've made an event in Google Tag Manager, which triggers when a specific page is loaded.
The Event label is the value of my user defined variable SearchCounter with type: Custom JavaScript.
In 'SearchCounter' I have the following JS:
function(){
var counter;
if(localStorage.getItem("count_search") === null || localStorage.getItem("count_search") === 'undefined'){
localStorage.setItem("count_search", "1");
return localStorage.getItem("count_search");
}
else{
counter = parseInt(localStorage.getItem("count_search"));
counter = counter + 1;
localStorage.setItem("count_search", counter);
return localStorage.getItem("count_search");
}
return localStorage.getItem("count_search");
}
When I don't have the item in my local storage already, it still give's me 7 instead of 1. Then I'll press F5: count_search = 17, And again f5: 27. A CTRL-F5 gives me 37.
It should be 1, 2, 3, 4, 5 etcetera.
I hope someone can help me to implement a counter-alike function in Google Tag Manager, so I can send the amount of searches to GA, when a goal has been achieved. So, When someone clicks a specific button a would like to get the value of count_search, to send it to GA within an event.
Thanks very much.
First of all this metric is given by google analytics by default so i don't see why ur trying to store it somewhere else. If you dont want the avg that google uses you can just store a custom dimension at 'Session' level with the sessionID and those in a custom report open Sessions by pageviews. Here is info about it.
On the other hand, if you insist doing it your way i think even if this works it isn't the best approach you would get a much better result storing the counter in a custom dimension at 'Session' level. (It ll overwrite the value each time for a given session and you ll end up with the last one send)
Hope it helps.
What you need to do is changing the name of the parameter saved in the localStorage. I don't know why, but count_search does not work. I tested your setup and encountered the same weird effect where the count_search item is summing up to astronomical numbers. Using a different name like thisIsMyPageViewCounter works just fine though! Probably count_search is accessed by another object in the document or window and you managed to get a value out of it by chance.
If you want to add the page view count to an event, I do not see any other way than creating both a Custom HTML Tag to set the counter and a Custom JS Variable to return the count.
This is the Custom HTML Script to be added to each page view:
<script>
(function() {
if(localStorage.getItem("thisIsMyPageViewCounter") === null || localStorage.getItem("thisIsMyPageViewCounter") === 'undefined') {
localStorage.setItem("thisIsMyPageViewCounter", 1);
} else {
var counter = 0;
counter = parseInt(localStorage.getItem("thisIsMyPageViewCounter"));
counter = counter + 1;
localStorage.setItem("thisIsMyPageViewCounter", counter);
}
})();
</script>
This is the Custom JS Variable to be added as a value to the event:
function() {
pageviewCounter = parseInt(localStorage.getItem("thisIsMyPageViewCounter"));
return pageviewCounter;
}
I hope this helps!

How would one set the initial value of an editable div?

So, I've got a notepad extension for Google Chrome that syncs and displays stored notes from a user. Currently my problem is as follows.
When the extension is run for the first time after download, the word 'undefined' is displayed in the editable div (id = edit_notepad). I want it to just be blank instead of displaying anything. Obviously, I know its undefined because the user hasn't been able to add any text yet.
Picture of what's displayed on initial run:
From my content script, here are my chrome.storage get and set functions (which do work):
document.body.onload = function() {
chrome.storage.sync.get("edit_notepad", function(items) {
if (!chrome.runtime.error) {
console.log(items);
document.getElementById("edit_notepad").innerHTML = items.edit_notepad;
}
});
}
document.getElementById("edit_notepad").onkeyup = function() {
var d = document.getElementById("edit_notepad").innerHTML;
chrome.storage.sync.set({ "edit_notepad" : d }, function() {
if (chrome.runtime.error) {
console.log("Runtime error.");
}
});
}
I presume I'm going to need some sort of if statement, but after hours of playing around, I'm lost as to what exactly it'd contain. The issue I've kept running into is that whatever I set the initial value of edit_notepad to, it always reverts back to "undefined" even when a user has written some notes! e.g. "This is a notes test" would revert back to "undefined" when the notepad is closed and reopened.
Well, an easy way to do this would be to specify a default value in your chrome.storage.sync.get(). Doing so would apply the default value when the key does not exist in the storage. However, given that you are replacing any contents which might already exist, the better solution would be not to set the contents when you have no value, or an invalid value, stored. The only valid value will be a string. This will prevent you from overwriting any default value supplied by the webpage when you have no value stored. Thus, an if statement something like the following should work (alternately, you could test for !== 'undefined':
document.body.onload = function() {
chrome.storage.sync.get("edit_notepad", function(items) {
if (!chrome.runtime.error) {
console.log(items);
if(typeof items.edit_notepad === 'string') {
document.getElementById("edit_notepad").innerHTML = items.edit_notepad;
}
}
});
}
Note: Storing the contents of the editable <div> on every key will result in many users running into both the MAX_WRITE_OPERATIONS_PER_MINUTE and MAX_WRITE_OPERATIONS_PER_HOUR quotas. You will need to have some other criteria for writing to storage.sync. Perhaps you could temporarily store the value in storage.local and only to storage.sync every couple of minutes.

Using Local Storage to set a class for user preference

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

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

Variable not updating in script string, yet it updates

Very confused here.
I have a search box which reads a list of school names from my database. When I select a school, the id (from the db) gets put in a hidden textbox.
I also have a search box which reads a list of courses from my database. However, I made the query so that it only reads the courses from the selected school.
It does that, in theory.
I was planning to pass the school id, which I grab from the hidden box, to the search script which in turn passes it to my database query. However, the variable I put my school id in doesn't seem to be updating.. yet it does. Let me explain.
I come on the page. The school for my test account has id 1. The id number in my hidden box is indeed 1. I search for a school which I know has some courses assigned to it: the id number in the box changes to 3.
I have a JS variable called school_id which I declared outside of my $(document).ready. I assume that means it's global (that's what I got taught even though SO told me once it isn't really the correct way to do this. Still have to look into that). I wrote a function which updates this variable when the school search box loses focus:
$("#school").blur(function() {
school_id = $("#school_id").val();
});
A quick javascript:alert(school_id); in my browser bar also shows the updated variable: it is now 3 instead of 1.
Onto the search script part of my page (excerpt of the script):
script:"/profiel/search_richting?json=true&limit=6&id=" + school_id + "&"
As you can see, I pass the school_id variable to the script here. However, what seems to be happening is that it always passes '1', the default variable when the page loads. It simply ignores the updated variable. Does this string get parsed when the page loads? In other words, as soon as the page loads, does it actually say &id=1? That's the only idea I can come up with why it would always pass '1'.
Is there a way to make this variable update in my script string? Or what would be the best way to solve this? I'm probably missing out on something very simple here again, as usual. Thanks a lot.
EDIT
Updated per request. I added a function getTheString as was suggest and I use the value of this function to get the URL. Still doesn't work though, it still seems to be concatenating before I get a chance to update the var. HOWEVER, with this code, my ajax log says id:[object HTMLInputElement], instead of id:1. Not sure what that means.
<script type="text/javascript">
var school_id;
$(document).ready(function() {
$("#school").blur(function() {
school_id = $("#school_id").val();
});
// zoekfunctie
var scholen = {
script:"/profiel/search_school?json=true&limit=6&",
varname:"input",
json:true,
shownoresults:false,
maxresults:6,
callback: function (obj) { document.getElementById('school_id').value = obj.id; }
};
var as_json = new bsn.AutoSuggest('school', scholen);
var richtingen = {
script: getTheString(),
varname:"input",
json:true,
shownoresults:true,
maxresults:6
};
var as_json2 = new bsn.AutoSuggest('studierichting', richtingen);
});
function getTheString() {
return "/profiel/search_richting?json=true&limit=6&id=" + school_id + "&";
}
</script>
This is because the URL is static, it is not updated as the ID changes.
You should update the URL as part of the code you wrote to get the ID:
$("#school").blur(function() {
school_id = $("#school_id").val();
// update URL here ...
});
Aren't you concatenating script:"/profiel/search_richting?json=true&limit=6&id=" + school_id + "&" before the event is fired and the var updated?
Okay. So the problem was my third party plug-in instead of the code I wrote. I fixed this by editing the code of the autoSuggest plugin so it now includes my id field in the AJAX request.
var url = this.oP.script+this.oP.varname+"="+encodeURIComponent(this.sInp)+"&id="+ $("#school_id").val();
Thanks to everyone who tried to help me out!

Categories