Localstorage and saving session state - javascript

I am making a webapp, that uses mobiscroll as a number counter. The numbers are saved via a submit button below it. The problem I have is whenever the user presses the home button, when the webapp is reloaded, it resets the number list. I figured it would be a good idea to save the value to localstorage,and recall it when the app is reopened. Now that's where I am stuck.
Here is the function for the button press that works fine:
<script type="text/javascript">
function save_it() {
//Save the scroll value for later
var scrollsave = $('#i').scroller('getValue');
localStorage.setItem("scrollsave", scrollsave);
localStorage.saveServer
}
</script>
I have a function further up, that is giving me trouble, and refusing to work proper, I have tried the following methods:
My first attempt to assign
<script type="text/javascript">
$(function () {
var scrollstate = localStorage["scrollsave"];
if (scrollstate != null) {
$('#i').scroller('setValue', scrollstate);
}
});
</script>
I get an error of, Object x,x,x,x has no method 'join'.
Second attempts to convert to array and back, but no luck.
var oldscroll = localStorage.getItem["scrollsave"];
var finalsaved = SON.parse(oldscroll);
if (finalsaved != null) {
$('#i').scroller('setValue', finalsaved);
The documentaion on mobiscroll is here http://docs.mobiscroll.com/22/mobiscroll-core . And it says, "scroller values from the data parameter passed as array".
My key, scrollsave is stored with a value of 1,2,1,1 . Which seems to meet the correct formatting to throw into the mobiscroll part.
I have a feeling there is something trivial I am overlooking, but I can't figure out what.

var oldscroll = localStorage.getItem["scrollsave"]; should be var oldscroll = localStorage.getItem("scrollsave");

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.

Returning empty string on a input that has a value

I have a date input in my page, which I'm using Daterangepicker framework to populate it.
Here is the code of how I start my page!
$(function(){
startSelectors();
var variaveis = returnInputVars();
var rede = variaveis[0];
var codLoja = variaveis[1];
var period = variaveis[2];
console.log('1.'+rede+' 2.'+codLoja+' 3.'+period);
});
function returnInputVars(){
var rede = $("#dropdown-parceria").val();
var codLoja = $("#dropdown-loja").val();
var periodo = $("#datepicker-range").val();
return [rede, codLoja, periodo];
};
The function startSelectors() is set to start my datepicker and other fields, which is working perfectly. After it, I create a var called "variaveis" to fill
with the values of each field because I will use then later (this functions also works perfectly at other scripts of my page).
Running the page, my console returns this:
The funny thing is, if I type at the console this, the value is shown, just while starting the script is does not work!
Anybody experienced something like this?
***UPDATE
Adding this script to my start function:
console.log($("#datepicker-range"));
The value is shown, but the second console.log don't:
EDIT 1. FIDDLE (Suggested by #halleron)
To ensure things are loaded in the correct order, it is useful to apply a page sniffer code snippet that will scan the page continuously until a condition is met, or until a preset counter limit is reached (to prevent strain on browser memory). Below is an example of what I typically use that would fit your scenario.
I think because you are dealing with asynchronous loading, you can't have a global variable that holds the values in a global scope without an interval to detect when it can be used. Otherwise, it will attempt to read the variable when it is not yet ready.
You can invoke functions anywhere you like. But I would keep all of your variables contained within the page_sniffer_2017() because that is a controlled environment where you know that everything successfully loaded and you know that the variables are ready to be accessed without error.
That way, regardless of connection speed, your functions will only fire when ready and your code will flow, sequentially, in the right order.
Within the ajax success options, always add a class to the body of the document that you can search on to determine if it has finished loading.
$(document).ready(function() {
page_sniffer_2017();
});
function page_sniffer_2017() {
var counter = 0;
var imgScanner = setInterval(function() {
if ($("#datepicker-range").length > 0 && $("#datepicker-range").val().length && jQuery('body').hasClass('date-picker-successfully-generated')) {
var periodoDatepicker = $("#datepicker-range").val(); // ok
console.log(periodoDatepicker); // ok
var variaveis = returnInputVars(replaceDate(periodoDatepicker)); // ok
console.log(variaveis[0], variaveis[1], variaveis[2]);
//startNewSelectors(variaveis);
// start ajax call
generateData(variaveis[0], variaveis[1], variaveis[2]);
clearInterval(imgScanner);
} else {
//var doNothing = "";
counter++;
if (counter === 100) {
console.log(counter);
clearInterval(imgScanner);
}
}
}, 50);
}

Can't overwrite object saved with rhaboo in javascript

I'm trying to save an object with rhaboo in javascript. The first time after initialising it is working but when I'm trying to save it again it gives me the
rhaboo.min.js:1 Uncaught TypeError: Cannot read property 'refs' of undefined error. I pinned down the error to the line where I save the keyArray with notes.write('presentationNotes', keyArray);
How I get the error in detail:
I open my webapplication with a clean localStorage (nothing is saved) and rhaboo gets initialised. After that I navigate to a document and open the notes-div with the notes-button. I write something in the notes-area and hit the notes-submit button to save the notes with rhaboo to localStorage. I do the same for a second document. For now everything works. Both notes get saved correctly so that I have an object like this:
keyArray = {activeDoc1: ['note1', 'note2'], activeDoc2: ['note1', 'note2']}
saved in rhaboo in notes.presentationNotes. Then I reload my webapplication and rhaboo is already initialised. I navigate to the documents as before and check if I can load the saved notes. This works as expected but when I try to hit the notes-submit button again it gives me the aforementioned error. What am I doing wrong?
var notes = Rhaboo.persistent('Presentation Notes');
$(document).ready(function(event) {
var keyArray, activeDoc;
if (!notes.initialised) {
notes.write('initialised', true);
notes.write('presentationNotes', {});
console.log('Rhaboo Initialised');
keyArray = {};
} else {
console.log('Rhaboo already initialised');
keyArray = notes.presentationNotes;
console.log('notes.presentationNotes onLoad = ');
console.log(notes.presentationNotes);
}
//Notes open
$(document).on('click', '#notes-button', function() {
$('.notes-div').show();
activeDoc = $('.node.active').attr('id');
if (notes.presentationNotes[activeDoc] != null) {
//Iterate notes
$.each(notes.presentationNotes[activeDoc], function(index, value) {
$('#notes-area').append(value + '\n');
});
}
});
//Notes save
$(document).on('click', '#notes-submit', function() {
$('.notes-div').hide();
var str = $('#notes-area').val();
var array = str.split("\n");
keyArray[activeDoc] = array;
//Save notes
notes.write('presentationNotes', keyArray);
//Clear textarea
$('#notes-area').val('');
});
}
Without the HTML I haven't been able to try this, so I'm just guessing here, but I suspect your problem will go away if you stop using keyArray and activeDoc. The whole point of rhaboo is that it is not a place to store your data. It IS your data.
I see no transient data in your program, i.e., no data which you actively want to delete when the user goes away and comes back. All the data is supposed to be persistent, therefore it should all be under the Rhaboo.persistent.
That's the philosophy, but to be more specific, I think your problem is here:
keyArray[activeDoc] = array;
When I wonder what keyArray is is find:
keyArray = notes.presentationNotes;
so the earlier line actually says:
notes.presentationNotes[activeDoc] = array;
but it says on the tin that that should read:
notes.presentationNotes.write(activeDoc, array);
The upshot is that that the hooks that make rhaboo work have not been inserted into array, as notes.presentationNotes.write would have done.
When you next said:
notes.write('presentationNotes', keyArray);
it meant:
notes.write('presentationNotes', notes.presentationNotes).
which is clearly not what you meant. Rhaboo doesn't suspect that array has no hooks yet because it can see that notes.presentationNotes does have hooks.
I also forget to use write sometimes, and it really bugs me that JS offers no way to hook into the creation of a NEW key within an object X, no matter what you've done to X. Without that limitation, there'd be no need for write and it could be foolproof.

Executing a jquery function stored as a variable name

I'm struggling with figuring out how to call/execute a function in jQuery. I've done quite a bit of searching and find what looks like it should be the answer, but it doesn't seem to work. I assume it is a scope issue since everything else seems to match examples I've found here, but I'm relatively new to jQuery and can't quite figure it out.
Basically, when the "bookmark" button is clicked, it uses ajax to create an entry in the database, and changes the format of the clicked button. This acts as expected. The trick is this requires someone to be logged in. The actual click of the button adds a #bookmarkme anchor to the url - if they aren't logged in (this is where things start getting tricky for me), the log in window pops up and they are prompted to sign up/log in, and the page reloads to set all the log in variables properly. This also works as expected. Where it breaks down is once the user logs in and the page reloads, I can't get the "bookmarkFunction" to run.
<script type="text/javascript">
var loggedin = <?php echo $loggedin; ?>;
var headerButtonScript = function(){
var bookmarkFunction = $("#bookmark").click(function(){
var directoryName = "<?php echo $directoryName;?>";
if(loggedin == 1 && $("#bookmark").hasClass("headerButton")){
$.ajax({
type: "POST",
url: "../includes/bookmarkProcess.php",
data: {directory: directoryName},
success: function(data, status){
if(data == "success"){
$("#bookmark").switchClass("headerButton", "headerButtonDisabled", 1000, "easeInOutQuart");
$("#bookmark").text("Bookmarked");
}
}
});
}
else{
$("#signInContent").toggleClass('hidden');
$("#signInPopUp").toggleClass('hidden');
}
});
};
var headerButtonsAfterLoad = function(){
var currentAddress = window.location.href;
var hashPosition = currentAddress.indexOf("#");
var targetLocation = currentAddress.substring(hashPosition+1);
if(targetLocation == "bookmarkme"){
if(loggedin==1){
//CALL bookmarkFunction HERE;
//I know I get to this location when expected, because placing an alert("message") gives me the pop up
}
}
};
$(document).ready(headerButtonScript);
$(window).bind('load',"",headerButtonsAfterLoad);
</script>
Based on my research, I have tried the following lines (one line attempted each time rather than all at once, of course) in the excerpt to try to call the function, but no luck yet.
if(targetLocation == "bookmarkme"){
if(loggedin==1){
//CALL bookmarkFunction HERE;
bookmarkFunction();
bookmarkFunction.run();
bookmarkFunction.call();
bookmarkFunction.apply();
}
}
Any help on locating my issue - scope, methods, or otherwise - is greatly appreciated!
"I need the script to take the same action it would when I click on the bookmark button (ID = bookmark) when the page reloads and has the anchor #bookmarkme"
This will do what you want^
$('#bookmarkme').trigger('click');
$("#bookmark").click(). should work.
Remember, calling a jQuery method on a jQuery object returns the original jQuery object. So if you say:
var bookmark=$('#bookmark')
Then bookmark is set to the jQuery object (which contains the element of id=bookmark as a property).
If you attach methods to the object like this:
var bookmark=$('#bookmark').click(function(){console.log('You clicked!')})
Then, yes, the element with id bookmark will now call this event when you click it, but the click method on a jquery object returns the original jquery object. That means bookmark will still be equal to $("#bookmark"), not the function in the click method.
So in conclusion, when you attach an event to a jquery object, like click or hover, it goes into the dom and attaches the event, and then returns the original jquery object. That way you can do things like:
var bookmark=$("#bookmark").click(function(){console.log("you clicked")}).mouseover(function(){console.log("you moused over")})
And you can keep attaching events forever and ever, and bookmark will always be equal to $("#bookmark")

Use jQuery to determine when Django's filter_horizontal changes and then get the new data

I have a filter_horizontal selector in my Django admin that has a list of categories for products (this is on a product page in the admin). I want to change how the product change form looks based on the category or categories that are chosen in the filter_horizontal box.
I want to call a function every time a category is moved from the from or to section of the filter_horizontal.
What I have now is:
(function($){
$(document).ready(function(){
function toggleAttributeSection(choices) {
$.getJSON('/ajax/category-type/', { id: choices}, function (data, jqXHR) {
// check the data and make changes according to the choices
});
}
// The id in the assignment below is correct, but maybe I need to add option[]??
var $category = $('#id_category_to');
$category.change(function(){
toggleAttributeSection($(this).val());
});
});
})(django.jQuery);
The function never gets called when I move categories from the left side to the right side, or vice versa, of the filter_horizontal.
I assume that $category.change() is not correct, but I don't know what other events might be triggered when the filter_horizontal is changed. Also, I know there are multiple options inside of the select box. I haven't gotten that far yet, but how do I ensure all of them are passed to the function?
If anyone can point me in the right direction I would be very grateful. Thank!
You need to extend the SelectBox.redisplay function in a scope like so:
(function() {
var oldRedisplay = SelectBox.redisplay;
SelectBox.redisplay = function(id) {
oldRedisplay.call(this, id);
// do something
};
})();
Make sure to apply this after SelectBox has been initialized on the page and every time a select box refreshes (option moves, filter is added, etc.) your new function will be called.
(Code courtesy of Cork on #jquery)
I finally figured this out. Here is how it is done if anyone stumbles on this question. You need to listen for change events on both the _from and _to fields in the Django filter_horizontal and use a timeout to allow the Django javascript to finish running before you pull the contents of the _from or _to fields. Here is the code that worked for me:
var $category = $('#id_category_to');
$category.change(function(){
setTimeout(function () { toggleAttributeSection(getFilterCategoryIds()) }, 500);
});
var $avail_category = $('#id_category_from');
$avail_category.change(function(){
setTimeout(function () { toggleAttributeSection(getFilterCategoryIds()) }, 500);
});
And this is how I get the contents of the _to field:
function getFilterCategoryIds() {
var x = document.getElementById("id_category_to");
var counti;
var ids = [];
for (counti = 0; counti < x.length; counti++) {
ids.push(x.options[counti].value);
}
return ids;
}
I know it was a convoluted question and answer and people won't come across this often but hopefully it helps someone out.

Categories