3 State CSS Toggle Switch

3 State CSS Toggle Switch

Try something like this:

.switch-toggle {  width: 10em;}
.switch-toggle label:not(.disabled) { cursor: pointer;}
<link href="https://cdn.jsdelivr.net/css-toggle-switch/latest/toggle-switch.css" rel="stylesheet" />
<div class="switch-toggle switch-3 switch-candy"> <input id="on" name="state-d" type="radio" checked="" /> <label for="on" onclick="">ON</label>
<input id="na" name="state-d" type="radio" disabled checked="checked" /> <label for="na" class="disabled" onclick=""> </label>
<input id="off" name="state-d" type="radio" /> <label for="off" onclick="">OFF</label>
<a></a></div>

3 state toggle button

First of all, it looks to me like your two functions are doing the same thing. They're toggling the display property of the images. In both cases, if display is set to '', it gets set to 'none'. If display is set to 'none', it gets set to ''.

Secondly, I think the problem is that you're toggling them. If you only want to show one at a time, you need to set one to shown and the other two to hidden. If you just toggle them every time, then the two that are hidden will always change to shown at the same time.

I think it should look more like this: (sample)

<script type="text/javascript">
function hide(elementID)
{
document.getElementById(elementID).style.display = 'none';
}

function show(elementID)
{
document.getElementById(elementID).style.display = '';
}
</script>

<img id="off" src="images/general/sound-off.png" width="40" height="32" onClick="show('on'); hide('off'); playAudio();" alt="on">
<img id="on" src="images/general/sound-on.png" width="40" height="32" onClick="show('pause'); hide('on'); pauseAudio();" style="display:none;" alt="off">
<img id="pause" src="images/general/sound-pause.png" width="40" height="32" onClick="show('on'); hide('pause'); playAudio();" style="display:none;" alt="on">

Three state toggle switch in angular

really I like the radio-buttons of ng-bootstrap https://ng-bootstrap.github.io/#/components/buttons/examples#radio
(well, you can add as style

.btn-primary.focus, .btn-primary:focus {  
box-shadow: 0 0 0 0;
}

To avoid the "ugly" shadow in focus)

Make some similar without third-party libraries is play with css. if we has an options like

<div *ngFor="let option of options" style="display:inline"  
[className]="value==option.value?'active':'noactive'" >
<input class="radio" type="radio" name="state-d" id="{{option.id}}"
[(ngModel)]="value" [value]="option.value" />
<label for="{{option.id}}">
{{option.id}}
</label>
</div>

Simply add

[type="radio"].radio {
border: 0;
clip: rect(0 0 0 0);
height: 1px; margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
}
.active{
color:red;
}
.noactive{
color:blue;
}

remove the "caret" and give some style to radio buttons. well, make an animation it's more complex. I'll try using Angular Animations defining three states, but I'm not pretty sure how make it

Updated using Angular animations
Angulars animation in this case is easy. Just defined three states (I make a very simple example (my options will be a simple array)

An animation is only defined states and how pass to one state to other

@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
animations: [
trigger('posX',[
state('uno',style({transform:'translateX(0)'})),
state('dos',style({transform:'translateX(100px)'})),
state('tres',style({transform:'translateX(200px)'})),
transition('* => uno',animate(200)),
transition('* => dos',animate(200)),
transition('* => tres',animate(200)),
])
]
})
export class AppComponent {
pos:string='uno';
pos2:string='uno';
options=['uno','dos','tres'];
}

The animation only say that, when [@posX] was 'uno', no translate, when [@posX] was 'dos' translate 100px to the left and when [@posX] was 'tres' translate 200px

An html will be two divs that are in the same position (I use margin-top:-2rem)

<div style="background-color:transparent;">
<div *ngFor="let option of options" style="display:inline;" >
<input class="radio" type="radio" name="state-d" id="{{'l'+option}}"
[(ngModel)]="pos" [value]="option" />
<label class="radio" for="{{'l'+option}}">
{{option}}
</label>
</div>
</div>
<div style="overflow:hidden;margin-top:-2rem">
<div [@posX]="pos" (@posX.done)="pos2=pos" style="background:blue;width:100px" >
{{pos2}}
</div>
</div>

And a css to hide the "caret" and give width to the labels.

