Need Help Creating A Segmented Control - javascript

I'm trying to create a segmented control to help organize content on my website. So far, I've got the segmented control created and looking the way I want using HTML and CSS. Now, I would like to expand the functionality of this control to show / hide a series of div tags when each segment is selected. However, JavaScript is definitely not my forte, and I haven't been able to find a good, responsive solution to this problem.
Below is the code I've got so far. You'll also notice a series of div tags whose text indicates which tags should be shown when each segment in the control is selected. I'm pretty sure JavaScript would be the easiest solution to this problem, but as I said, I'm not familiar enough with that language to come up with a good solution here. Any help you can provide on expanding this segmented control so I can use it to show and hide different div tags based on the active segment that is selected would be greatly appreciated.
Here's the HTML I've got:
<ul class="segmented-control">
<li class="segmented-control__item">
<input class="segmented-control__input" type="radio" value="1" name="option" id="option-1" checked>
<label class="segmented-control__label" for="option-1">Step 1</label>
</li>
<li class="segmented-control__item">
<input class="segmented-control__input" type="radio" value="2" name="option" id="option-2" >
<label class="segmented-control__label" for="option-2">Step 2</label>
</li>
<li class="segmented-control__item">
<input class="segmented-control__input" type="radio" value="3" name="option" id="option-3" >
<label class="segmented-control__label" for="option-3">Step 3</label>
</li>
</ul>
Here's the various div tags that should be displayed when a segment within the control is selected. Obviously they are all displaying right under the segmented control right now, and nothing happens to any of these div tags when a new segment is selected. This is what the JavaScript would need to do :)
<div class="Step_1_Content" align="center">
<p>This is the content that should be displayed when the Step 1 segment has been selected</p>
</div>
<div class="Step_2_Content" align="center">
<p>This is the content that should be displayed when the Step 2 segment has been selected</p>
</div>
<div class="Step_3_Content" align="center">
<p>This is the content that should be displayed when the Step 3 segment has been selected</p>
</div>
And here's the CSS I'm using for the Segmented Control:
<style>
.segmented-control {
display: table;
width: 100%;
margin: 2em 0;
padding: 0;
}
.segmented-control__item {
display: table-cell;
margin: 0;
padding: 0;
list-style-type: none;
}
.segmented-control__input {
position: absolute;
visibility: hidden;
}
.segmented-control__label {
display: block;
margin: 0 -1px -1px 0; /* -1px margin removes double-thickness borders between items */
padding: 1em .25em;
border: 1px solid #E62033;
color: #E62033;
font: 14px/1.5 sans-serif;
text-align: center;
cursor: pointer;
}
.segmented-control__label:hover {
background: #ffffff;
color: #E62033;
}
.segmented-control__input:checked + .segmented-control__label {
background: #E62033;
color: #ffffff;
}
</style>
Once again, thanks in advance for your help!

You can simply store the state of the checkboxes in variables, and hide the divs based on those variables.
The first variables I included below are used on page load, the other ones when the object has changed.
Check it out here: https://jsfiddle.net/ezfy66f9/
var checked1 = $('#option-1').is(':checked');
var checked2 = $('#option-2').is(':checked');
var checked3 = $('#option-3').is(':checked');
if (checked1 == 1) {
$('.Step_1_Content').show();
$('.Step_2_Content').hide();
$('.Step_3_Content').hide();
} else if (checked2 == 1) {
$('.Step_2_Content').show();
$('.Step_1_Content').hide();
$('.Step_3_Content').hide();
} else if (checked3 == 1) {
$('.Step_3_Content').show();
$('.Step_1_Content').hide();
$('.Step_2_Content').hide();
}
$(".segmented-control").change(function () {
var checked1 = $('#option-1').is(':checked');
var checked2 = $('#option-2').is(':checked');
var checked3 = $('#option-3').is(':checked');
if (checked1 == 1) {
$('.Step_1_Content').show();
$('.Step_2_Content').hide();
$('.Step_3_Content').hide();
} else if (checked2 == 1) {
$('.Step_2_Content').show();
$('.Step_1_Content').hide();
$('.Step_3_Content').hide();
} else if (checked3 == 1) {
$('.Step_3_Content').show();
$('.Step_1_Content').hide();
$('.Step_2_Content').hide();
}
});

