I have 12 <a> tags and they are linked to image. What i want to do is to connect all of them in one if as a .clicked == true. For some reason it does not work so here i am with another question.
A sample of my <a> tag.
<div id="container">
<div id="slider">
</div>
<div id="wypelniacz">
<img style="top: 22%; right: 60%;" alt="" src="greenapple.png" class="apl" id="apple1" onclick="imageSwap(1) ; this.onclick=null;">
</div>
</div>
JS
function imageSwap(id)
{
document.getElementById("apple" + id).src = "redapple.png";
}
To make it easier to explain i have posted a picture of what am i doing.
When apple is not clicked it remains green, but when i click on it, it will change to red.
Then, when all 12apples are red the whole div copntent will be deleted and swapped for one image. How can i possibly do that? Thanks in advance!
So add a class for attribute and check how many you have
function imageSwap(id) {
var img = document.getElementById("apple" + id);
img.src = "redapple.png";
img.classList.add("selected");
var count = document.querSelectorAll(".selected").length;
console.log(count);
}
or just with html and css
document.querySelector(".tree").addEventListener("change", function(evt) {
const checked = document.querySelectorAll(".apple:checked").length;
console.log(checked);
console.log(evt.target.form.checkValidity());
});
.apple {
display: none;
}
.apple + label {
display: inline-block;
width: 100px;
height: 100px;
background-image: url(http://placekitten.com/g/100/100);
}
.apple:checked + label {
background-image: url(http://placekitten.com/100/100);
}
<form class="tree">
<input type="checkbox" class="apple" id="apple1" required><label for="apple1"></label>
<input type="checkbox" class="apple" id="apple2" required><label for="apple2"></label>
<input type="checkbox" class="apple" id="apple3" required><label for="apple3"></label>
<input type="checkbox" class="apple" id="apple4" required><label for="apple4"></label>
<input type="checkbox" class="apple" id="apple5" required><label for="apple5"></label>
<button>Next</button>
</form>
Use event delegation, that is I attach a click event to '.container', and use 'event.target' to manipulate the target apple
toggle target apple class to switch background-color
check all apples, if there is no '.red', then switch to a new image(Here I just remove the '.red' class all)
document.addEventListener('DOMContentLoaded', ev => {
const apples = [...document.querySelectorAll('.apple')]
const container = document.querySelector('.container')
container.addEventListener('click', ev => {
if (ev.target.matches('.apple')) {
ev.preventDefault()
ev.target.classList.toggle('red')
const apples = [...container.querySelectorAll('.apple')]
if (apples.every(apple => apple.classList.contains('red'))) {
apples.forEach(apple => apple.classList.remove('red'))
}
}
})
}, false)
div {
display: flex;
flex-flow: row wrap;
justify-content: space-evenly;
align-items: center;
}
.apple {
width: 5rem;
height: 5rem;
border-radius: 5rem;
background: green;
}
.green {
background: green;
}
.red {
background: red;
}
<div class="container">
</div>
Related
I'm sure this is an amateur question, but I am having difficulty figuring out how to dynamically add html items to the right(same horizontal level) inside of my div. When I add a new Label it adds below the previous label I added. How do I place the new Label to the right of the previous label I added to my webpage?
My javascript:
<script>
$(document).ready(function(){
$("#comp").click(function (e){
event.preventDefault()
$('#items').append('<label>My Label</label>+
'<input>'+
'<br>'+
'<label>Second Label</label>');
});
});
</script>
My html:
<div id = "items">
</div>
<input type="button", name = "comp" value = "Compare" id="comp"></input>
I had to alter your HTML to be standard to demonstrate, but the answer is use display:inline-block as a style on the added label
$("#comp").click(function(e) {
event.preventDefault()
const item = '<label>My Label</label> <input> <br> <label>Second Label</label>';
$('#items').append('<div class="newitem">' + item + ' </div>');
});
#items .newitem {
display: inline-block;
padding: 3px;
margin: 0 3px 3px 0;
border: 1px solid #ccc;
border-radius: 4px;
}
#items .newitem input {
width: 25px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="items">
</div>
<input type="button" name="comp" value="Compare" id="comp" />
You need to change the styling to inline. Either change from a div to a span or, add change the div to <div style="display: inline"></div>
Add a display of flex to #items, then you can add margin on label or gap on #items. With flex you can also control justify-content prop as well...
$(document).ready(function() {
$("#comp").click(function(e) {
event.preventDefault()
$('#items').append('<label>My Label</label>');
});
});
#items {
display: flex;
justify-content: start;
/* gap: 1rem; <-- alternative */
}
label {
margin-right: 1rem;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="items">
</div>
<input type="button" , name="comp" value="Compare" id="comp">
There are 5 boxes, which can be changed from 'white'<->'yellow' colors by mouse events (mouseover, mouseout and click). There is also a blue area with text displaying the level of the clicked box.
After clicking into the third box, I got 'hard level' text in blue area and 3 boxes color in yellow.
What I need is to return it to the default level ('easy level' and first box in yellow only) by clicking the reset button.
I have been trying do this like this , but it isn't working:
resetBtn = document.querySelector('#update');
and eventlistener:
resetBtn.addEventListener('click', highlightStars(`#star1`), true)
Here is an example:
window.addEventListener('DOMContentLoaded', changeStars, false);
const resetBtn = document.querySelector('#update');
/* Change level of the game depending on user choice */
function changeStars() {
/* Displaying level text inside blue box */
const updateAltText = currentLevelIndex => {
let levelText = document.querySelector('#level-text');
/* 'currentLevelIndex + 1' replaces event 'currentElement' */
levelText.textContent = document.querySelector(`#star${currentLevelIndex + 1}`).alt;
}
/* Captcha level number - default is 1 */
const getNumber = str => Number(str.match(/\d+/)[0]) || 1;
/* Star index is always one number lower than level number (indexing rules) */
const getStarIndex = event => getNumber(event.target.id) - 1;
let stars = document.querySelectorAll('.star');
const handleStarClick = event => {
/* FIRST - blocking possibility to change star behaviour by mouse events */
gameLevel.removeEventListener('mouseover', highlightStars);
gameLevel.removeEventListener('mouseout', highlightStars);
/* SECOND - making all needed star with yellow color */
const stars = document.querySelectorAll('.star');
for (let i = 0; i <= getStarIndex(event); i++) {
stars[i].classList.add('yellow');
}
};
const highlightStars = event => {
const starIndex = getStarIndex(event);
updateAltText(starIndex);
for (let i = 1; i <= starIndex; i++) {
const star = document.querySelector(`#star${i + 1}`);
star.classList.toggle('yellow');
}
};
// resetBtn.addEventListener('click', highlightStars(`#star1`), true);
resetBtn.addEventListener('click', updateAltText(0), true);
const gameLevel = document.querySelector('.game-level');
gameLevel.addEventListener("mouseover", highlightStars);
gameLevel.addEventListener("mouseout", highlightStars);
gameLevel.addEventListener('click', handleStarClick, {once: true});
}
.stars {
display: flex;
margin: 10px auto;
width: 500px;
}
input[type='image'] {
width: 60px;
height: 60px;
border: thin solid black;
}
.yellow {
background-color: yellow;
}
.game-level {
display: flex;
width: 300px;
height: 100%;
}
.level-block {
display: flex;
width: 200px;
margin-left: 10px;
justify-content: center;
align-items: center;
border: 1px solid hsl(217, 86%, 50%);
border-radius: 25px;
background-color: hsl(212, 29%, 80%);
}
.level-block > span {
font-size: 18px;
}
.reset {
width: 80px;
height: 80px;
}
<div class="stars">
<div class="game-level">
<input type="image" class="star yellow" id="star1" src="" width="60" alt="easy level">
<input type="image" class="star" id="star2" src="" width="60" alt="normal level">
<input type="image" class="star" id="star3" src="" width="60" alt="hard level">
<input type="image" class="star" id="star4" src="" width="60" alt="very hard level">
<input type="image" class="star" id="star5" src="" width="60" alt="impossible level">
</div>
<div class="level-block">
<span id="level-text">Easy level</span>
</div>
</div>
<input type="button" class="reset" id="update" value="RESET">
The following demo uses JavaScript for click events only, all mouse events (ie hover) are pure CSS. The reset behavior simply removes .active class on all buttons then adds .active class to the first button. Instead of the first button title being displayed after a reset -- the reset button title: "Game Reset" is displayed, it might be a little confusing for users if there's no confirmation of a reset. Other behavior is included in demo that is logical and consistent such as toggling, hovering to a temporary state and clicking for a persistent state etc. Details are commented in demo.
// Reference the form
const stars = document.forms.stars;
/*
Register the form to the click event -- when a click occurs anywhere on or within the form, callback function twinkle() is
called
*/
stars.onclick = twinkle;
/**
//A -- twinkle passes a reference to the Event Object... (e)
//B1 - Two Event Object properties are used to reference:
The tag the was clicked by user: event.target
The tag registered to the event: event.currentTarget
//B2 - The HTMLFormElement property: .elements collects all form
controls into a Live HTML Collection (aka NodeList)
//C -- ui.star is a Collection of form controls with [name=star]
The brackets [] and spread operator ... converts the
NodeList into an Array
//D -- Reference the message tag. If the clicked tag was the reset
button -- for...of loop iterates through each [name=star]
and removes the class .active from all [name=star]
//E1 - Next add .active class to the default button
//E2 - Set the legend.message text to the value of clicked button
[title] attribute...
~~~~~~~
//F -- ...But if a button.star was clicked, a check to verify if
clicked tag has the .active class -- then a for...of
loop identical to the one described in line D is used to
remove any .active class.
//G -- After there are no .active, the Boolean declared in line F
determines whether the clicked tag gets the .active class
and its [title] attribute displayed or not
*/
function twinkle(e) {
const active = e.target;
const ui = e.currentTarget.elements;
const starZ = [...ui.star];
const msg = document.querySelector(".message");
if (active.matches("#clear")) {
for (let star of starZ) {
star.classList.remove("active");
}
ui.star1.classList.add('active');
msg.textContent = active.title;
} else if (active.matches(".star")) {
let status = active.classList.contains("active");
for (let star of starZ) {
star.classList.remove("active");
}
if (!status) {
active.classList.add("active");
msg.textContent = active.title;
} else {
active.classList.remove("active");
msg.textContent = "";
}
}
return false;
}
:root {
font: 400 small-caps 2.5vw/1 Arial
}
.levels {
display: table;
width: 96%;
height: auto;
border: 1px solid hsl(217, 86%, 50%);
border-radius:4px;
}
.message {
display: table-caption;
width: 40vw;
height: 6vh;
margin: 0 auto 2vh;
padding: 0.5vh 0;
border: 1px solid hsl(217, 86%, 50%);
border-radius: 1.5rem;
background-color: hsla(212, 29%, 80%, 25%);
text-align: center;
font-size: 1.5rem;
color: #0078D7;
}
#clear {
float: right;
transform: rotate(45deg);
padding: 0;
border: none;
background: none;
font-size: 3.5rem;
cursor: pointer;
}
#clear:focus {
outline: 0;
}
/*
Flex is applied to the button.star'S parent tag so the order
property can be utilized.
*/
.flex {
display: flex;
justify-content: space-evenly;
align-items: center;
width: 70vw;
}
.star {
display: table-cell;
position: relative;
width: 16vw;
height: 24vh;
border: thin solid black;
background: #DDD;
font-size: 3.75rem;
text-align: center;
vertical-align: middle;
cursor: pointer;
}
/*
GSC (General Sibling Combinator: ~ ) provides highlighting across
multiple buttons.
Exp. 5 buttons: [-] [-] [X] ~ [>] ~ [>]
*/
.star.active,
.star:hover,
.star.active ~ .star,
.star:hover ~ .star {
background: gold;
}
/*
HTML layout has button.star in reverse order. Applying order to
each button rectifies the order by APPEARING in order while the
HTML structure remains reversed.
*/
#star1 {
order: 1;
border-top-left-radius: 6px;
border-bottom-left-radius: 6px;
}
#star2 {
order: 2;
}
#star3 {
order: 3;
}
#star4 {
order: 4;
}
#star5 {
order: 5;
border-top-right-radius: 6px;
border-bottom-right-radius: 6px;
}
#star1:hover,
#star1.active {
color: #5BC0DE;
}
#star2:hover,
#star2.active {
color: #FF1C8D;
}
#star3:hover,
#star3.active {
color: #00D800;
}
#star4:hover,
#star4.active {
color: #0000D5;
}
#star5:hover,
#star5.active {
color: #D50000;
}
<form id="stars" action="">
<fieldset name="levels" class="levels">
<legend class="message">Novice</legend>
<button id="clear" type="reset" title="Game Reset">🔄</button>
<section class="flex">
<button id="star5" name='star' class="star" title="Master">🟐</button>
<button id="star4" name='star' class="star" title="Expert">🟌</button>
<button id="star3" name='star' class="star" title="Advanced">🟊</button>
<button id="star2" name='star' class="star" title="Intermediate">🟆</button>
<button id="star1" name='star' class="star active" title="Novice">🟂</button>
</section>
</fieldset>
</form>
So basically I have a simple system with a list, where when I choose one item it displays a description and an image binded to that item.
The project: https://jsfiddle.net/jhnjcddh/2/
The problem is that I need to add the text inside my JS, thus If I would want to add any tags like <b></b>; or such I would Incase that text inside there:
map.set(item1, {
desc: '<a href=''>Hello!</a>',
...
});
BUT The outcome of this is the full form so like this:
<a href=''>Hello!</a>
I tried putting it into a var and appending:
var text1 = '<a href=''>Hello!</a>'
map.set(item1, {
desc: text1,
...
});
..but that gives the same outcome.
THE CODE:
// -----------------START OF STYLING ELEMENT-----------------
var btns = document.getElementsByClassName("item");
for (var i = 0; i < btns.length; i++) {
btns[i].addEventListener("click", function() {
var siblings = this.parentNode.childNodes
siblings.forEach(function(element) {
if (element.className){ // && element.className.indexOf('active') !== -1) { // TAKIT: Removed, see suggestion below
if (element.classList.contains('active')) // TAKIT: Suggestion: Easier, and better readability!
element.classList.remove("active");
}
})
this.classList.add("active"); // TAKIT: Suggestion instead of this.className += " active";
});
}
// -----------------END OF STYLING ELEMENT-----------------
// -----------------START OF LOGIC ELEMENT-----------------
const map = new Map();
// register item element as a key and object with corresponding description / image as value
map.set(item1, {
desc: 'text1',
img: 'https://pbs.twimg.com/profile_images/980681269859241984/-4cD6ouV_400x400.jpg'
});
map.set(item2, {
desc: 'some description item2',
img: 'https://78.media.tumblr.com/3d4a916d45190b2a58bec61f491cdb99/tumblr_p84af9767X1qhy6c9o1_500.gif'
});
map.set(item3, {
desc: 'some item3',
img: 'https://cdn.europosters.eu/image/1300/32201.jpg'
});
map.set(item4, {
desc: ' description for item4',
img: 'https://www.scribblefun.com/wp-content/uploads/2018/02/Pusheen-Coloring-Images.png'
});
map.set(item5, {
desc: 'This item5 is cool',
img: 'https://c1-zingpopculture.eb-cdn.com.au/merchandising/images/packshots/855db32a4fc24da2ba2ce821edd2a51e_Large.png'
});
map.set(item6, {
desc: 'item6 displays attitude',
img: 'https://c1-ebgames.eb-cdn.com.au/merchandising/images/packshots/969932eb9d274a57a59daf9e75319929_Medium.png'
});
map.set(item7, {
desc: 'amazing item7 just breathtaking',
img: 'https://images-na.ssl-images-amazon.com/images/I/81GErgo2%2B8L._SY355_.jpg'
});
map.set(item8, {
desc: ' item8 is an interesting conept',
img: 'https://cdn.shopify.com/s/files/1/2012/3849/products/4048862.jpg?v=1505815578'
});
// you can bind on click handler for example
const list = document.querySelectorAll('ol'); // TAKIT: Modified to return multiple elements
list.forEach(function() { // TAKIT: Added to manage the multiple elements
this.addEventListener('click', event => {
// if element that was registered in our map triggered the event
if (map.has(event.target)) {
var wrapper = event.target.closest('.wrapper'); // TAKIT: Get parent wrapper
// change text of description area
wrapper.querySelector('.description').textContent = map.get(event.target).desc; // TAKIT: Modified
// change src of the image
wrapper.querySelector('img').src = map.get(event.target).img; // TAKIT: Modified
}
});
});
// -----------------END OF LOGIC ELEMENT-----------------
body {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
/* containers */
#content-working {
margin: 20px;
}
* {
font-family: Corbel;
}
.wrapper {
border: 1px solid red;
padding: 10px;
display: inline-flex;
justify-content: center;
align-items: center;
}
.image,
.description,
.list {
border: 1px solid #472836;
box-sizing: border-box;
margin: 5px;
}
/* list */
.list {
width: 150px;
height: 250px;
background-color: #9AD2CB;
overflow-y: auto;
overflow-x: hidden;
}
.list ol {
list-style: none;
padding: 0;
margin: 0;
}
.list li {
padding: 5px;
transition: all .3s ease;
}
.list li:nth-child(even) {
background-color: #91f2e6;
width: 100%;
height: 100%;
}
.list li:hover,
.list .active {
cursor: pointer;
color: red;
padding-left: 25px;
}
/* sub-container */
.image,
.description {
width: 150px;
height: 150px;
}
.image {
background-color: #D7EBBA;
}
.image img {
width: 100%;
height: 100%;
}
.description {
background-color: #FEFFBE;
overflow-y: auto;
overflow-x: hidden;
height: 95px;
}
<div id="content-working">
<div class="wrapper">
<div class="list">
<ol>
<li id="item1" class="item">items1</li>
<li id="item2" class="item">items2</li>
<li id="item3" class="item">items3</li>
<li id="item4" class="item">items4</li>
</ol>
</div>
<div class="image-container">
<div class="image">
<img src="https://semantic-ui.com/images/wireframe/image.png" alt="">
</div>
<div class="description">
just a placeholder text for when nothing has been chosen.
</div>
</div>
</div>
<div class="wrapper">
<div class="list">
<ol>
<li id="item5" class="item">items5</li>
<li id="item6" class="item">items6</li>
<li id="item7" class="item">items7</li>
<li id="item8" class="item">items8</li>
</ol>
</div>
<div class="image-container">
<div class="image">
<img src="https://semantic-ui.com/images/wireframe/image.png" alt="">
</div>
<div class="description">
just a placeholder text for when nothing has been chosen.
</div>
</div>
</div>
</div>
What am I doing wrong here? Why isn't this working?
You're setting everything through textContent.
Use innerHTML to allow tags being interpreted.
https://jsfiddle.net/pd6o0zfn/ (items7)
On line 70 of your Jsfiddle :
wrapper.querySelector('.description').textContent = map.get(event.target).desc; // TAKIT: Modified
You need to replace .textContent by .innerHTML as follow to keep your HTML formatting :
wrapper.querySelector('.description').innerHTML = map.get(event.target).desc; // TAKIT: Modified
I have searched other similar questions on here and tried to replicate them, but I am unsure what I am doing wrong.
I am only wanting one checkbox to be able to be checked. I set the limit with limitCal and am checking the siblings.
Anyone see what I am doing wrong?
jQuery.fn.fadeBoolToggle = function (bool) {
return bool ? this.fadeIn(400) : this.fadeOut(400);
}
function packageSelect() {
var limitCal = 1;
$('.calendar-check').on('change', function () {
$(this).parents('.product-wrap:first').find('.checkmark-img').fadeBoolToggle(this.checked);
if ($(this).siblings(':checked').length >= limitCal) {
this.checked = false;
}
$('#next1').fadeBoolToggle($('.product-check:checked').length > 0);
var prods = [];
$('.calendar-check:checked').each(function () { prods.push($(this).val()) });
});
};
packageSelect();
.calendar-check {
display: none;
}
.product-wrap {
width: 100%;
position: relative;
display: block;
}
.checkmark-img {
display: none;
width: 40%;
height: auto;
z-index: 1;
cursor: pointer;
}
.package-check-toggle {
position: relative;
height: 100%;
width: 100%;
display: block;
}
.package-setup {
display: none;
margin: 40px 0;
width: 100%;
}
#calendar-box-wrap {
margin: 20px 0;
}
.calendar-box {
display: inline-block;
vertical-align: top;
width: 25%;
margin: 0 4%;
position: relative;
}
.calendar-selection-img {
width: 100%;
height: auto;
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="calendar-box">
<div class="product-wrap">
<label for="cal-2year" class="package-check-toggle">
<img src="images/calendar-package.png" alt="2-year Photo Gift" class="calendar-selection-img">
<img src="images/checkmark-circle.png" class="checkmark-img total-center">
</label>
<input type="checkbox" class="calendar-check" id="cal-2year" value="2-year Calendar">
</div>
</div><div class="calendar-box">
<div class="product-wrap">
<label for="cal-whiteboard" class="package-check-toggle">
<img src="images/calendar-package.png" alt="Whiteboard Photo Gift" class="calendar-selection-img">
<img src="images/checkmark-circle.png" class="checkmark-img total-center">
</label>
<input type="checkbox" class="calendar-check" id="cal-whiteboard" value="Whiteboard Calendar">
</div>
</div>
Here's a simplified version of what you're trying to do. Basically, intercepting the click event of the checkbox allows you to prevent the default action (checking the checkbox). The value of checked for this is going to be the value it would be if the click is successful. So, if the checkbox would be unchecked, let the click happen. Also let the click happen if the number of checked checkboxes is less than or equal to the limit. Otherwise, stop the checkbox from getting checked. I've set the limit for this example to 2 just for demonstration.
var limit = 2;
$('input:checkbox').on('click', function (e) {
if (!this.checked || $('input:checkbox:checked').length <= limit) {
return true;
}
return false;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="checkbox">
<input type="checkbox">
<input type="checkbox">
<input type="checkbox">
const allCheckBoxs = document.querySelectorAll("input")
let limit = 2
allCheckBoxs.forEach( el => {
el.addEventListener("click", e => {
if(el.checked){
limit--
if(limit < 0){
e.preventDefault();
console.log("Sorry, you are over the limit")
}
}else{
limit++
console.log(limit)
}
})
})
<input type="checkbox" />
<input type="checkbox" />
<input type="checkbox" />
<input type="checkbox" />
I'm trying to build a 'radio button' selection style list, but not actually using input type="radio". My backend developer has advised me I need to create this using type="checkbox" in our specific case. I believe this can be done with JS.
So how can I make it so that when 1 option is in checked state, the other is unchecked using JS? Here is what I have so far:
http://codepen.io/rjtkoh/pen/VLZrMo
<label for="toggle-1">
<input type="checkbox" id="toggle-1">
<div>option A</div>
</label>
<label for="toggle-2">
<input type="checkbox" id="toggle-2">
<div>option B</div>
</label>
and CSS:
/* Checkbox Hack */
input[type=checkbox] {
position: absolute;
top: -9999px;
left: -9999px;
}
/* Default State */
div {
background: green;
width: 400px;
height: 100px;
line-height: 100px;
color: white;
text-align: center;
margin-bottom: 20px;
}
/* Toggled State */
input[type=checkbox]:checked ~ div {
background: red;
}
I've had a look at other threads talking about changing pseudo classes via JS, but my case dealing with input types confuses me.
Why do you need to do this with a checkbox if the sematics work for radio? There may be a legitimate reason, but without knowing this, I'd suggest you use a radio group instead, which will work without any JavaScript whatsoever, you just need to set a common name attribute on both inputs:
input[type=radio] {
position: absolute;
top: -9999px;
left: -9999px;
}
/* Default State */
div {
background: green;
width: 400px;
height: 100px;
line-height: 100px;
color: white;
text-align: center;
margin-bottom: 20px;
}
/* Toggled State */
input[type=radio]:checked + div {
background: red;
}
<label for="toggle-1">
<input type="radio" name="option" id="toggle-1">
<div>option A</div>
</label>
<label for="toggle-2">
<input type="radio" name="option" id="toggle-2">
<div>option B</div>
</label>
Here is a pure javascript solution since I don't see jQuery tags in your question:
If you REALLY need to do this with checkboxes you can do this:
html
<div id="radio_group">
<label for="toggle-1">
<input type="checkbox" id="toggle-1">
<div>option A</div>
</label>
<label for="toggle-2">
<input type="checkbox" id="toggle-2">
<div>option B</div>
</label>
</div>
javascript
var options = document.getElementById('radio_group').childNodes;
var checkboxes = document.getElementsByTagName('input');
function uncheck() {
for (var i = 0; i < checkboxes.length; i++) {
if (checkboxes[i].type == 'checkbox') {
checkboxes[i].checked = '';
}
}
}
function checkBox(e) {
e.preventDefault();
if(e.target.nodeName == 'DIV') {
uncheck();
e.target.previousElementSibling.checked = 'checked';
}
}
for (var i = 0; i < options.length; i++) {
options[i].addEventListener('click', checkBox, false);
}
heres a fiddle --> https://jsfiddle.net/tL68Lsub/
If you really need the checkbox to work as a radio, you can use:
$("input[type='checkbox']").click(function () {
if ($(this).is(":checked")) {
$("input[type='checkbox']").not(this).removeAttr("checked");
$(this).attr("checked", "true");
}
})