Saving CSS State Jquery Cookie - javascript

I've been trying to implement a way to save the CSS class that gets added on click to each item. I'm not sure how to go about it since each item has a different ID. That idea is that a user can revisit a page, and still have their items selected. I tried looking up other examples, but most only involved saving the body css and not an array of ids. I tried with Jquery Cookie but to no avail, any help would be greatly appreciated.
$('.select_it, .myState').on('click', function(e) {
var id = $(this).attr('id');
isRadio = $(this).data('status');
if(isRadio) {
if ($(this).hasClass('myState')) {
$(this).removeClass('myState');
} else {
$('.select_it').removeClass('myState');
$(this).addClass('myState');
}
$('.nextbutton').fadeTo("slow", 1.0, function() {
});
jsRoutes.controllers.Builder.selectedOption(id).ajax({
success : function(data) {
}
});
} else {
$('.nextbutton').fadeTo("slow", 1.0, function() {
});
$(this).toggleClass('myState');
jsRoutes.controllers.Builder.selectedOption(id).ajax({
success : function(data) {
}
});
}
});
Solution:
var state = {};
$('.nextbutton').click(function () {return false;});
if (localStorage.getItem("state") === null) {
//
} else {
$('.nextbutton').fadeTo("slow", 1.0, function() {
$('.nextbutton').unbind('click');
});
state = JSON.parse(localStorage["state"]);
}
$('.select_it, .myState').each(function(i, obj) {
if(state[obj.id] == 'myState') {
$(this).addClass('myState');
}
});
$('.select_it, .myState').on('click', function(e) {
var id = $(this).attr('id');
isRadio = $(this).data('status')
if(isRadio) {
$('.nextbutton').fadeTo("slow", 1.0, function() {
$('.nextbutton').unbind('click');
});
$('.myState').each(function(index, element){
$(this).removeClass('myState');
$(this).addClass('select_it');
state[element.id]='select_it';
});
$(this).addClass('myState');
state[id]='myState';
jsRoutes.controllers.Builder.selectedOption(id).ajax({success : function(data) {}});
} else {
if ($(this).hasClass('select_it')) { // TOGGLE ON
state[id]='myState';
$(this).removeClass('select_it');
$(this).addClass('myState');
} else { // TOGGLE OFF
state[id]='select_it';
$(this).removeClass('myState');
$(this).addClass('select_it');
}
jsRoutes.controllers.Builder.selectedOption(id).ajax({success : function(data) {}});
}
localStorage['state'] = JSON.stringify(state);
});

Cookie can only store a string. I would also consider using localStorage rather than cookie...and use cookie as fallback for older browsers that don't support localStorage.
If you create an object using element ID's as keys, you can use JSON.stringify to create string to store and use JSON.parse to convert string to object again.
/* example populated object, only need an empty object to start*/
var ui_state={
ID_1:'someClass',
ID_2:'inactiveClass'
}
Then within event handlers:
$('#ID_1').click(function(){
var newClass= /* logic to dtermine new class*/
$(this).addClass(newClass);
storeStateToLocal(this.id, newClass);
});
/* simplified store method*/
function storeStateToLocal(element_id, newClass){
ui_state[element_id]= newClass;/* update ui_state object*/
if(window.locaStorage != undefined){
localStorage.setItem('ui_state', JSON.stringify( ui_state) );
}else{
/* stringify to cookie*/
}
}
On page load can iterate over the object:
var ui_state= getStateFromLocal();/* if none in storage, return false*/
if(ui_state){
$.each(ui_state,function( element_id, currClass){
$('#'+element_id).addClass(currClass);
});
}else{
ui_state={};/* create empty object if none already in storage*/
}

Hmm not 100% sure, but is it something like this what you want?
$('.select_it').each(function(){
if ($(this).attr('id') != $.cookie(cookieName)) {
$(this).removeClass('myState');
} else {
$(this).addClass('myState');
}
});
Or maybe more like this:
$('.select_it, .myState').on('click', function(e) {
$('.select_it').removeClass('myState');
$(this).addClass('myState');
// more code
});

Related

How to run 2 js functions

