Day/Night mode - CSS + JQuery - Cookies? - javascript

I'm testing javascript code for day/light background switch and I don't know how to do something. I'm newbie to javascript, so I'm learning new stuff.
So what I want to do?
When I click for example on button "Day" (which change background to yellow), I want that style for yellow background stay in the code after page is refreshed. I heard something about Cookies/LocalStorage, but I don't know how to implement it for this code.
Feel free to change whole code if you know easier way to do this, but please explain why it's better or why it should be like that.
Thanks in advance for your help.
Here is the code:
HTML:
<body id="body">
<input type="button" onclick="day();" value="Day" />
<input type="button" onclick="night();" value="Night" />
<input type="button" onclick="reset();" value="Reset" />
</body>
CSS:
.darkSwitch {
background: #808080;
}
.lightSwitch {
background: #ffff99;
}
JavaScript:
function day() {
body.className = "lightSwitch";
};
function night() {
body.className = "darkSwitch";
};
function reset() {
body.className = "";
};
$(function() {
var button = $('input[type=button]');
button.on('click', function() {
button.not(this).removeAttr('disabled');
$(this).attr('disabled', '');
});
});

Last edit: now disabling selected button on page load, CODE NOT IN THIS POST, see the latest JSFiddle
Explanation
What I did:
The code is put in between<script> tags at the end of the <body> (personnal preference)
I added the parameter event to the onClick event of the button element.
I added event.preventDefault() at the start of the onclick event of the button element: ensuring the page is NOT refreshed on the click of a button.
Warning: ALL the buttons will behave the same in your page. If you have other buttons, I suggest you add another class for those three buttons and bind the event on the button.myClass element.
I added a condition on the button state change, so the reset button won't get disabled.
eval($(this).val().toLowerCase()+"();"); gets the value of the the clicked button and executes the function attached to it.
Solution
HTML
<body id="body">
<input type="button" class="changeBg" onclick="day();" value="Day" />
<input type="button" class="changeBg" onclick="night();" value="Night" />
<input type="button" class="changeBg" onclick="reset();" value="Reset" />
</body>
JavaScript
(JSFiddle) <-- Check this out Updated with classes & cookies
function day() {
body.className = "lightSwitch";
};
function night() {
body.className = "darkSwitch";
};
function reset() {
body.className = "";
};
$(function () {
/* RegEx to grab the "bgColor" cookie */
var bgColor = document.cookie.replace(/(?:(?:^|.*;\s*)bgColor\s*\=\s*([^;]*).*$)|^.*$/, "$1");
var button = $('input[type=button].changeBg');
button.on('click', function (event) {
event.preventDefault();
/* Executing the function associated with the button */
eval($(this).val().toLowerCase() + "();");
button.not($(this)).removeAttr('disabled');
if ($(this).val() != "Reset") {
$(this).attr('disabled', '');
/* Here we create the cookie and set its value, does not happen if it's Reset which is fired. */
document.cookie = "bgColor="+$(this).val();
}
});
/* If the cookie is not empty on page load, execute the function of the same name */
if(bgColor.length > 0)
{
eval(bgColor.toLowerCase()+'()');
/* Disable the button associated with the function name */
$('button[value="'+bgColor+'"]').attr("disabled","disabled");
}
});

I recommend you don't use cookies unless localStorage is not supported. They slow your site down.
if(localStorage){
localStorage.setItem("bgColor", "lightSwitch");
}else{
document.cookie = "bgColor=lightSwitch";
}

Related

Detect changes made to input through code