here the code:
$( document ).ready(function() {
// load initial state
hideContent();
$(".step1").show();
// click on li-element
$( "li" ).on( "click", function() {
var li = $(this);
// find the content number
var number = li.find("input").attr("value");
hideContent();
showContent(number) ;
});
});
function hideContent() {
$(".content").hide();
}
function showContent(number) {
$(".content.step"+number).show();
}
.segmented-control {
display: table;
width: 100%;
margin: 2em 0;
padding: 0;
}
.segmented-control__item {
display: table-cell;
margin: 0;
padding: 0;
list-style-type: none;
}
.segmented-control__input {
position: absolute;
visibility: hidden;
}
.segmented-control__label {
display: block;
margin: 0 -1px -1px 0; /* -1px margin removes double-thickness borders between items */
padding: 1em .25em;
border: 1px solid #E62033;
color: #E62033;
font: 14px/1.5 sans-serif;
text-align: center;
cursor: pointer;
}
.segmented-control__label:hover {
background: #ffffff;
color: #E62033;
}
.segmented-control__input:checked + .segmented-control__label {
background: #E62033;
color: #ffffff;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul class="segmented-control">
<li class="segmented-control__item">
<input class="segmented-control__input" type="radio" value="1" name="option" id="option-1" checked="checked">
<label class="segmented-control__label" for="option-1">Step 1</label>
</li>
<li class="segmented-control__item">
<input class="segmented-control__input" type="radio" value="2" name="option" id="option-2" >
<label class="segmented-control__label" for="option-2">Step 2</label>
</li>
<li class="segmented-control__item">
<input class="segmented-control__input" type="radio" value="3" name="option" id="option-3" >
<label class="segmented-control__label" for="option-3">Step 3</label>
</li>
</ul>
<div class="step1 content" align="center">
<p>This is the content that should be displayed when the Step 1 segment has been selected</p>
</div>
<div class="content step2" align="center">
<p>This is the content that should be displayed when the Step 2 segment has been selected</p>
</div>
<div class="content step3" align="center">
<p>This is the content that should be displayed when the Step 3 segment has been selected</p>
</div>

Look this jsfiddle, it's html+css only solution. But this one requires a placement of your div's with content inside of appropriate segment control li elements, like this:
<li class="segmented-control__item">
<input id="option-1" ...>
<label class="segmented-..." for="option-1">Step 1</label>
<div class="Step_1...">
<p>some content...</p>
</div>
</li>
and also some additional css.

Related

How to extend a div backwards?

Does anyone know how to extend a div 2 to the back, lowering the div 1 to the down, when clicking, in a simple way? It looks easy but with css it is not possible and with javascript it is difficult.
I want when clicking on the 2 extends back and the 1 goes down:
But instead this happens:
div 2 goes down.
Html and Css:
.frame {
width: 50%;
height: 400px;
font: bold 70px roboto;
color: black;
background-color: yellow;
float: left;
}
input:checked + .frame {
width: 100%;
}
input{
display: none;
}
<body class="gallery">
<input type="checkbox" id="a" />
<label for="a" class="frame a">1</label>
<input type="checkbox" id="b" />
<label for="b" class="frame b" style="background-color: green">2</label>
<input type="checkbox" id="c" />
<label for="c" class="frame a" style="background-color: green">3</label>
<input type="checkbox" id="d" />
<label for="d" class="frame b">4</label>
</body>
I tried with this javascript:
Demo
To Make the clicked div moves above all:
You can easily do that:
1-Make the gallery parent flex
2-Give order: 2; for all children
3-Change the order to 1 when checked
Apply:
body{
margin: 0;
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.frame {
width: 50%;
height: 100px;
font: bold 70px roboto;
color: black;
text-align: center;
order: 2;
}
input:checked + .frame {
width: 100%;
order: 1;
}
input{
display: none;
}
<body class="gallery">
<input type="checkbox" id="a"/>
<label for="a" class="frame" style="outline: 2px solid">1</label>
<input type="checkbox" id="b"/>
<label for="b" class="frame" style="outline: 2px solid">2</label>
<input type="checkbox" id="c"/>
<label for="c" class="frame" style="outline: 2px solid">3</label>
<input type="checkbox" id="d"/>
<label for="d" class="frame" style="outline: 2px solid">4</label>
<input type="checkbox" id="e"/>
<label for="e" class="frame" style="outline: 2px solid">5</label>
<input type="checkbox" id="f"/>
<label for="f" class="frame" style="outline: 2px solid">6</label>
</body>
And now, when you click anyone, it will go to the top and fill the parent width.
And when you click another one while the first is still active, it will be move to the top too and fill the parent width without affecting the older one.
If you want to stop having many frames selected at the top, just turn your inputs to be radio instead of checkbox and connect them all with the same name attribute.
To make the clicked div moves above its brother only:
Here you must dived every two frames in a separate row div and do the same job for the rest.
Apply:
body {
margin: 0;
display: flex;
flex-direction: column;
flex-wrap: nowrap;
}
.row {
width: 100%;
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.frame {
width: 50%;
height: 100px;
font: bold 70px roboto;
color: black;
text-align: center;
order: 2;
}
input:checked + .frame {
width: 100%;
order: 1;
}
input {
display: none;
}
<body class="gallery">
<div class="row">
<input type="checkbox" id="a" />
<label for="a" class="frame" style="outline: 2px solid">1</label>
<input type="checkbox" id="b" />
<label for="b" class="frame" style="outline: 2px solid">2</label>
</div>
<div class="row">
<input type="checkbox" id="c" />
<label for="c" class="frame" style="outline: 2px solid">3</label>
<input type="checkbox" id="d" />
<label for="d" class="frame" style="outline: 2px solid">4</label>
</div>
<div class="row">
<input type="checkbox" id="e" />
<label for="e" class="frame" style="outline: 2px solid">5</label>
<input type="checkbox" id="f" />
<label for="f" class="frame" style="outline: 2px solid">6</label>
</div>
</body>
Now if you clicked a div, it will go above its brother only, there is a small difference that the other elements will not merge with its brother.
And absolutely there is many many many other ways using css or javascript, but I think the first one does what you want.
Nice question. Yep, it does not have pure-css solution, unfortunately...
Fully agree with previous comment regarding to "swapping" strategy via "order" css property. It's definitely less code and more performant then "physically moving" html elements in DOM
Also, "display: grid" is always better then flex for multi-dimensional layouts (2-column in our case)
Supposing that initial requirement expects that any "even cell" should behave as "2", I see full solution like this:
const el_cells = document.querySelectorAll('.wrapper .cell');
el_cells.forEach((el_clicked, index) => {
const el_prev = index > 0 ? el_cells[index - 1] : null;
el_clicked.addEventListener('click', () => {
// checking if element was already expanded
const expanding = !el_clicked.classList.contains('active')
// restoring initial cells state
el_cells.forEach((el, i) => {
el.classList.remove('active');
el.style.order = i + 1;
});
if (expanding) {
// resizing selected cell
el_clicked.classList.add('active');
// swapping 'even' cell with previous one (f.e. 2 with 1, 4 with 3, etc...)
if (index % 2 === 1) {
el_clicked.style.order--;
el_prev.style.order++;
}
}
})
})
/* some not very important global styles */
* {
margin: 0;
padding: 0;
font-size: 40px;
font-weight: bold;
}
/* our yellow-green grid */
.wrapper {
display: grid;
grid-template-columns: 1fr 1fr;
}
.wrapper .cell {
height: 100px;
background: yellow;
}
.wrapper .cell.green {
background: green;
}
.wrapper .cell.active {
grid-column: span 2;
}
<div class="wrapper">
<div class="cell">1</div>
<div class="cell green">2</div>
<div class="cell green">3</div>
<div class="cell">4</div>
<div class="cell">5</div>
<div class="cell green">6</div>
<div class="cell green">7</div>
<div class="cell">8</div>
</div>
Improved this example a bit to make expanded cells to collapse on click :)
"Uladzimir Interesting, when you click on 2 it extends, then you click on 4 and everyone else resets. Can you tell me how to keep the 2 extended after clicking another one?"
Well, this small clarification adds additional "layer of complexity" to the initial question :)
The reason is that when initially you click "2" - you know that all "even elements" should push "odd ones" below them. On the other hand, when "2" gets expanded and you click "5" - how system should behave if not getting "2" collapsed ?
Seems that "5" has to push "4" below like "2" did that with "1".
So now logics of re-ordering elements has to become "generic" not like it was previously (re-ordering even-index elements when clicked)
And now user clicks, for example, "3", how to process this situation then ? Where do we have to push "1" in this case ? Under "5" probably ? I do not know... But, you see, lots of "edge cases" start appearing here...
What's bad here is that if you implement that - the solution would be definitely bulky, dirty and not very readable and understandable, unfortunately... So, I think, the best way here - to suggest your customers some easier-to-implement option (for example as I suggested initially when collapsing previously expanded elements)
Just a possible and not "too complicated" variant is to list selected elements always "on top":
const el_cells = document.querySelectorAll('.wrapper .cell');
let el_expanded = [];
el_cells.forEach((el_clicked) => {
el_clicked.addEventListener('click', () => {
const expanding = !el_clicked.classList.contains('active');
// resizing/collapsing current cell
if (expanding) {
el_clicked.classList.add('active');
} else {
el_clicked.classList.remove('active');
}
// refreshing expanded element collection
if (expanding) {
el_expanded = [el_clicked, ...el_expanded];
} else {
el_expanded = el_expanded.filter(_ => _ !== el_clicked);
}
// re-indexing not-expanded elements
el_cells.forEach((el, idx) => {
if (el_expanded.indexOf(el) !== -1) return;
el.style.order = 1000 + idx + 1 // 1000 added here to list them after "expanded" ones
})
// re-indexing expanded elements
el_expanded.forEach((el, idx) => {
el.style.order = idx + 1;
})
});
});
/* some not very important global styles */
* {
margin: 0;
padding: 0;
font-size: 40px;
font-weight: bold;
}
/* our yellow-green grid */
.wrapper {
display: grid;
grid-template-columns: 1fr 1fr;
}
.wrapper .cell {
height: 100px;
background: yellow;
}
.wrapper .cell.green {
background: green;
}
.wrapper .cell.active {
grid-column: span 2;
}
<div class="wrapper">
<div class="cell">1</div>
<div class="cell green">2</div>
<div class="cell green">3</div>
<div class="cell">4</div>
<div class="cell">5</div>
<div class="cell green">6</div>
<div class="cell green">7</div>
<div class="cell">8</div>
</div>
Again, this is not "ideal" option, you see. With lots of elements in list it would also require some "scroll-to-top" logics :( Anyway, it is understandable, predictable and requires "not too much" code to create and maintain

Hide certain inputs and show others using a switch button in jQuery

Hello Stackoverflow community, hope that you're doing well, what I'm trying to do is when I click the switch button I want it to hide certain inputs and show others, my code is a form to add students and teachers, since there are cummon inputs I tought about hide the uncummon one when I press the switch button and when I click it again do the opposite but all of that seem to be failed, I can only hide some and when I click it again it won't work, here what I did:
The Jquery code:
$(document).ready(function(){
$('.teacher').hide();
$('.switch').click(function(){
$('.student').hide();
$('.teacher').show();
});
});
The HTML code:
<label>Student </label>
<label class="switch">
<input type="checkbox" id="switchVal" value="0">
<span class="slider"></span>
</label>
<label> Teacher</label>
$('.teacher').hide();
$('.switch').click(function() {
$('.student').toggle();
$('.teacher').toggle();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='student'>Student</div>
<div class="switch">
<input type="checkbox" id="switchVal" value="0">
<span class="slider"></span>
</div>
<div class='teacher'>Teacher</div>
Use $(".teacher, .student").toggle();
Or, if needed, for more granular control you could always get the current checkbox state using
const isChecked = this.checked; // boolean`
Example:
jQuery($ => {
$(".teacher").hide();
$("#switchVal").on("input", function() {
$(".teacher, .student").toggle();
});
});
.toggler {
display: inline-flex;
gap: 0 5px;
cursor: pointer;
}
.toggler-checkbox {
display: inline-block;
width: 35px;
height: 15px;
background: #444;
border-radius: 1.2em;
}
.toggler-checkbox::before {
content: "";
position: relative;
display: inline-block;
width: 15px;
height: 15px;
background: #0bf;
border-radius: 1em;
transition: transform 0.3s;
}
.toggler input:checked ~ .toggler-checkbox::before {
transform: translateX(20px);
}
.toggler-label {
user-select: none;
}
.toggler-label:nth-of-type(1) {
order: -1;
color: #0bf;
}
.toggler input:checked ~ .toggler-label:nth-of-type(1) {
color: inherit;
}
.toggler input:checked ~ .toggler-label:nth-of-type(2) {
color: #0bf;
}
<label class="toggler">
<input type="checkbox" id="switchVal" value="0" hidden>
<span class="toggler-checkbox"></span>
<b class="toggler-label">Student</b>
<b class="toggler-label">Teacher</b>
</label>
<ul>
<li class="student">Student: Anna</li>
<li class="student">Student: John</li>
<li class="teacher">Teacher: Mark</li>
<li class="student">Student: Tara</li>
<li class="teacher">Teacher: Zack</li>
</ul>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>

Remove the default checked value in radio button and replace it with the another radio button that is click

I just want to change the default check value in radio button to what is the user selected value.Because whenever i try it still display in console log the default checked and not the one who is check. i want to change default checked to what user selected in HTML. Can anyone help me? im just really a newbie. Any help would be appreciated. Thank you.Here is the code.
CSS:
html,
body {
font: 400 small-caps 16px/1.25 Arial;
}
fieldset {
width: fit-content;
padding: 0;
}
legend {
font-size: 1rem
}
details {
width: 150px;
cursor: pointer;
margin: 0 4px -5px 0;
padding: 0 0 0 10px;
}
summary {
position: relative;
width: 96%;
outline: 0.5px ridge grey;
}
/*
Hides <detail>'s default arrow
*/
details summary::-webkit-details-marker {
visibility: hidden;
position: absolute;
z-index: -1;
}
/*| Pseudo-<option>
All pseudo-<option> are initially hidden and
<label class='opt'> are the only tags that will show/hide,
the next comment explains how.
*/
.rad {
display: none
}
.opt {
display: none;
margin: 0 0 2px 0;
cursor: pointer;
font-size: 0.9rem;
box-shadow: -2px -2px 11px rgba(0, 0, 0, 0.3) inset;
}
/*| Two Conditions
1. If <details open='true'> all <label class='opt'> are visible.
=============================================
2. if <input class='rad' type='radio' checked> then the
<label class='opt'> that proceeds the radio button is visible.
*/
[open] .opt,
.rad:checked+.opt {
display: block;
}
/*| For Demonstration Purposes
This ruleset changes how the console is displayed.
*/
.as-console-wrapper {
width: 50%;
min-height: 100%;
margin-left: 50%;
font-variant: normal;
}
.as-console-row.as-console-row::after {
content: '';
padding: 0;
margin: 0;
border: 0;
width: 0;
}
</style>
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Custom select box Jquery Plugin by VJ</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css">
<!--| Flag Icons
This stylesheet provides the flag icons.
For details, go to:
https://afeld.github.io/emoji-css/
-->
<link href="https://afeld.github.io/emoji-css/emoji.css" rel="stylesheet" />
</head>
<body>
<form id="container">
<fieldset>
<legend>Country</legend>
<!--| Pseudo-<select>
<details> provides the dropdown behavior and
<summary> contains the pseudo-<option>
-->
<details>
<summary>
<!--| 4 Pseudo-<option>
Each <label> and <input type='radio'> pair are
synced to each other by matching the values of
<label for="ID"> and <input id="ID">.
-->
<!--| Trigger and State
When <label> is clicked ... <input type='radio'>
is checked. This simple "cause and effect" can
be leveraged into a system of states (ie off/on).
For details, review the CSS.
-->
<input id='X' type='radio' class='rad' name='rad' value="" checked>
<label class='opt' for='X'>
<i class='em em-us'></i>
United States
</label>
<input id='US' type='radio' class='rad' name='rad' value="United States">
<label class='opt' for='US'>
<i class='em em-us'></i>
United States
</label>
<input id='GB' type='radio' class='rad' name='rad' value="Great Britain">
<label class='opt' for='GB'>
<i class='em em-gb'></i>
Great Britain
</label>
<input id='IN' type='radio' class='rad' name='rad' value="India">
<label class='opt' for='IN'>
<i class='em em-flag-in'></i>
India
</label>
<input id='NP' type='radio' class='rad' name='rad' value="Nepal">
<label class='opt' for='NP'>
<i class='em em-flag-np'></i>
Nepal
</label>
</summary>
</details>
</fieldset>
</form>
</body>
</html>
JAVASCRIPT
<script type="text/javascript">
var xC = document.forms.container;
var xE = xC.elements;
var vR = xE.rad;
xC.onchange = function() {
// console.log(vR.value);
// location.reload();
if(vR.value=="United States") {
alert("welcome us");
location.reload();
}
else if(vR.value=="United States") {
alert("welcome us");
location.reload();
}
}
</script>
localStorage
Use localStorage to save the selected value then retrieve the value when page is reloaded. Note: For details on how the rest of this demo works, see this post.
var xC = document.forms.container;
var xE = xC.elements;
var vR = xE.rad;
var cty = localStorage.getItem('country');
xC.addEventListener('change', saveCountry);
document.addEventListener('DOMContentLoaded', setCountry);
function saveCountry(e) {
localStorage.setItem('country', vR.value);
console.log("Welcome, " + vR.value);
};
function setCountry(e) {
for (let i = 0; i < vR.length; i++) {
if (vR[i].value === cty) {
vR[i].checked = true;
}
}
console.log("Welcome, " + vR.value);
};
Plunker
Demo
This demo does not fully function due to SO restricting localStorage. For a fully functional demo, review this Plunker. To test it, select a country, then refresh the page by clicking the refresh button in the preview panel or CTRL+ENTER for PC or ⌘+RETURN for Mac.
Details are commented in demo
var xC = document.forms.container;
var xE = xC.elements;
var vR = xE.rad;
/*
Get the string saved in localStorage named 'country'
*/
var cty = localStorage.getItem('country');
/*| When <form> is changed
Call saveCountry()
*/
xC.addEventListener('change', saveCountry);
/*| When Page is Reloaded
Call setCountry()
*/
document.addEventListener('DOMContentLoaded', setCountry);
/*
Save the value selected in pseudo-<select> in localStorage
*/
function saveCountry(e) {
localStorage.setItem('country', vR.value);
console.log("Welcome, " + vR.value);
};
/*
Loop through the pseudo-<option>s
When a pseudo<option> matches the value saved...
in localStorage under the name of 'country'...
check that pseudo-<option> by assigning it...
the attribute [checked] = true
*/
function setCountry(e) {
for (let i = 0; i < vR.length; i++) {
if (vR[i].value === cty) {
vR[i].checked = true;
}
}
console.log("Welcome, " + vR.value);
};
html,
body {
font: 400 small-caps 16px/1.25 Arial;
}
fieldset {
width: fit-content;
padding: 0;
}
legend {
font-size: 1rem
}
details {
width: 170px;
cursor: pointer;
margin: 0 4px -5px 0;
padding: 0 5px 10px 10px;
}
summary {
width: 100%;
position: relative;
}
/*
Shows <detail>'s default arrow
*/
/*
summary::-webkit-details-marker {
position: absolute;
padding: 0 0 0 5px;
z-index: 1;
top: 25%;
}
[open] summary::-webkit-details-marker {
top: 5%;
}
.em {
padding: 0 0 0 10px;
}
*/
/*
Hides <detail>'s default arrow
*/
summary::-webkit-details-marker {
visibility: hidden;
position: absolute;
z-index: -1;
}
.em {
padding: 0;
}
/*| Pseudo-<option>
All pseudo-<option> are initially hidden and
<label class='opt'> are the only tags that will show/hide,
the next comment explains how.
*/
.rad {
display: none
}
.opt {
display: none;
position: relative;
z-index: 2;
width: 100%;
margin: 0;
cursor: pointer;
font-size: 0.9rem;
box-shadow: -2px -2px 11px rgba(0, 0, 0, 0.3) inset;
}
/*| Two Conditions
1. If <details open='true'> all <label class='opt'> are visible.
=============================================
2. if <input class='rad' type='radio' checked> then the
<label class='opt'> that proceeds the radio button is visible.
*/
[open] .opt,
.rad:checked+.opt {
display: block;
}
/*| For Demonstration Purposes
This ruleset changes how the console is displayed.
*/
.as-console-wrapper {
max-height: 50%;
font-variant: normal;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Custom select box Jquery Plugin by VJ</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css">
<!--| Flag Icons
This stylesheet provides the flag icons.
For details, go to:
https://afeld.github.io/emoji-css/
-->
<link href="https://afeld.github.io/emoji-css/emoji.css" rel="stylesheet">
</head>
<body>
<form id="container">
<fieldset>
<legend>Country</legend>
<!--| Pseudo-<select>
<details> provides the dropdown behavior and
<summary> contains the pseudo-<option>
-->
<details>
<summary>
<!--| 4 Pseudo-<option>
Each <label> and <input type='radio'> pair are
synced to each other by matching the values of
<label for="ID"> and <input id="ID">.
-->
<!--| Trigger and State
When <label> is clicked ... <input type='radio'>
is checked. This simple "cause and effect" can
be leveraged into a system of states (ie off/on).
For details, review the CSS.
-->
<input id='X' type='radio' class='rad' name='rad' value="" checked>
<label class='opt' for='X'>
<i class='em em-us'></i> United States
</label>
<input id='US' type='radio' class='rad' name='rad' value="United States">
<label class='opt' for='US'>
<i class='em em-us'></i> United States
</label>
<input id='GB' type='radio' class='rad' name='rad' value="Great Britain">
<label class='opt' for='GB'>
<i class='em em-gb'></i> Great Britain
</label>
<input id='IN' type='radio' class='rad' name='rad' value="India">
<label class='opt' for='IN'>
<i class='em em-flag-in'></i> India
</label>
<input id='NP' type='radio' class='rad' name='rad' value="Nepal">
<label class='opt' for='NP'>
<i class='em em-flag-np'></i> Nepal
</label>
</summary>
</details>
</fieldset>
</form>
<!--|For Demonstration Purposes
Provides console
-->
</body>
</html>
Are you saying that when selecting the United States radio button it selects the default radio button in error? The
location.reload()
lines are reloading the page whenever the United States radio button is selected, and the new page defaults to the first radio button as selected. So you could just remove those lines and the correct radio button would stay as selected.
If the page reload is intentional and you want the new page to have the same radio button selected as the last page then you could pass a URL param to the new page and then use javascript on the new page to read any params and select the right radiobutton
e.g.
document.replace('yourpage.html?selectedCountry=US')

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