I have 2 function that I am trying to run, one after another. For some reason they both run at the same time, but the second one does not load properly. Is there a way to run the first function wait then run the second function?:
//run this first
$('#abc').click(function() {
$('.test1').show();
return false;
});
//run this second
(function ($) {
"use strict";
// A nice closure for our definitions
function getjQueryObject(string) {
// Make string a vaild jQuery thing
var jqObj = $("");
try {
jqObj = $(string)
.clone();
} catch (e) {
jqObj = $("<span />")
.html(string);
}
return jqObj;
}
function printFrame(frameWindow, content, options) {
// Print the selected window/iframe
var def = $.Deferred();
try {
frameWindow = frameWindow.contentWindow || frameWindow.contentDocument || frameWindow;
var wdoc = frameWindow.document || frameWindow.contentDocument || frameWindow;
if(options.doctype) {
wdoc.write(options.doctype);
}
wdoc.write(content);
wdoc.close();
var printed = false;
var callPrint = function () {
if(printed) {
return;
}
// Fix for IE : Allow it to render the iframe
frameWindow.focus();
try {
// Fix for IE11 - printng the whole page instead of the iframe content
if (!frameWindow.document.execCommand('print', false, null)) {
// document.execCommand returns false if it failed -http://stackoverflow.com/a/21336448/937891
frameWindow.print();
}
// focus body as it is losing focus in iPad and content not getting printed
$('body').focus();
} catch (e) {
frameWindow.print();
}
frameWindow.close();
printed = true;
def.resolve();
}
// Print once the frame window loads - seems to work for the new-window option but unreliable for the iframe
$(frameWindow).on("load", callPrint);
// Fallback to printing directly if the frame doesn't fire the load event for whatever reason
setTimeout(callPrint, options.timeout);
} catch (err) {
def.reject(err);
}
return def;
}
function printContentInIFrame(content, options) {
var $iframe = $(options.iframe + "");
var iframeCount = $iframe.length;
if (iframeCount === 0) {
// Create a new iFrame if none is given
$iframe = $('<iframe height="0" width="0" border="0" wmode="Opaque"/>')
.prependTo('body')
.css({
"position": "absolute",
"top": -999,
"left": -999
});
}
var frameWindow = $iframe.get(0);
return printFrame(frameWindow, content, options)
.done(function () {
// Success
setTimeout(function () {
// Wait for IE
if (iframeCount === 0) {
// Destroy the iframe if created here
$iframe.remove();
}
}, 1000);
})
.fail(function (err) {
// Use the pop-up method if iframe fails for some reason
console.error("Failed to print from iframe", err);
printContentInNewWindow(content, options);
})
.always(function () {
try {
options.deferred.resolve();
} catch (err) {
console.warn('Error notifying deferred', err);
}
});
}
function printContentInNewWindow(content, options) {
// Open a new window and print selected content
var frameWindow = window.open();
return printFrame(frameWindow, content, options)
.always(function () {
try {
options.deferred.resolve();
} catch (err) {
console.warn('Error notifying deferred', err);
}
});
}
function isNode(o) {
/* http://stackoverflow.com/a/384380/937891 */
return !!(typeof Node === "object" ? o instanceof Node : o && typeof o === "object" && typeof o.nodeType === "number" && typeof o.nodeName === "string");
}
$.print = $.fn.print = function () {
// Print a given set of elements
var options, $this, self = this;
// console.log("Printing", this, arguments);
if (self instanceof $) {
// Get the node if it is a jQuery object
self = self.get(0);
}
if (isNode(self)) {
// If `this` is a HTML element, i.e. for
// $(selector).print()
$this = $(self);
if (arguments.length > 0) {
options = arguments[0];
}
} else {
if (arguments.length > 0) {
// $.print(selector,options)
$this = $(arguments[0]);
if (isNode($this[0])) {
if (arguments.length > 1) {
options = arguments[1];
}
} else {
// $.print(options)
options = arguments[0];
$this = $("html");
}
} else {
// $.print()
$this = $("html");
}
}
// Default options
var defaults = {
globalStyles: true,
mediaPrint: false,
stylesheet: null,
noPrintSelector: ".no-print",
iframe: true,
append: null,
prepend: null,
manuallyCopyFormValues: true,
deferred: $.Deferred(),
timeout: 750,
title: null,
doctype: '<!doctype html>'
};
// Merge with user-options
options = $.extend({}, defaults, (options || {}));
var $styles = $("");
if (options.globalStyles) {
// Apply the stlyes from the current sheet to the printed page
$styles = $("style, link, meta, base, title");
} else if (options.mediaPrint) {
// Apply the media-print stylesheet
$styles = $("link[media=print]");
}
if (options.stylesheet) {
// Add a custom stylesheet if given
$styles = $.merge($styles, $('<link rel="stylesheet" href="' + options.stylesheet + '">'));
}
// Create a copy of the element to print
var copy = $this.clone();
// Wrap it in a span to get the HTML markup string
copy = $("<span/>")
.append(copy);
// Remove unwanted elements
copy.find(options.noPrintSelector)
.remove();
// Add in the styles
copy.append($styles.clone());
// Update title
if (options.title) {
var title = $("title", copy);
if (title.length === 0) {
title = $("<title />");
copy.append(title);
}
title.text(options.title);
}
// Appedned content
copy.append(getjQueryObject(options.append));
// Prepended content
copy.prepend(getjQueryObject(options.prepend));
if (options.manuallyCopyFormValues) {
// Manually copy form values into the HTML for printing user-modified input fields
// http://stackoverflow.com/a/26707753
copy.find("input")
.each(function () {
var $field = $(this);
if ($field.is("[type='radio']") || $field.is("[type='checkbox']")) {
if ($field.prop("checked")) {
$field.attr("checked", "checked");
}
} else {
$field.attr("value", $field.val());
}
});
copy.find("select").each(function () {
var $field = $(this);
$field.find(":selected").attr("selected", "selected");
});
copy.find("textarea").each(function () {
// Fix for https://github.com/DoersGuild/jQuery.print/issues/18#issuecomment-96451589
var $field = $(this);
$field.text($field.val());
});
}
// Get the HTML markup string
var content = copy.html();
// Notify with generated markup & cloned elements - useful for logging, etc
try {
options.deferred.notify('generated_markup', content, copy);
} catch (err) {
console.warn('Error notifying deferred', err);
}
// Destroy the copy
copy.remove();
if (options.iframe) {
// Use an iframe for printing
try {
printContentInIFrame(content, options);
} catch (e) {
// Use the pop-up method if iframe fails for some reason
console.error("Failed to print from iframe", e.stack, e.message);
printContentInNewWindow(content, options);
}
} else {
// Use a new window for printing
printContentInNewWindow(content, options);
}
return this;
};
})(jQuery);
How would I run the first one wait 5 or so seconds and then run the jquery print? I'm having a hard time with this. So the id would run first and then the print would run adter the id="abc" Here is an example of the code in use:
<div id="test">
<button id="abc" class="btn" onclick="jQuery.print(#test1)"></button>
</div>
If I understand your problem correctly, you want the jQuery click function to be run first, making a div with id="test1" visible and then, once it's visible, you want to run the onclick code which calls jQuery.print.
The very first thing I will suggest is that you don't have two different places where you are handling the click implementation, that can make your code hard to follow.
I would replace your $('#abc').click with the following:
function printDiv(selector) {
$(selector).show();
window.setTimeout(function () {
jQuery.print(selector);
}, 1);
}
This function, when called, will call jQuery.show on the passed selector, wait 1ms and then call jQuery.print. If you need the timeout to be longer, just change the 1 to whatever you need. To use the function, update your example html to the following:
<div id="test">
<button id="abc" class="btn" onclick="printDiv('#test1')"</button>
</div>
When the button is clicked, it will now call the previously mentioned function and pass it the ID of the object that you want to print.
As far as your second function goes, where you have the comment **//run this second**, you should leave that alone. All it does is extend you jQuery object with the print functionality. You need it to run straight away and it currently does.