Somewhere in my page I have an button that when clicked changes the value of another input. However I don't have control over the code where the click event is defined (on a clients' CDN) and I didn't bother to look. I just want to capture the event when my inputs' value is change through the code. Here's an example:
HTML
<input type="text" id="myinput" />
<input type="button" id="theonechanging" value="Click Me" />
<br />
<p id="message"></p>
JS
var i = 0;
$("#theonechanging").click(function(e) {
// YOU CAN NOT CHANGE THIS FUNCTION
$("#myinput").val("changed via button " + i++);
});
$("#myinput").on("input change bind",function(e) {
$("#message").text("changed " + i++);
});
Here's a fiddle where you can test the situation: http://jsfiddle.net/fourat05/t9x6uhoh/
Thank you for your help !
There's an incredibly hacky way to do this.
What you do is replace the jQuery.fn.val function with your own implementation, and call the old implementation from the new one. This technique is a kind of Monkey patching.
The implementation is as follows:
var i = 0;
$("#theonechanging").click(function(e) {
// YOU CAN NOT CHANGE THIS FUNCTION
$("#myinput").val("changed via button " + ++i);
});
var handleChanges = function(){
$("#message").text("changed " + i);
}
var oldval = jQuery.fn.val;
jQuery.fn.val = function(){
oldval.apply(this,arguments);
if(this.attr('id') === 'myinput'){ //and possibly add a check for changes
handleChanges();
}
}
$("#myinput").on("input change bind",function(e) {
i++;
handleChanges();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<input type="text" id="myinput" />
<input type="button" id="theonechanging" value="Click Me" />
<br />
<p id="message"></p>
However, I strongly recommend against using it, because:
This alters the behaviour of a widespread library, thus creating possible pitfalls for the developers producing code for the same page
It will quickly become complicated to detect multiple events on multiple elements.
Please understand the side effects of this method before implementing it.
Values changed directly in the DOM dont trigger those events, but since you have an action that is called to change the value, you can trigger the input change event.
$("#theonechanging").on("click", function(e) {
$("#myinput").trigger("change");
});
fiddle
use triggers
var i = 0;
$("#theonechanging").click(function(e) {
// YOU CAN NOT CHANGE THIS FUNCTION
$("#myinput").val("changed via button " + i++);
});
$("#theonechanging").on("click", function(e) {
$("#myinput").trigger("change");
});
$("#myinput").on("input change bind",function(e) {
$("#message").text($("#myinput").val());
});
Fiddle
I think it is not possible without changing the script for BUTTON.
When the user click the 'Button', you should trigger another function to catch the change in 'Input'.
If you don't want to change the 'Button' script, you can try something like the code below, seeking for the correct combination of events:
(check the list of events here: http://www.w3schools.com/tags/ref_eventattributes.asp)
<html>
<body>
<input type="text" id="myinput" onchange="change_Message('onchange')"
onclick="change_Message('onclick')"
oninput="change_Message('oninput')"
onkeypress="change_Message('onkeypress')"/>
<input type="button" id="theonechanging" value="Click Me" onclick="change_Input()"/>
<br />
<p id="message"></p>
<script>
var input_value = document.getElementById('myinput').value; // as global variable
function Test_if_Change()
{
if ( document.getElementById('myinput').value != input_value )
{
change_Message('Test_if_Change');
}
}
setInterval(Test_if_Changed, 10);
function change_Input() { document.getElementById('myinput').value = 'input changed by button'; }
function change_Message(event) { document.getElementById('message').innerHTML = 'message changed by '+event+' to: ' + document.getElementById('myinput').value; }
</script>
</body>
</html>
There is no perfect way to detect input value changes through code but if you you are using jquery ,you can hook the val function and trigger change event manually.
jQuery.fn._val = jQuery.fn.val;
jQuery.fn.val = function(){
jQuery.fn._val.apply(this,arguments);
if(arguments.lenght==1){
this.trigger('code-change');
}
}
}

Bind button to a Javascript case/action

I am new to Javascript, and i run into some big problems. I got some functions, which I can type into a text field and press enter, and the functions works. But i have created 4 buttons, which i want to connect to the actions.. i got 4 actions: "UP","DOWN","LEFT" and "RIGHT".
This is the js fiddle over my code: http://jsfiddle.net/n24gQ/
I have made the buttons like this but I dont know what to write inside the OnClick tag?
<div id="gamebuttons">
<button id="up" button onClick="">UP</button>
<button id="down" button onClick="">DOWN</button>
<button id="left" button onClick="">LEFT</button>
<button id="right" button onClick="">RIGHT</button>
</div>
I hope you can understand what my problem is. I made 4 javascript cases which I want to bind to 4 html buttons if possible.. :) It is the cases: "frem" "tilbage" "hoejre" and "venstre" i need to bind.. Sorry not everything in the code is english, but it should be understandable..
Fiddle
You can simply write the function name you've defined for the buttons into the onclick attribute, e.g. like this:
<button id="up" type="button" onclick="alert('UP'); return false;">UP</button>
However, as your buttons already have id's you can also check if one of those id's got clicked without the need of onclick in your markup:
JavaScript:
var buttonUp = document.getElementById('up');
buttonUp.onclick = function() { myFunction(); return false; }
jQuery:
$('#up').on('click', myFunction());
Instead of using inline handlers (bad practice) or multiple handlers for each button, I would use event delegation on your button wrapper, like so
$('#gamebuttons').on('click', 'button', function() {
/* get the id attribute of the clicked button */
var button_id = this.id;
case (button_id) {
"UP" : /* code for up button */ break;
"DOWN" : /* code for down button */ break;
"LEFT" : /* code for left button */ break;
"RIGHT" : /* code for right button */ break;
}
});
Please pass the function name inside the OnClick tag
for example if you want to associate playGame function to DOWN button
write
<button id="down" onclick="playGame();">DOWN</button>
I think these below changes will give you solution.
Instead of the first button, you need to bind events to all of the buttons which you required. Currently, querySelector() getting only first button to bind events. So, use querySelectorAll()
Replace this code
var button = document.querySelector("button");
button.style.cursor = "pointer";
button.addEventListener("click", clickHandler, false);
button.addEventListener("mousedown", mousedownHandler, false);
button.addEventListener("mouseout", mouseoutHandler, false);
With below code
var gamebuttonslist=document.querySelectorAll("#gamebuttons button");
for (var vitem=0;vitem<gamebuttonslist.length;vitem++) {
if (typeof gamebuttonslist[vitem] != "undefined" && gamebuttonslist[vitem] != null) {
gamebuttonslist[vitem].style.cursor = "pointer";
gamebuttonslist[vitem].addEventListener("click", clickHandler, false);
gamebuttonslist[vitem].addEventListener("mousedown", mousedownHandler, false);
gamebuttonslist[vitem].addEventListener("mouseout", mouseoutHandler, false);
}
}

How to trigger a click event on disabled elements

I have a disabled button, which is enabled after checking "I accept terms and conditions" checkbox.
The problem is that I wanted to trigger an alert, if a user clicks the disabled button. How can I do this? If an element is disabled, it looks as "onclick" events are not fired.
The sample of the code:
<input id="subm_tc" class="btn btn-primary" type="submit" disabled="" value="Log in" name="Submit">
$("#subm_tc").click(function () {
if($("#modlgn-tc").is(':checked')){
alert('checked');
} else {
alert('unchecked');
}
});
If I wrap the element in div and listen to clicks on that div, it works, but you need to click outside the button.
How can I fix this?
Thanks
UPDATE. I've managed to resolve this by adding a fake div over the submit button and listening to events on that div (I also change z-index to -200 to enable clicks on the button itself):
<div style="position:relative">
<div id="subm_tc" style="position: absolute; left: 0px; right: 0px; bottom: 0px; top: 0px; z-index: 99999;"></div>
<input id="subm_tc" class="btn btn-primary" type="submit" disabled="" value="Log in" name="Submit">
</div>
Now it works as intended
My solution was to put the button in a div, which is clickable. when the button is disabled, the div has the width and height of the button, so clicking the button triggers the div. when the button is enabled, the div is shrunk to 0 width 0 height, so the click event registers with the button instead of the div. This code includes some demoing code as well for a toggle button which toggles the enabled/disabled state of the button in question
fiddle: http://jsfiddle.net/6as8b/2/
HTML
Click 'Toggle" to make 'Button' enabled or disabled. click it, and see that that one event fires if it is enabled, and another if disabled.
<input type=button value='toggle' id='toggle'><BR>
<div style='position:relative'>
<div id='clickable'></div>
<input id=theButton type=button disabled value='Button'>
</div>
<div id=clicks></div>
CSS
#clickable{
position:absolute;
width:55px;
height:25px;
}
JS
$(document).ready(function () {
$('#clickable').on('click',function () {
if ($('#theButton:disabled').length>0)
{
$('#clicks').append('|Disabled Button Clicked|<br>');
}
else
{
//do nothing and let the button handler do it
$('#theButton').click();
}
});
$('#theButton').on('click',function() {
$('#clicks').append('|ENABLED button clicked|<br>');
});
$('#toggle').on('click',function() {
if ($('#theButton:disabled').length>0)
{
$('#theButton').removeAttr('disabled');
$('#clickable').css({'width':'0px','height':'0px'});
}
else
{
$('#theButton').attr('disabled','disabled');
$('#clickable').css({'width':'55px','height':'25px'});
}
});
});
Disabled elements doesn't trigger any mouse events at all, so that's probably a lost cause.
However, when clicking a parent element, the event.target seems to be given correctly, which means this should work :
$(document).on('click', function (e) {
if (e.target.id == 'subm_tc') {
if($("#modlgn-tc").is(':checked')){
alert('checked');
} else {
alert('unchecked');
}
}
});
FIDDLE
You can write a function that adds listeners to the mousedown and mouseup events, and if the targets match your Node (i.e. the mousedown and following mouseup were on your element), then it invokes another function
function listenFullClick(elm, fn) {
var last;
document.addEventListener('mousedown', function (e) {
last = e.target === elm;
});
document.addEventListener('mouseup', function (e) {
if (e.target === elm && last) fn();
});
};
listenFullClick(
document.getElementById('foo'), // node to look for
function () {alert('bar');} // function to invoke
);
DEMO
Old topic, but here are my two cents as I had the same challenge lately:
Don't try to position a clickable element above it but wrap it with one so you won’t directly be able to click it. Assuming a button with display: inline-block set:
<span class="on-disabled">
<input id="subm_tc" class="btn btn-primary" type="submit" disabled value="Log in" name="Submit">
</span>
Define you click event for the case of the button being disabled:
$('.on-disabled').click(function (ev) {
// Don’t react to click events bubbling up
if (ev.target !== ev.currentTarget) return;
// Do your thing
alert('Sorry, this button is disabled');
});
And simply style the button like:
#subm_tc {
display: inline-block;
}
#subm_tc[disabled] {
position: relative;
z-index: -1;
}
This allows you to easily react to a click even in case of a disabled button.
See FIDDLE.
If you use Twitter Bootstrap, they give you a class disabled that provides the styling but doesn't remove the click event. Given that, what I did was this (keep in mind also, I wanted to be sure that when the button was no longer disabled, the original click event did fire, and I didn't want to deal with unbinding, rebinding it).
function disableButton(btn, message) {
btn.addClass("disabled")
if (!(message == null || message == "")) {
btn.data("message", message)
}
}
function enableButton(btn) {
btn.removeClass("disabled")
}
$("#btn").click(function() {
if (!($(this).hasClass("disabled"))) {
// original, desired action
} else {
message = $(this).data("message")
if (!(message == null || message == "")) {
alert(message)
}
}
})
2022 Update: I know this is an old question, but here's an update after evaluating various solutions, including CSS position:absolute and pointer-events:none
The disadvantage of simulating the disabled look ("Pretend Disable") was that, back then, various browsers presented disabled elements differently. That's not as true today because Chrome, Edge, Firefox, and other modern browsers, implement disabled button inputs (and likely other inputs) with the equivalent of opacity .5 .
The solution below is inspired by https://css-tricks.com/making-disabled-buttons-more-inclusive which uses the aria-disabled attribute in place of the older disabled attribute. That article strongly advised against using CSS techniques such as position:absolute and pointer-events:none, because when disabled, the input (or underlying/overlying element) cannot receive focus preventing the possibility of an automatic tooltip when tabbed to and preventing a screen reader from announcing the element is disabled.
Accessible Rich Internet Applications (ARIA) is a set of attributes that define ways to make web content and web applications (especially those developed with JavaScript) more accessible to people with disabilities.
HTML:
<input type='button' id='toggle' value='Toggle'>
<input type='button' id='theButton' value='Button'>
<div id='clicksReport'></div>
Plain JavaScript:
document.querySelector('#theButton').onclick = function () {
if (document.querySelector('#theButton').ariaDisabled)
{
// Your disabled button code (if any)
document.querySelector('#clicksReport').insertAdjacentHTML("beforeend",'|Disabled Button Clicked|<br>');
}
else
{
// Your emabled button code
document.querySelector('#clicksReport').insertAdjacentHTML("beforeend",'|ENABLED button clicked|<br>');
}
}
document.querySelector('#toggle').onclick = function() {
if (document.querySelector('#theButton').ariaDisabled)
{
// If not a button input, also remove the readOnly attribute
var el = document.querySelector('#theButton');
el.ariaDisabled = null;
el.style.opacity = null;
}
else
{
// If not a button input, also set the readOnly attribute
var el = document.querySelector('#theButton');
el.ariaDisabled = true;
el.style.opacity = '.5';
}
}
JS Fiddle: https://jsfiddle.net/SKisby/3Lna8q7h/7/
The same in d3 (as that's what I'm currenlty using and it's similar to jQuery):
d3.select('#theButton').on('click',function () {
if (d3.select('#theButton').attr('aria-disabled'))
{
// Your disabled button code (if any)
d3.select('#clicksReport').node().insertAdjacentHTML("beforeend",'|Disabled Button Clicked|<br>');
}
else
{
// Your emabled button code
d3.select('#clicksReport').node().insertAdjacentHTML("beforeend",'|ENABLED button clicked|<br>');
}
});
d3.select('#toggle').on('click',function() {
if (d3.select('#theButton').attr('aria-disabled'))
{
// If not a button input, also remove the readOnly attribute
d3.select('#theButton').attr('aria-disabled',null)
.style('opacity',null);
}
else
{
// If not a button input, also set the readOnly attribute
d3.select('#theButton').attr('aria-disabled',true)
.style('opacity','.5');
}
});
d3 Fiddle: https://jsfiddle.net/SKisby/qkvf3opL/2/
The above are simple, both have the same disabled look in Chrome, Firefox, and other modern browsers, and have the benefits of being able to receive focus (where an automatic tooltip could then be implemented and ARIA screen readers can convey the element is effectively disabled).
If the input is not a button, also set and remove the readOnly attribute.

Javascript: Changing variable on button click

I have a javascript file linked to index.html like below:
<script src='game.js' type='text/javascript'>
</script>
Assume that game.js contains:
var speed = ...;
Along with some other content.
I have 3 buttons on the HTML page that when clicked I want to change the variable speed in the javascript. Once clicked I want all 3 buttons to be disabled or hidden until the reset button is clicked. Any idea how I go about this?
Using pure HTML/JavaScript, here's what I would do:
<form name="form1">
<span id="buttons">
<input type="button" name="button1" value="Speed1"/>
<input type="button" name="button2" value="Speed2"/>
<input type="button" name="button3" value="Speed3"/>
</span>
<input name="reset" type="reset"/>
</form>
<script type="text/javascript">
var speed, buttonsDiv=document.getElementById("buttons");
for (var i=1; i<=3; i++) {
var button = document.form1["button" + i];
button.onclick = function() {
speed = this.value;
alert("OK: speed=" + speed);
buttonsDiv.style.display = 'none';
};
}
document.form1.reset.onclick = function() {
speed = null;
alert("Speed reset!");
buttonsDiv.style.display = 'inline';
return true;
};
</script>
Here is a working example: http://jsfiddle.net/maerics/TnTuD/
Create functions within your javascript files that attach to the click events of each button.
The functions would change the variable you want.
aButtonelement.addEventListener('click',functionToChangeVariable,false)
Include the following in your Javascript file:
function DisableButtons() {
speed = 100;
document.getElementById("btn_1").disabled = true;
document.getElementById("btn_2").disabled = true;
document.getElementById("btn_3").disabled = true;
}
function EnableButtons() {
document.getElementById("btn_1").disabled = false;
document.getElementById("btn_2").disabled = false;
document.getElementById("btn_3").disabled = false;
}
In your HTML, assign the following onClick events:
<button onClick="DisableButtons();">Button 1</button>
<button onClick="DisableButtons();">Button 2</button>
<button onClick="DisableButtons();">Button 3</button>
<button onClick="EnableButtons();">Reset</button>
something like this? http://jsfiddle.net/qMRmn/
Basically, speed is a global variable, and clicking a button with the class set-speed class will set the speed to a new value, and disable all of the set-speed buttons. Clicking the reset button will re-enable them.
The code should be fairly self explanatory.
Easiest way, use jQuery.
$("#idofbutton").click(function () {
// change variables here
});
Or you could register an event:
document.getElementById("idofbutton").addEventListener('click', function () {
// change variables here
}, false);
Source

properly disabling the submit button

this is the code that I use to disable the button
$("#btnSubmit").attr('disabled', 'disabled')
$("#btnSubmit").disabled = true;
and this is my submit button
<input id="btnSubmit" class="grayButtonBlueText" type="submit" value="Submit" />
the button although looks disabled, you can still click on it.. This is tested with FF 3.0 and IE6
Am I doing something wrong here?
If it's a real form, ie not javascript event handled, this should work.
If you're handling the button with an onClick event, you'll find it probably still triggers. If you are doing that, you'll do better just to set a variable in your JS like buttonDisabled and check that var when you handle the onClick event.
Otherwise try
$(yourButton).attr("disabled", "true");
And if after all of that, you're still getting nowhere, you can manually "break" the button using jquery (this is getting serious now):
$(submitButton).click(function(ev) {
ev.stopPropagation();
ev.preventDefault();
});
That should stop the button acting like a button.
Depending on how the form submission is handled you might also need to remove any click handlers and/or add one that aborts the submission.
$('#btnSubmit').unbind('click').click( function() { return false; } );
You'd have to add the click handler's again when (if) you re-enable the button.
You need to process Back/Prev button into browser.
Example bellow
1) Create form.js:
(function($) {
$.enhanceFormsBehaviour = function() {
$('form').enhanceBehaviour();
}
$.fn.enhanceBehaviour = function() {
return this.each(function() {
var submits = $(this).find(':submit');
submits.click(function() {
var hidden = document.createElement('input');
hidden.type = 'hidden';
hidden.name = this.name;
hidden.value = this.value;
this.parentNode.insertBefore(hidden, this)
});
$(this).submit(function() {
submits.attr("disabled", "disabled");
});
$(window).unload(function() {
submits.removeAttr("disabled");
})
});
}
})(jQuery);
2) Add to your HTML:
<script type="text/javascript">
$(document).ready(function(){
$('#contact_frm ).enhanceBehaviour();
});
</script>
<form id="contact_frm" method="post" action="/contact">
<input type="submit" value="Send" name="doSend" />
</form>
Done :)

Categories

Resources