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
JavaScript Image Overlay Over a Specified Div
Scrolltop Jquery, Scrolling to Div with Id
CSS Media Query Height Greater Than Width and Vice Versa (Or How to Imitate with JavaScript)
Vertical-Align Text Within a Textarea
Getting the Rgb Values for a CSS/HTML Named Color in JavaScript
Fixed Positioned Element Flicker in Ie Only, How to Solve
How to Position Popover Over a Highlighted Portion of Text
How to Handle Radio Event When Icheck-Helper Is Used
Bootstrap 4: Why Popover Inside Scrollable Dropdown Doesn't Show
How to Change the Design of the Textarea Resize Handle in CSS
How to Center the Text in the Headers for an Ag-Grid Control
How to Remove an Existing Class Name and Add a New One with Jquery and Cookies
Detecting Width: Auto in Jquery