Clear local storage for div on radio selection

I'm trying to get local storage to clear for all fields in one specific div when the user selects the No radio button:
Slightly incomplete jsfiddle but should do the trick
I'm obviously not doing something right here (.hide-show-yes is where I want all fields inside that div to clear):
$(document).ready(function(){
$('input[name="for_person"]').on('click', function () {
if ($('#personNo').prop('checked')) {
// ??
$('.hide-show-yes').localStorage.removeItem('fname');
} else {
// do nothing
}
});
});
localStorage is not a jQuery method . Also
$(document).ready([function() {
if (localStorage["dontclear"]) {
$('#dontclear').val(localStorage["dontclear"]);
}
if (localStorage["fname"]) {
$('#fname').val(localStorage["fname"]);
}
if (localStorage["lname"]) {
$('#lname').val(localStorage["lname"]);
}
console.log(localStorage)
}, function() {
$('.stored').change(function() {
localStorage[$(this).attr('name')] = $(this).val();
console.log(localStorage)
});
$('input[name="for_person"]').on('click', function() {
if ($('#personNo').prop('checked')) {
// ??
localStorage.removeItem('fname');
} else {
// do nothing
}
});
}]);
plnkr http://plnkr.co/edit/LPw3zbpgrhJkSh1hdKXG?p=info

if statement within function breaks javascript

