When I click a button the text will change every time. For example when I go to the page it shows 'Close'. If I click that button and it's value will change to 'Open'. It happens in another way also. If I click the 'Open' then it changes to close.
However the problem is if the button is in 'Open' state and if I do refresh it's changing to 'Close'. But if it's in 'Close' and I click refresh it's not changing to 'Open'.
What I need is after every click it should change from open to close or close to open. But after refresh also it should be in the same state. it should not get changed. How should I do it.
function changeStatus() {
console.log("Hi");
var val = document.getElementById("openClose").value;
$.ajax({
type: 'POST',
url: '/change/me',
data: {
'val': val
},
success: function(result) {
alert("The text has been changed");
}
})
}
$(".changeme").click(function() {
$(this).text(function(i, text) {
return text === 'Close' ? 'Open' : 'Close'
})
})
<!--Stylesheets-->
<link href="https://netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet">
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet">
<link href="http://getbootstrap.com/2.3.2/assets/css/bootstrap.css" rel="stylesheet" />
<!--JS files-->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
<button class="btn btn-danger changeme" onclick="changeStatus()" id="openClose">Close</button>
</div>
Version with local storage (but you can't test it inside snippet, snippet don't give acces to local storage, but codepen does) Demo on codepen
let store = window.localStorage
function changeStatus() {
let val
store.getItem('btnstat') === "Open"? checkUpdLocal("Close") : checkUpdLocal("Open") // toggle status
val = store.getItem('btnstat')
$.ajax({
type: 'POST',
url: '/change/me',
data: {
'val': val
},
success: function(result) {
alert("The text has been changed");
}
})
}
function checkUpdLocal(stat){
if(!store.getItem('btnstat')){ // if local storage does not exist
store.setItem('btnstat', "Close") // close by default
}else if(store.getItem('btnstat') && !stat){ // if storage exist but we don't change status (first ini) - change buttno text
$('.changeme').html(store.getItem('btnstat'))
}
if(stat){ // setter
store.setItem('btnstat', stat)
$('.changeme').html(stat)
}else{
return store.getItem('btnstat') // getter
}
}
$( document ).ready( function(){checkUpdLocal()})
<!--Stylesheets-->
<link href="https://netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet">
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet">
<link href="http://getbootstrap.com/2.3.2/assets/css/bootstrap.css" rel="stylesheet" />
<!--JS files-->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
<button class="btn btn-danger changeme" onclick="changeStatus()" id="openClose">Close</button>
</div>
Here is an example of using sessionStorage to persist state temporarily.
The sessionStorage object stores data for only one session (the data
is deleted when the browser tab is closed). sessionStorage will not
work on old browsers that do not have support for it.
<script type="text/javascript">
$(document).ready(function () {
if (sessionStorage.getItem("changeState") == null) {
$(".changeme").text("Close");
sessionStorage.setItem("changeState", "Close");
} else {
if (sessionStorage.getItem("changeState") === "Close") {
$(".changeme").text("Close");
} else {
$(".changeme").text("Open");
}
}
$(".changeme").click(function () {
if (sessionStorage.getItem("changeState") === "Close") {
$(this).text("Open");
sessionStorage.setItem("changeState", "Open");
} else {
$(this).text("Close");
sessionStorage.setItem("changeState", "Close");
}
})
});
</script>
When you use localStorage, you have to check if the value has been saved before
$( document ).ready(function(){
if(localStorage.getItem("openClose")!==undefined){
$('.changme').text(localStorage.getItem("openClose"));
});
(edited to put the lookup in ready function)
It's the older way, but you could also save the state in a cookie.
Save it with:
document.cookie = "Open";
on page load, retrieve it with
`
var state = document.cookie;
This is very awkward though; I would recommend using a cookie library to manipulate these.
Just one more answer if someone is thinking what if cookies are disabled in the browser and you still want to save the state of the elements on your web page according to the user's interaction.
In this case, you can save the state of the elements by doing AJAX call and save states to the database when the user changes the state of elements. But this would be a good approach only if you have lots of elements state to be saved. For 1-2 elements don't try this method. It will be inefficient.
By using cookies approach:
of course, you can store the 'state' in a cookie, and then retrieve that cookie when the page gets refreshed.
As cookies only admit strings, you can convert javascript objects to strings using
var str = JSON.stringify(obj);
and to convert back use
var obj = JSON.parse(str);
(JSON functions are supported in modern browsers).
This way you can save/retrieve a javascript object, you could store (in your case) some coordinates, positions, sizes, whatever you need.
Related
The situation : I use a script (a) in an HTML document to be able to use a particular SDK. Then I use a second script (b) basic to be able to create a Kendo UI table.
My problem : I try to pass data from script (a) to script (b) via global variables but it doesn't work, what can I do?
Info that might help you:
my document is a form framed by tags
I use Camunda. The first script allows me to use the SDK to retrieve the ID of the instance associated with the form being processed. (but I don't think this is the crux of the problem)
I assume that both scripts are read at the same time by the browser, and that's why script (b) can't read the variable simply because it is not yet created in script (a).
The code :
<script type="text/javascript" src="http://localhost:8080/camunda/app/tasklist/scripts/kendo.all.min.js"></script>
<script cam-script type="text/form-script">
var taskService = camForm.client.resource('task');
var processInstanceId = null;
var result = null;
taskService.get(camForm.taskId, function(err, task) {
//alert(JSON.stringify(task));
debugger;
processInstanceId = task.processInstanceId;
$.get("http://localhost:8080/engine-rest/process-instance/"+processInstanceId+"/variables", function(result) {
debugger;
window.alert("coucou");
console.log(result.JsonWeightSetpoints.value);
});
debugger;
console.log(result.JsonWeightSetpoints.value);
debugger;
});
</script>
<script type="text/javascript">
console.log(result.JsonWeightSetpoints.value);
//this is where I implement the Kendo UI grid
</script>
<div id="grid"></div>
I cannot read the content of the result variable in script (b) because it is not defined.
How do I do this?
Custom events solution:
<script type="text/javascript" src="http://localhost:8080/camunda/app/tasklist/scripts/kendo.all.min.js"></script>
<script cam-script type="text/javascript">
var taskService = camForm.client.resource('task');
var processInstanceId = null;
var result = null;
taskService.get(camForm.taskId, function(err, task) {
//alert(JSON.stringify(task));
debugger;
processInstanceId = task.processInstanceId;
$.get("http://localhost:8080/engine-rest/process-instance/"+processInstanceId+"/variables", function(result) {
debugger;
window.alert("coucou");
console.log(result.JsonWeightSetpoints.value);
// the value is available here, we now can trigger an event and send it
document.dispatchEvent(new CustomEvent("handler", {
detail: { value: result.JsonWeightSetpoints.value }
}));
});
debugger;
console.log(result.JsonWeightSetpoints.value);
debugger;
});
</script>
<script type="text/javascript">
console.log(result.JsonWeightSetpoints.value);
//this is where I implement the Kendo UI grid
// event listener, this would get executed only when we want
document.addEventListener("handler", function(event) {
// write you logic here
console.log(event.detail.value);
});
</script>
<div id="grid"></div>
useful resources:
MDN: Creating and triggering
events
Introducing asynchronous JavaScript
Edit: I figured it out. I'm a complete numpty and didn't test putting the switcher code at the top of my other scripts. As soon as I did that, I fixed it, and it works perfectly.
Old post below.
I want to be able to have my users select a stylesheet via button or link, and have the browser remember that. I'm not great with jQuery, but I know generally enough to follow tutorials and reverse-engineer, to a point.
I have been attempting to use this plugin, but it's not playing nicely with my existing code. There are a couple of things that could be causing the issue, but I think the most likely culprit is the different versions of jQuery that are used. Using just the 1.4.4 breaks some of the core functionality (the ability to reset the checkbox state), and using just the 1.11.2 means that the plugin doesn't work at all. I've no idea how to resolve this, nor even what to google.
After further testing, when using the demo's index.html, I can use just the 1.11 library without breaking functionality. But when using my index.html, it doesn't function at all. So that's probably not the issue.
The demo HTML is viewable online, and here is a pastebin of my full index.html. Obligatory plea for mercy regarding my subpar coding skills.
Here's the demo header:
<link type="text/css" rel="stylesheet" href="css/styles.css" />
<link type="text/css" rel="stylesheet" id="theme" href="css/theme1.css" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js?ver=1.4.4"> </script>
<script type="text/javascript" src="js/jquery.style-switcher.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$('#header').styleSwitcher();
});
</script>
And here's my header:
<link href="css/style.css" rel="stylesheet" type="text/css">
<link href="css/classic.css" rel="stylesheet" type="text/css">
<script src="http://code.jquery.com/jquery-1.11.2.min.js" type="text/javascript"></script>
<link href='http://fonts.googleapis.com/css?family=Marcellus+SC|Open+Sans' rel='stylesheet' type='text/css'>
<link rel="icon" type="image/png" href="http://starbuckguild.com/ore/favicon.png">
<script>
//Add functionality for hiding perm nodes that may be silver or iron
$(document).ready(function () {
$("input[name=both]").not(".textbox").click(function () {
if ($(this).is(":checked")) {
$("input[name=both]").prop('checked', true)
$("input[name=both]").parent(".container").addClass("visited_node");
$("input[name=both]").parent(".container").hide(500);
}
else $(this).parent(".container").removeClass("visited_node")
});
$("input[name=both2]").not(".textbox").click(function () {
if ($(this).is(":checked")) {
$("input[name=both2]").prop('checked', true)
$("input[name=both2]").parent(".container").addClass("visited_node");
$("input[name=both2]").parent(".container").hide(500);
}
else $(this).parent(".container").removeClass("visited_node")
});
$("input[name=both3]").not(".textbox").click(function () {
if ($(this).is(":checked")) {
$("input[name=both3]").prop('checked', true)
$("input[name=both3]").parent(".container").addClass("visited_node");
$("input[name=both3]").parent(".container").hide(500);
}
else $(this).parent(".container").removeClass("visited_node")
});
//Mark node as visited.
$("input").not(".textbox").click(function () {
if ($(this).is(":checked")) {
$(this).parent(".container").addClass("visited_node");
$(this).parent(".container").hide(500);
}
else $(this).parent(".container").removeClass("visited_node")
});
//Show visited nodes
$("#showall").click(function () {
$(".visited_node").show();
});
//Hide visited nodes
$("#hideall").click(function () {
$(".visited_node").hide();
});
//Hide all nodes with list price less than 1s
$("#good").click(function () {
$("input[name=bad]").parent(".container").addClass("visited_node");
$("input[name=bad]").parent(".container").hide();
});
//Add short route function
$("#short").click(function () {
$("input").parent(".container").addClass("visited_node");
$("input").parent(".container").hide();
$("input[name=1hr]").parent(".container").removeClass("visited_node");
$("input[name=1hr]").parent(".container").show();
});
//Prompt user to reset all nodes
$("#uncheckall").click(function () {
$(".button").show();
$(this).hide();
});
//Actually reset all nodes if user is sure
$("#imsure").click(function () {
$(".visited_node").show();
$("input").not(".textbox").prop("checked", false);
$(".visited_node").removeClass("visited_node");
$(".button").show();
$(this).hide();
});
//Hide or show nodes by type
$("#nav a").click(function () {
var id = $(this).attr('id');
id = id.split('_');
if ($(this).is(".off")){
$("#menu #menu_" + id[1]).show();
}
else {
$("#menu #menu_" + id[1]).hide();
}
$(this).toggleClass("off");
});
//Show map to nodes when clicked
var option = 'blank';
var url = window.location.href;
option = url.match(/option=(.*)/)[1];
showDiv(option);
});
function showDiv(option) {
$('.boxes').hide();
$('#' + option).show();
$('#blank').hide();
}
The plugin also requires
<div id="header">
Default
Darkness
Colorful
</div>
to be placed in the body of the page. I've just been putting it inside my navigation div at the top of the page, but perhaps I'm making a mistake there as well/instead.
As an aside, I note that the local machine version of the demo's index.html does not save the stylesheet preferences, whereas the web version does - I assume this is normal behaviour? Edit: It is. It works fine when uploaded.
I finally found a select menu plugin smart enough to work in IE comparability mode and also allows me to fire an event before the menu options are displaced. This awesome plugin is called jQuery Selectric.
I need to fire an event before the options are displayed and I want to make an ajax request which tells me which option I should enable/disable.
I was able to make the ajax request before the menu opens. but I am having hard time trying to disable the options. The options are always enabled even after I disable them.
I tried to use the $('select').selectric('refresh'); on ajax sucess but his cause a problem that the menu will never get a chance to open because just before it open the ajax request will close it again.
How can I disable options on the fly?
Here is what I have done
$('#MasterWrapUps').selectric();
$('#MasterWrapUps').on('selectric-before-open', function (e) {
var status = "noattempt";
$.ajax({
type: "GET",
url: "/getStatus",
dataType: "json",
cache: false,
success: function (data) {
if ( data && ! $.isEmptyObject(data) ) {
status = data.status;
}
attrWrapUpMenu(status);
}
});
});
function attrWrapUpMenu(status)
{
$('.dispositionMenuOption').each(function (index, element) {
var option = $(element);
if ( customIsAllowed(status, option) ) {
option.attr("disabled", false);
} else {
if( option.attr('selected') ) {
//At this point we know the option that is select can't be used, select the default value
$('#MasterWrapUps').val('0')
}
option.attr("disabled", true);
}
});
}
Since you cannot know how long the ajax is going to take to complete, I can think of two possible solutions:
The first is to display a hidden <div> over the input and, on click, show a loading image inside it. Then wait until the ajax is over to finally hide the div and trigger a click event on the updated <input>, or ....
You can launch the update function as soon as the page loads and keep the <select> disable until the ajax is complete.
I recommend the second one, but there might be other solutions. If you need any help implementing any of these you should open a new question.
Update
Since you want to do it after the click, the best I could come up with was this solution. It has the drawback that if the ajax takes too long and the user leaves the select input, it will reopen anyway. But I think this could be fixed with some focus/class verification. I'll leave that in your hands.
I must remind you that this kind of UI might leave some users (the one with bad connection) confused about what is available or not.
$('#MasterWrapUps').selectric().on('selectric-init', function () {
$('#MasterWrapUps').selectric('open');
});
$('.selectric').on('click', function () {
setTimeout(function () { /* fake ajax */
$('option:first-child').attr('disabled', true);
$('#MasterWrapUps').selectric('refresh');
}, 600 );
});
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-1.11.3.js"></script>
<script src="http://lcdsantos.github.io/jQuery-Selectric/jquery.selectric.js"></script>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
<link rel="stylesheet" href="http://lcdsantos.github.io/jQuery-Selectric/selectric.css">
<style>.selectric-above .selectric-items {top: 100%; bottom: auto}</style>
</head>
<body>
<select id="MasterWrapUps">
<option value="ant">Ant</option>
<option value="bird">Bird</option>
<option value="cat">Cat</option>
</select>
</body>
</html>
I reported this as a bug in github https://github.com/lcdsantos/jQuery-Selectric/issues/109. The author of the plugin Leonardo Santos at came up with a smart hacky way to solve the problem.
He gave me this code
$('#MasterWrapUps').selectric();
var isOpen = false;
var selectricData = $('#MasterWrapUps').data('selectric');
$('#MasterWrapUps').on('selectric-open', function (e) {
var status = "noattempt";
if (!isOpen) {
selectricData.close();
$.ajax({
type: "POST",
url: "/echo/json/",
dataType: "json",
cache: false,
data: {
// emulate ajax delay on jsfiddle
delay: 1
},
success: function (data) {
if ( data && ! $.isEmptyObject(data) ) {
status = data.status;
}
attrWrapUpMenu(status);
}
});
}
});
function customIsAllowed() {
return !!(Math.random()+.5|0);
}
function attrWrapUpMenu(status) {
$('.dispositionMenuOption').each(function (index, element) {
var option = $(element);
if ( customIsAllowed(status, option) ) {
option.prop('disabled', false);
} else {
if( option.prop('selected') ) {
$('#MasterWrapUps').val('0');
}
option.prop('disabled', true);
}
});
isOpen = true;
selectricData.refresh();
selectricData.open();
isOpen = false;
}
The code can also be found in this fiddle https://jsfiddle.net/lcdsantos/rgaeqbp6/
I hope this code help someone :)
I’m working on a left menu bar that expands on a button click.
I want to save the state of the menu, if it is expanded or not.
When it refreshes the class must still be added.
$('#menu-action').click(function() {
$('.sidebar').toggleClass('active');
$('.main').toggleClass('active');
$(this).toggleClass('active');
if ($('.sidebar').hasClass('active')) {
$(this).find('i').addClass('fa-close');
$(this).find('i').removeClass('fa-bars');
} else {
$(this).find('i').addClass('fa-bars');
$(this).find('i').removeClass('fa-close');
}
});
// Add hover feedback on menu
$('#menu-action').hover(function() {
$('.sidebar').toggleClass('hovered');
});
Try Local Storage:
$(document).ready(function() {
if(localStorage.getItem("active")) {
$('.sidebar').addClass("active")
}
});
$(window).unload(function() {
localStorage.setItem("active", $('.sidebar').hasClass("active"));
});
Local storage is not supported by all browsers. See the link above. You can use extensions like store.js to support old browsers.
Another option is to use cookie plugin as mentioned here.
Since you have not yet made it clear on how you want to read or write cookies, I'd recommend using js-cookie to make handling a little easier. Handling cookies with plain JS is possible, but a rather cumbersome task.
A solution using the mentioned library would work like this (Expecting you have added js.cookie.js before your code to your HTML)
// Store references to reusable selectors
var $menuAction = $('#menu-action');
var $menuActionI = $menuAction.find('i'); // the <i> inside #menu-action
var $sidebar = $('.sidebar');
var activeClass = 'active';
// Docs: https://github.com/js-cookie/js-cookie/tree/v2.1.0#basic-usage
var isActive = Cookies.get('site-menu-active') || false;
function toggleMenu() {
$sidebar.toggleClass('active', isActive);
$('.main').toggleClass('active', isActive);
$menuAction.toggleClass('active', isActive);
$menuActionI.toggleClass('fa-close', isActive);
$menuActionI.toggleClass('fa-bars', isActive);
isActive = !isActive;
Cookies.set('site-menu-active', isActive, { expires: 7 });
}
// Calling immediately to set to state read from cookie
toggleMenu();
// Add click interaction
$menuAction.click(toggleMenu);
// Add hover feedback on menu
$menuAction.hover(function() {
$sidebar.toggleClass('hovered');
});
The Html5 storage is the best option for these scenario. Here you can change the localStorage to sessionStorage based on the requirement:
1)localStorage - even close the browser the data is alive
2)sessionStorage - while close the browser the data is removed
We can also remove the stored data
$('#menu-action').click(function() {
$('.sidebar').toggleClass('active');
$('.main').toggleClass('active');
$(this).toggleClass('active');
localStorage.setItem("active", $('.sidebar').hasClass('active'));
if ($('.sidebar').hasClass('active')) {
$(this).find('i').addClass('fa-close');
$(this).find('i').removeClass('fa-bars');
} else {
$(this).find('i').addClass('fa-bars');
$(this).find('i').removeClass('fa-close');
}
});
$(document).ready(function(){
if(localStorage.getItem("active")){
$('.sidebar').addClass('active');
$('.main').addClass('active');
$('#menu-action').find('i').addClass('fa-close');
$('#menu-action').find('i').removeClass('fa-bars');
}
});
I want to know if the line below is needed in this script, and if so, what purpose it serves.
$("#quantity-0").focus();
If I do not have a form field with id "quantity-0" what other elements could I focus (if required)? Can I focus a hidden form element?
Here's my code. It comes from this blog.
<script type="text/javascript" charset="utf-8">
//<![CDATA[
// Including jQuery conditionnally.
if (typeof jQuery === 'undefined') {
document.write({{ "http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js" | script_tag | json }});
document.write('<script type="text/javascript">jQuery.noConflict();<\/script>');
}
//]]>
</script>
<script>
$(document).ready(function () {
$("#quantity-0").focus();
var length = $("#linklist-length").val();
$("#submit-table").click(function(e) {
e.preventDefault();
//array for Variant Titles
var toAdd = new Array();
var qty;
for(i=0; i < length; i++){
toAdd.push({
variant_id: $("#variant-"+i).val(),
quantity_id: $("#quantity-"+i).val() || 0
});
}
function moveAlong(){
if (toAdd.length) {
var request = toAdd.shift();
var tempId= request.variant_id;
var tempQty = request.quantity_id;
var params = {
type: 'POST',
url: '/cart/add.js',
data: 'quantity='+tempQty+'&id='+tempId,
dataType: 'json',
success: function(line_item) {
//console.log("success!");
moveAlong();
},
error: function() {
//console.log("fail");
moveAlong();
}
};
$.ajax(params);
}
else {
document.location.href = '/cart';
}
};
moveAlong();
});
});
</script>
I want to know if the line below is needed in this script, and if so, what purpose it serves.
Calling the jQuery .focus() method with no arguments sets focus to the specified element. That line is the first line inside the document ready handler. So its purpose is to set focus to that particular field when the page first opens/loads.
As to whether it is needed, that's really up to the page designer. Setting focus to the field the user will most likely want to interact with first is generally helpful to them. If you didn't have that it wouldn't stop the page from working or anything.
If I do not have a form field with id "quantity-0" what other elements could I focus (if required)?
You can set focus to whatever element you like. Normally this would be either a form element of some kind (input, button, etc.) or a hyperlink. Whichever one makes most sense for a user to interact with first upon page load.
Can I focus a hidden form element?
Why would you want to do that? It doesn't make sense for a user to interact with a hidden element. I believe attempting to set focus to a hidden element may give an error in some browsers.