[type="radio"].radio {
border: 0;
clip: rect(0 0 0 0);
height: 1px; margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
}
label.radio
{
width:100px;
}

you can see in the stackblitz

NOTE: Obviously is an ugly example with style in-line and not in .css

Is it possible to have a 3-way toggle?

I don't think it's possible to have a tri-state button, but if you want a slider-type thing without JavaScript as you commented, just use a range input:

$('input').change(function() {    $('#res').html(this.value);})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script><input type="range" min="0" max="2" step="1" value="0" /><div>Debug value: <span id="res"></span></div>

How to change content with toggle button with html css and js

To do what you require hook an event handler to the checkbox input and then toggle the display setting of the parent elements of the sliders based on the state of that checkbox. Note that in this example I used div elements as the parents, but any block-level element would work.

let mainContent = document.querySelector('#main_content');
let secondaryContent = document.querySelector('#secondary_content');

document.querySelector('.switch input').addEventListener('change', e => {
mainContent.style.display = e.target.checked ? 'block' : 'none';
secondaryContent.style.display = e.target.checked ? 'none' : 'block';
});
.switch {
position: relative;
display: inline-block;
width: 60px;
height: 34px;
}

.switch input {
opacity: 0;
width: 0;
height: 0;
}

.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: .4s;
transition: .4s;
}

.slider:before {
position: absolute;
content: "";
height: 26px;
width: 26px;
left: 4px;
bottom: 4px;
background-color: white;
-webkit-transition: .4s;
transition: .4s;
}

input:checked+.slider {
background-color: #E21C90;
}

input:focus+.slider {
box-shadow: 0 0 1px #2196F3;
background-color: #E21C90;
}

input:checked+.slider:before {
-webkit-transform: translateX(26px);
-ms-transform: translateX(26px);
transform: translateX(26px);
}

/* Rounded sliders */

.slider.round {
border-radius: 34px;
}

.slider.round:before {
border-radius: 50%;
}

#secondary_content {
display: none;
}
<label class="switch">
<input type="checkbox" checked>
<span class="slider round"></span>
</label>

<div id="main_content">Slider 1</div>
<div id="secondary_content">Slider 2</div>

How to Switch off and ON the toggle Button based on the click event on icon

I think its a bad idea to toggle multiple icons with one switch (and be able to toggle them manually on a click), it confuses me. But nevermind, here you go.

First you need to declare a state of each of your icons, so you know which one is active/inactive (if there is any logic behind this, you want to know).

Every time you click on an icon which state changes to active, it becomes red. When you click on the toggle, and its state changes to inactive, all of your icons will change back to white.

component.html:

 <label class="rating-switch" id="toggleSwitch">
<input class="rating-checkbox" type="checkbox" [checked]="toggleState" (change)="onToggleClicked($event)">
<div class="slide round">

</div>
</label> <span class="no-rating-switch">No Rating</span>

<div class="container">
<span class="iconss"></span>
<i (click)="onIconClick(icon)" class="stl" [class]="icon- + i"
[style.color]="icon.active === true ? '#FF0000' : '#ffffff'" *ngFor="let icon of icons; let i = index">
</i>
</div>

component.ts:

  toggleState = true;
icons = [
{id: 1, class: 'icon-1', active: false},
{id: 2, class: 'icon-2', active: false},
{id: 3, class: 'icon-3', active: false},
{id: 4, class: 'icon-4', active: false},
{id: 5, class: 'icon-5', active: false},
{id: 6, class: 'icon-6', active: false},
{id: 7, class: 'icon-7', active: false},
];

ngOnInit() {

}

onIconClick(icon: any) {
let iconToEdit = this.icons.find(ico => ico.id === icon.id);
if (iconToEdit && !iconToEdit.active) {
this.icons.forEach(i => i.active = false);
iconToEdit.active = !iconToEdit.active;
this.markToggleAsActive();
} else {
this.icons.forEach(i => i.active = false);
}
}

onToggleClicked(event: any) {
this.toggleState = event.target.checked;
this.markIconsAsInactive();
}

markIconsAsInactive() {
if (!this.toggleState) {
this.icons.forEach(icon => icon.active = false);
}
}

markToggleAsActive() {
this.toggleState = !!this.icons.find(icon => icon.active);
}


Related Topics



Leave a reply



Submit