I'm stumped with this one and would really appreciate someone's help.
I'm customizing highslide for integration with wordpress. Via the following code within the highslide.config.js file I'm adding a class name to certain elements and passing different attributes through an onClick call depending on certain conditions.
Everything works until I add the following code:
if(hsGroupByWpGallery){
slideshowGroup: this.parentNode.parentNode.parentNode.id
};
When the above code is present, not only does that one statement not execute, but the whole thing stops working. Even if the if statement is something like if(1=1){}; it still breaks.
If I have instead simply slideshowGroup: this.parentNode.parentNode.parentNode.id or nothing (the two options I'm looking for), both do what I would expect. I just need an if statement to switch between them.
Here's the relevant code:
jQuery(document).ready(function() {
var hsCustomGalleryGroupClass = 'fbbHighslide_GalleryGroup';
var hsCustomGalleryGroupChecker = 0;
var hsGroupByWpGallery = true;
jQuery('.' + hsCustomGalleryGroupClass).each(function(){
hsCustomGalleryGroupChecker++;
return false;
});
if (hsCustomGalleryGroupChecker > 0){
jQuery('.' + hsCustomGalleryGroupClass).each(function(i, $item) {
var grpID = $item.id;
jQuery('#' + grpID + ' .gallery-item a').addClass('highslide').each(function() {
this.onclick = function() {
return hs.expand(this, {
slideshowGroup: grpID
});
};
});
});
} else {
jQuery('.gallery-item a').addClass('highslide').each(function() {
this.onclick = function() {
return hs.expand(this, {
// This is the problem if statement
if(hsGroupByWpGallery){
slideshowGroup: this.parentNode.parentNode.parentNode.id
};
});
};
});
};
});
Thanks in advance.
The problem is you are trying to assign a conditional property.. you can't have a if condition inside a object definition like that
jQuery('.gallery-item a').addClass('highslide').each(function () {
this.onclick = function () {
var obj = {};
//assign the property only if the condition is tru
if (hsGroupByWpGallery) {
obj.slideshowGroup = this.parentNode.parentNode.parentNode.id;
}
return hs.expand(this, obj);
};
});
Another way to do the same is
jQuery('.gallery-item a').addClass('highslide').each(function () {
this.onclick = function () {
//if the flag is true sent an object with the property else an empty object
return hs.expand(this, hsGroupByWpGallery ? {
slideshowGroup: this.parentNode.parentNode.parentNode.id
} : {});
};
});
I think you might want this, based on the other code:
jQuery('.gallery-item a').addClass('highslide').each(function() {
this.onclick = function() {
if(hsGroupByWpGallery){
return hs.expand(this, {
slideshowGroup: this.parentNode.parentNode.parentNode.id
});
}
};
});

jquery addClass and removeClass issues

I am having strange issues with jQuery and adding and removing classes. I'm trying to see on success of a json request, that for the particular hyper link, it should call addClass and removeClass to add/remove particular css properties. When I click on it, it NEVER works, but when I try the css classes independently, they work fine. Is there something I'm missing here? Thanks for the input.
$(document).ready(function() {
$('.add_link').bind("click", function(e) {
$.getJSON("/add/", function(json) {
if (json.SUCCESS != null) {
$(this).removeClass('blue_button_link').addClass('gray_out_button_link');
}
});
});
});
$(document).ready(function() {
$('.add_link').bind("click", function(e) {
// cache it in a local variable.
var $this = $(this);
$.getJSON("/add/", function(json) {
if (json.SUCCESS != null) {
$this.removeClass('blue_button_link').addClass('gray_out_button_link');
}
});
});
});
In event handler you have another context, so you cannot use this how you want. Try:
$(document).ready(function() {
var link = $('.add_link');
link.bind("click", function(e) {
$.getJSON("/add/", function (json) {
if (json.SUCCESS != null) {
link.removeClass('blue_button_link').addClass('gray_out_button_link');
}
});
});
});
Or:
$(document).ready(function() {
$('.add_link').bind("click", function(e) {
var link = $(this);
$.getJSON("/add/", function (json) {
if (json.SUCCESS != null) {
link.removeClass('blue_button_link').addClass('gray_out_button_link');
}
});
});
});

How to run a JavaScript function when the user is visiting an hash link (#something) using JQuery?

I have a webb application at http://example.com/app and I would like to show a form if the user is visiting http://example/app#add-item.
Is there any way I can use a jQuery script to add this functionallity?
My current jQuery script already has a structure like this:
$(document).ready(
function() {
$('#search').keyup(
function() { ... }
);
}
)
How can I show a form using someting like this:
$(document).ready(
function() {
$('#search').keyup(
function() { ... }
);
$('#add-item').visit( // .visit probably doesn't exist
function() { content.innerHTML = myForm; }
);
}
)
Here is something I do:
var hash = (window.location.hash).replace('#', '');
if (hash.length == 0) {
//no hash
}
else {
//use `hash`
//example:
if(hash == 'add-item'){
//do something
}
}
Might be able to use the hashchange event, as shown at http://benalman.com/projects/jquery-hashchange-plugin/.
$(document).ready(
function() {
$('#search').keyup(
function() { ... }
);
$('#add-item').click(
function() { $("#content").html(myForm); }
);
}
);
I assume you have a element with id "content" where you want to display the form.

Categories