How do I run a animation on every input change? - javascript

I'm working on a animation that appears if you interact with some input elements. On a input change event, the script adds the class highlight and removes it after a delay of 1 second.
The problem is, If I switch the radio buttons faster than 1 second the animation does not work. What options do I have to run the animation on every input change?
$(':radio[name="group1"], :radio[name="group2"]').on('change', function(e) {
$('#' + this.getAttribute('name') + ' .selected').text(this.value);
});
//
// This to get the checked radios
//
$(':radio[name="group1"]:checked, :radio[name="group2"]:checked').trigger('change');
$("div").bind('DOMNodeInserted DOMNodeRemoved', function() {
$(this).addClass('highlight').delay(1000).queue(function(next){
$(this).removeClass("highlight");
next();
});
});
input{
display: none;
}
label{
display: inline-block;
width:20%;
cursor: pointer;
padding: 20px;
margin: 10px;
background: #eee;
color: #111;
}
input:checked + label{
background: #111;
color: #fff;
}
div{
background: #eee;
color: #111;
padding: 10px;
margin: 4px;
}
div span{
display: block;
margin: 4px;
}
.title{
font-weight: bold;
}
div.highlight {
-webkit-animation: highlight 1s infinite;
-moz-animation: highlight 1s;
-o-animation: highlight 1s;
animation: highlight 1s;
}
#-webkit-keyframes highlight {
from {background-color: #0099cc;}
to {background-color: none;}
}
#-moz-keyframes highlight {
from {background-color: #0099cc;}
to {background-color: none;}
}
#-o-keyframes highlight {
from {background-color: #0099cc;}
to {background-color: none;}
}
#keyframes highlight {
from {background-color: #0099cc;}
to {background-color: none;}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="a" type="radio" name="group1" value="Description group1 1" checked>
<label for="a">Group1 Radio1</label>
<input id="b" type="radio" name="group1" value="Description group1 2">
<label for="b">Group1 Radio2</label>
<input id="c" type="radio" name="group1" value="Description group1 3">
<label for="c">Group1 Radio3</label>
<input id="d" type="radio" name="group2" value="Description group2 1" checked>
<label for="d">Group2 Radio1</label>
<input id="e" type="radio" name="group2" value="Description group2 2">
<label for="e">Group2 Radio2</label>
<input id="f" type="radio" name="group2" value="Description group2 3">
<label for="f">Group2 Radio3</label>
<!-- Output value here -->
<div id="group1">
<span class="title">Group1</span>
<span class="selected"></span>
</div>
<div id="group2">
<span class="title">Group2</span>
<span class="selected"></span>
</div>

Queue them in the opposite direction:
$("div").bind('DOMNodeInserted DOMNodeRemoved', function() {
$(this).removeClass('highlight').delay(10).queue(function(next) {
$(this).addClass("highlight");
next();
});
});
(and set animetion loop to once)

Related

Within a radio-group, how to add and remove class names at radio button parents when checking/unchecking takes place?

I am trying to add a class to the radio button parent element when checked.
The problem is, the class doesn't seem to delete when using removeClass. I can still see the red background when the checkbox is unchecked.
This is what I came up with so far ...
$('input:radio').change(function () {
if($(this).is(':checked')) {
$(this).parent().addClass('selected');
} else {
$(this).parent().removeClass('selected');
}
});
.selected {
background-color: #fff5f5;
color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>Select a maintenance drone:</p>
<div class="">
<input type="radio" id="huey" name="drone" value="huey"
checked>
<label for="huey">Huey</label>
</div>
<div class="">
<input type="radio" id="dewey" name="drone" value="dewey">
<label for="dewey">Dewey</label>
</div>
<div class="">
<input type="radio" id="louie" name="drone" value="louie">
<label for="louie">Louie</label>
</div>
How do I need to change my code in order to achieve the correct behavior?
No need to check else part in the is(':checked') condition.
On click of radio button;
Firstly, perform removeClass() from all radio button.
Then, addClass() only to the respective checked parent element.
$('input:radio').change(function(){
$('input:radio[name=' + this.name + ']').parent().removeClass('selected'); //remove class "selected" from all radio button with respective name
$(this).parent().addClass('selected'); //add "selected" class only to the checked radio button
});
input[type="radio"] + label {
cursor: pointer;
display: block;
height: 40px;
width: 200px;
text-align: center;
line-height: 40px;
}
.selected {
background-color: #fff5f5;
color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<p>Select a maintenance drone:</p>
<div class="">
<input type="radio" id="huey" name="drone" value="huey">
<label for="huey">Huey</label>
</div>
<div class="">
<input type="radio" id="dewey" name="drone" value="dewey">
<label for="dewey">Dewey</label>
</div>
<div class="">
<input type="radio" id="louie" name="drone" value="louie">
<label for="louie">Louie</label>
</div>
First remove all classes of parents, then add class to parent of selected one.
$('input[type=radio]').change(function() {
$('input[type=radio]').each(function() {
$(this).parent().removeClass('selected');
});
$(this).parent().addClass('selected');
});
.selected {
background-color: #fff5f5;
color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>Select a maintenance drone:</p>
<div class="">
<input type="radio" id="huey" name="drone" value="huey" checked>
<label for="huey">Huey</label>
</div>
<div class="">
<input type="radio" id="dewey" name="drone" value="dewey">
<label for="dewey">Dewey</label>
</div>
<div class="">
<input type="radio" id="louie" name="drone" value="louie">
<label for="louie">Louie</label>
</div>
you can solve it with only css
input[type="radio"] ~ label {
cursor: pointer;
display: block;
height: 40px;
width: 200px;
text-align: center;
line-height: 40px;
}
input[type="radio"] {
position: absolute;
}
input[type="radio"]:checked ~ label {
background-color: #fff5f5;
color: red;
}
This is a "fat free, valid HTML and CSS only" variant with a slightly improved semantic structure ...
.radio-group label,
.radio-group .content {
display: block;
position: relative;
}
.radio-group label {
cursor: pointer;
}
.radio-group label:hover {
background-color: #fffbfb;
}
.radio-group .content {
z-index: 0;
padding: 1.3em 8px 8px 24px;
margin: -1.3em 0 0 0;
}
.radio-group .label,
.radio-group [type="radio"] {
position: relative;
z-index: 1;
}
.radio-group [type="radio"] {
top: 1px;
}
.radio-group [type="radio"]:checked ~ span {
color: red;
}
.radio-group [type="radio"]:checked ~ .content {
background-color: #fff5f5;
}
<fieldset class="radio-group">
<legend>Select a maintenance drone:</legend>
<label>
<input type="radio" name="drone" value="huey"/>
<span class="label">Huey</span>
<span class="content">... more phrasing content ...</span>
</label>
<label>
<input type="radio" name="drone" value="dewey"/>
<span class="label">Dewey</span>
<span class="content">... more phrasing content ...</span>
</label>
<label>
<input type="radio" name="drone" value="louie"/>
<span class="label">Louie</span>
<span class="content">... more phrasing content ...</span>
</label>
</fieldset>
This works fine
$('input:radio').change(function(){
$('input:radio').parent().removeClass('selected'); // Remove the class from every element
$(this).parent().addClass('selected'); // Add calss to the clicked element
});
.selected {
background-color: #fff5f5;
color: red;
}
<html>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body>
<div class="">
<input type="radio" id="huey" name="drone" value="huey"
checked />
<label for="huey">Huey</label>
</div>
<div class="">
<input type="radio" id="dewey" name="drone" value="dewey" />
<label for="dewey">Dewey</label>
</div>
<div class="">
<input type="radio" id="louie" name="drone" value="louie" />
<label for="louie">Louie</label>
</div>
</body>

How to add border to label when radio button is selected

<label for="seeker" class="checkbox">
I am a Job Seeker
<input type="radio" id="seeker" name="designation">
</label>
<label for="employer" class="checkbox">
I am an Employer
<input type="radio" id="employer" name="designation">
</label>
I have multiple HTML radio inputs which are wrapped around labels (https://i.imgur.com/GLdqodq.png) when a radio is selected for say input name "designation" I'd like to add a border color to the label of the radio button that was selected and remove the border from the other labels (https://i.imgur.com/LOMlBUP.png), here's the the JS code I tried using but for some reason when a radio button is unchecked JS can't seem to detect the event.
const radios = document.querySelectorAll('.checkbox input')
radios.forEach((radio) => {
radio.addEventListener('change', e => {
if (e.target.checked) {
// logic to add label border
} else {
// logic to remove label border
}
})
})
I know this can be done using the CSS plus (+) operator but seems like that would require the label to preceded the input, something I wouldn't want to do. However I'm open to using a CSS method as long as the markup wouldn't have to be changed.
const inputs= document.body.querySelectorAll("input")
document.addEventListener("change", (e)=>{
inputs.forEach(input=>{
if(input.checked){
input.labels[0].style="border-style: solid; padding: 10px;"
}
if(!input.checked){
input.labels[0].style=""
}
})
})
here is the js logic
You can also try this code snippet. I have also provided the required styling if you want.
document.querySelector(".first-checkbox").addEventListener('click', function(){
document.querySelector(".first-checkbox").classList.add("active");
document.querySelector(".second-checkbox").classList.remove("active");
})
document.querySelector(".second-checkbox").addEventListener('click', function(){
document.querySelector(".second-checkbox").classList.add("active");
document.querySelector(".first-checkbox").classList.remove("active");
})
.first-checkbox,.second-checkbox{
border:1px solid #D3D3D3;
border-radius:5px;
padding:5px;
}
.checkbox-container{
width:80%;
display:flex;
justify-content:space-around;
padding:20px;
border:1px solid #C0C0C0;
border-radius:5px;
}
.active{
border:1px solid black;
border-radius:5px;
padding:5px;
}
<div class="checkbox-container">
<label for="seeker" class="first-checkbox">
I am a Job Seeker
<input type="radio" id="seeker" name="designation">
</label>
<label for="employer" class="second-checkbox">
I am an Employer
<input type="radio" id="employer" name="designation">
</label>
</div>
You can simply do it css using input:checked selector
Take an example from below code and codepen link https://codepen.io/naren-irain/pen/XWXWWqq
.radiobox {
display: inline-block;
cursor: pointer;
user-select: none;
}
.radiobox input {
position: absolute;
opacity: 0;
}
.radiobox .check {
background: #fff;
border: 1px solid #979797;
border-radius: 50%;
display: inline-block;
width: 16px;
height: 16px;
position: relative;
top: 1px;
margin-right: 5px;
vertical-align: top;
}
.radiobox span, .radioTab span, .checkbox span {
display: inline-block;
vertical-align: top;
}
.radiobox .check i,
.radioTab .check i {
background: #0db837;
border-radius: 50%;
display: block;
width: 10px;
height: 10px;
position: absolute;
top: 50%;
left: 50%;
margin: -5px 0 0 -5px;
opacity: 0;
transform: scale(0.75);
transition: all 0.3s;
}
.radiobox input:checked+.check,
.radioTab input:checked+ span .check {
border-color: #5cb85c;
}
.radiobox input:checked+.check i,
.radioTab input:checked+ span .check i {
opacity: 1;
transform: scale(1);
}
<h4>Select any one option</h4>
<label class="radiobox" for="one">
<input type="radio" id="one" name="designation" value="one" />
<span class="check"><i></i></span>
<span>This is one option</span>
</label>
<br/>
<br/>
<label class="radiobox" for="two">
<input type="radio" id="two" name="designation" value="two" />
<span class="check"><i></i></span>
<span>Never think this is an option</span>
</label>

Reset CSS Stars from Javascript

I have the following code, which allows a user to select a rating value and this works without issue. On the first selection, all stars are grey.
However if a user goes and rates a second thing, it doesn't retain the value but it does retain the previous number of yellow stars.
How do I reset it so no stars are yellow - I'm looking for a Javascript solution to this.
var rating = {}
function rate(value) {
rating.starValue = Number(value);
}
.stars,
.stars label::before
{
display: inline-block;
}
.stars label:hover,
.stars label:hover ~ label
{
color: #b5cebe;
}
.stars input
{
display: none;
}
.stars
{
direction: rtl;
}
.stars label
{
color: #ccc;
}
.stars label::before
{
content: "\2605";
width: 18px;
line-height: 18px;
text-align: center;
font-size: 50px;
padding: 25px;
cursor: pointer;
}
.stars input:checked ~ label
{
color: #f5b301;
}
<div class="stars">
<input type="radio" name="stars-1" id="stars-1-0" value="5" onclick="rate(this.value)"/><label for="stars-1-0"></label><!--
--><input type="radio" name="stars-1" id="stars-1-1" value="4" onclick="rate(this.value)"/><label for="stars-1-1"></label><!--
--><input type="radio" name="stars-1" id="stars-1-2" value="3" onclick="rate(this.value)"/><label for="stars-1-2"></label><!--
--><input type="radio" name="stars-1" id="stars-1-3" value="2" onclick="rate(this.value)"/><label for="stars-1-3"></label><!--
--><input type="radio" name="stars-1" id="stars-1-4" value="1" onclick="rate(this.value)"/><label for="stars-1-4"></label>
</div>
Edit: Before folks down vote this (presumably because they think I've not attempted to resolve this on my own), I've been trying to figure this out for over an hour, the primary issue I have is I can't figure out which DOM selector to use. As I've been hammering on this for over an hour, then I have no concise way of putting all the combinations that I've tried
You need to figure out how do you want to reset the radio button set i.e may be you have a reset button or you can toggle between the selected and unselected states.
Below is the code to just reset the radio buttons assuming an event for reset action.
var ratings = document.getElementsByName('stars-1');
ratings.forEach(function(element)
{
element.checked=false
})
There you go :)
querySelectorAll Link
var rating = {}
function rate(value) {
rating.starValue = Number(value);
}
function reset() {
var elements = document.querySelectorAll('.stars input[name=stars-1]');
elements.forEach(function(element) {
element.checked = false;
});
rating = {}
}
.stars,
.stars label::before
{
display: inline-block;
}
.stars label:hover,
.stars label:hover ~ label
{
color: #b5cebe;
}
.stars input
{
display: none;
}
.stars
{
direction: rtl;
}
.stars label
{
color: #ccc;
}
.stars label::before
{
content: "\2605";
width: 18px;
line-height: 18px;
text-align: center;
font-size: 50px;
padding: 25px;
cursor: pointer;
}
.stars input:checked ~ label
{
color: #f5b301;
}
<div class="stars">
<input type="radio" name="stars-1" id="stars-1-0" value="5" onclick="rate(this.value)"/><label for="stars-1-0"></label><!--
--><input type="radio" name="stars-1" id="stars-1-1" value="4" onclick="rate(this.value)"/><label for="stars-1-1"></label><!--
--><input type="radio" name="stars-1" id="stars-1-2" value="3" onclick="rate(this.value)"/><label for="stars-1-2"></label><!--
--><input type="radio" name="stars-1" id="stars-1-3" value="2" onclick="rate(this.value)"/><label for="stars-1-3"></label><!--
--><input type="radio" name="stars-1" id="stars-1-4" value="1" onclick="rate(this.value)"/><label for="stars-1-4"></label>
</div>
<input type='button' onclick='reset()' value='reset'>

How to disable other image when 2 image select out of 5?

In my website i want to add one feature to disable other image when user select 2 images.
In my website, i have 5 images. Form this 5 image user select max 2 no. of images.
When user select 2 images other 3 images are disable automatically.
See my demo on snippet.This is your answer, Hopefully it sends you in the right direction. Change js according to your need.Here I set length maximum 2.
if (+$("input[name=ItemGrp2]:checked").length > 2)
Use this code.
$( ".two" ).on( "change", function() {
if (+$("input[name=ItemGrp2]:checked").length > 2)
{
this.checked=false;
}
});
ul {
list-style-type: none;
}
li {
display: inline-block;
}
input[type="checkbox"][id^="cb"] {
display: none;
}
label {
border: 1px solid #fff;
padding: 10px;
display: block;
position: relative;
margin: 10px;
cursor: pointer;
}
label:before {
background-color: white;
color: white;
content: " ";
display: block;
border-radius: 50%;
border: 1px solid grey;
position: absolute;
top: -5px;
left: -5px;
width: 25px;
height: 25px;
text-align: center;
line-height: 28px;
transition-duration: 0.4s;
transform: scale(0);
}
label img {
height: 100px;
width: 100px;
transition-duration: 0.2s;
transform-origin: 50% 50%;
}
:checked + label {
border-color: #ddd;
}
:checked + label:before {
content: "✓";
background-color: grey;
transform: scale(1);
}
:checked + label img {
transform: scale(0.9);
box-shadow: 0 0 5px #333;
z-index: -1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<ul>
<li><input class="two" name="ItemGrp2" type="checkbox" id="cb1" />
<label for="cb1"><img src="http://lorempixel.com/100/100" /></label>
</li>
<li><input class="two" name="ItemGrp2" type="checkbox" id="cb2" />
<label for="cb2"><img src="http://lorempixel.com/101/101" /></label>
</li>
<li><input class="two" name="ItemGrp2" type="checkbox" id="cb3" />
<label for="cb3"><img src="http://lorempixel.com/102/102" /></label>
</li>
<li><input class="two" name="ItemGrp2" type="checkbox" id="cb4" />
<label for="cb4"><img src="http://lorempixel.com/103/103" /></label>
</li>
</ul>
var $form = $('.form');
var $imgInputs = $form.find('.img-cb');
$imgInputs.on('change', function () {
var isMaxSelected = ($imgInputs.filter(':checked').length >= 2);
$imgInputs.not(':checked').prop('disabled', isMaxSelected);
});
.img-cb {
display: block;
position: absolute;
opacity: 0;
}
.img-cb:disabled + img {
opacity: 0.3;
}
.img-cb:checked + img {
outline: 1px solid red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-2.1.4.js"></script>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<form action="" class="form">
<label>
<input class="img-cb" type="checkbox">
<img src="http://placehold.it/150" alt="">
</label>
<label>
<input class="img-cb" type="checkbox">
<img src="http://placehold.it/150" alt="">
</label>
<label>
<input class="img-cb" type="checkbox">
<img src="http://placehold.it/150" alt="">
</label>
<label>
<input class="img-cb" type="checkbox">
<img src="http://placehold.it/150" alt="">
</label>
<label>
<input class="img-cb" type="checkbox">
<img src="http://placehold.it/150" alt="">
</label>
</form>
</body>
</html>
Create an event listener which increments a counter initialized to zero upon clicking an image, but only if the counter is not >=2. Also push the ids of the photos clicked (the object is passed along the event anyway)
If counter reaches 2, use jQuery/ native Javascript to hide the photos not in the id list. (This would require a continuous sequence of ids to be given to the photos and also knowledge of # of photos, which in this case is assumed to be 5 and never change dynamically)

"X" check box with an input box

I am attempting to create a check box with an X instead of a check using an input box. However, some I want to work as a radio button (when you click one, the other's get "un-checked").
Basically, a group of three check boxes that only allows 1 box to have the check in it at a time.
Does anyone know an easy way to accomplish the radio button-esq approach to this without creating a specific function for each group of check box's?
HTML
<input name="box1" id="box1" class="checkBox" value="" readonly="readonly" onclick="return checkBox('box1')">
CSS
.checkBox { background-color:#fff; margin: 0; border: 0; padding: 0; border:1px solid #000; text-align: center; cursor: default;font-family: 'Arial Narrow', Arial, sans-serif;font-size:11px;font-weight:bold;width:1.1em;height:1.1em; }
Function
function checkBox(box) {
x = document.getElementById(box).value;
document.getElementById(box).value = (x == "X") ? "" : "X";
}
You can use custom radio buttons (css only) that looks like checkbox (Demo on jsBin and Demo on jsFiddle)
CSS:
div.radios > label > input {
visibility: hidden;
}
div.radios > label {
display: inline-block;
margin: 0 0 0 -10px;
padding: 0 0 10px 0;
height: 20px;
cursor:pointer;
}
div.radios > label > img {
display: inline-block;
padding: 0px;
height:20px;
width:20px;
background: none;
vertical-align:top;
}
div.radios > label > input:checked +img {
background: url(https://cdn2.iconfinder.com/data/icons/picons-essentials/71/no-24.png);
background-repeat: no-repeat;
background-position:center center;
background-size:20px 20px;
}
HTML:
<div class='radios'>
<label title="item1">
<input type="radio" name="foo" value="0" /> <img /> Radio One
</label>
<label title="item2">
<input type="radio" name="foo" value="1" /> <img /> Radio Two
</label>
</div>
You can give the radio group an identifier class, for instance "radio" and onclick reset them and set val of the clicked one. A jquery sample would be
<input class="checkBox radio" value="" readonly="readonly">
<input class="checkBox radio" value="" readonly="readonly">
<input class="checkBox radio" value="" readonly="readonly">
$(".radio").click(function() {
$(".radio").val('');
$(this).val('X');
});
For a pure CSS solution (that actually validates), you could use something like:
<input id="rd1" type="radio" name="opt" /><label for="rd1"></label>
<input id="rd2" type="radio" name="opt" /><label for="rd2"></label>
<input id="rd3" type="radio" name="opt" /><label for="rd3"></label>
And this is the CSS for it:
.radio-special {
display: none;
}
.radio-special + label {
background: #ddd;
height:24px;
width: 24px;
box-shadow: inset 0 0 2px 2px #aaa;
display: inline-block;
}
.radio-special:checked + label {
background: url('https://cdn1.iconfinder.com/data/icons/30_Free_Black_ToolBar_Icons/20/Black_Remove.png') #ddd no-repeat 2px 2px;
}
Note that this will still look a bit weird in the html side of it, but at least its valid markup.
Check how that displays on older versions of IE. It works fine on IE10.
Fiddle
Thanks for everyone's help! I've taken everyone's advice and decided to use a custom image radio/check box through css.
This method will not work for IE7/8 because of the :checked attribute but all you need to do is use selectivizr and everything should run smoothly.
HTML
<input id="option_1" name="option1" type="radio">
<label for="option_1">Option 1</label>
<input id="option_2" name="option2" type="radio">
<label for="option_2">Option 2</label>
<input id="option_3" name="option3" type="radio">
<label for="option_3">Option 3</label>
CSS
input[type='checkbox'], input[type='radio'] { opacity: 0; float: left; width: 14px; }
input[type='radio'] + label, input[type='checkbox'] + label {
margin: 0;
margin-right:-10px; /* Position between the box+label */
clear: none;
padding: 1px 1px 1px 20px; /* Position of the box+label */
cursor: pointer;
background: url('emptyBox.png') left center no-repeat;
float:left;
}
input[type='radio']:checked + label, input[type='checkbox']:checked + label {
background-image: url('selectedBox.png');
}

Categories

Resources