I need to fake a toggle switch with an input range.
The idea is to create a short range, with just 2 values, min and max. the css button will match one end of the range. So far you click on it, the div containing the range will move a bit bringing the other end of the ranger under your mouse.
I have this function, which applies on all input ranges on the page. But i need to apply it only on some classes, not all. But i can't find the right syntax and it doesn't work.
The Javascript:
$('input[type="range"]').on('change', function() {
$('div#launcher01').css('margin-top', parseInt($(this).val() ) > 0 ? parseInt($(this).val() ) + 'px' : '0px');
});
CSS:
.fakbl input {
height: 50px;
width: 50px;
HTML:
<div id="launcher01">
<div class="fakbl">
<input type="range" id="launch01" name="launch01" min="0" max="50" step="50"" />
</div>
</div>
Fiddle
Since you are already using jQuery, you can phrase your widget-maker as a jQuery plugin as follows :
$.fn.rangeButton = function(containerSelector) {
return this.each(function() {
var $self = $(this);
$self.on('change', function() {
$self.closest(containerSelector).css('margin-left', ($self.val()/3) > 0 ? ($self.val()/3) + 'px' : '0px');
}).trigger('change'); // trigger 'change' immediately to initialize everything.
});
};
Now, invoke the widget on each of your ranges, and pass a selector for the appropriate container :
$('#launcher01 input[type="range"]').rangeButton('#launcher01');
$('#launcher02 input[type="range"]').rangeButton('#launcher02');
Demo
Alternatively, by giving all containers the same class, you can invoke all your widgets with a single command :
$('.myClass input[type="range"]').rangeButton('.myClass');
Demo
May I ask a refinement please?
I completed the fake button. As you can see in this FIDDLE
(the white box will disappear, I added some opacity to it just to show that the button is working)
The red box (now green due to my buggy code part) is in the background and I would need it to change color depending on the status. I tried this but it doesn't work.
Here the code:
$.fn.rangeButton = function(containerSelector) {
return this.each(function() {
var $self = $(this);
$self.on('change', function() {
$self.closest(containerSelector).css('margin-left', ($self.val()/3) > 0 ? ($self.val()/3) + 'px' : '0px');
// this part is not working, if you remove this part, the button works flawlessy
if ($self = 100) {
document.getElementById("fakbuttonsfondo01").style.backgroundColor="rgb(0, 191, 1)";
} else {
document.getElementById("fakbuttonsfondo01").style.backgroundColor="rgb(0, 0, 255)";
}
// end of buggy code
}).trigger('change'); // trigger 'change' immediately to initialize everything.
});
};
$('#launcher01 input[type="range"]').rangeButton('#launcher01');
$('#launcher02 input[type="range"]').rangeButton('#launcher02');
Thanks:)
I am not quite sure if that's the correct way to phrase it, but here is my problem
As you can see, pretty simple code:
<div class="first"></div>
<div></div>
What I want to achieve is:
You click on the div with the first class, it will swap that class with the sibling element
You click the sibling element, and it swaps it back, so you just swap classes around 2 elements
The problem here is it works correctly only the first time, and the second time when the new element receives the class via addClass, jQuery doesn't recognize that it contains the class by the first page load? How can I resolve this?
P.S: I made a console.log(111); just to make sure, and sure enough it triggers ONLY when I click on the black div after the first swap (the one that SHOULD NOT have the first class anymore)
To achieve this behavior, you can use delegated events http://api.jquery.com/delegate/ on elements wrapper;
$(document).delegate('.first', 'click', function(e){
e.preventDefault();
console.log(123);
$(this).removeClass('first');
$(this).siblings().addClass('first');
})
A quick and simple way to do it is this:
$(document).ready(function() {
var first = $('.first');
var second = first.next();
first.click(function(e) {
e.preventDefault();
first.removeClass('first');
second.addClass('first');
});
second.click(function(e) {
e.preventDefault();
second.removeClass('first');
first.addClass('first');
});
});
div {
background-color: black;
height: 100px;
width: 100px;
margin-bottom: 10px;
}
.first {
background-color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="first"></div>
<div></div>
This way does not scale well.
Your problem was you only change when you click the $(first) which does not change when clicked it's still point to the first div.
A better way with vanilla javascript:
document.addEventListener('click', function(e) {
if (e.target.classList.contains('first')) {
e.target.classList.remove('first')
var sibling = getNextSibling(e.target) || getPreviousSibling(e.target)
if (sibling) {
sibling.classList.add('first')
}
}
})
function getNextSibling(elem) {
var sibling = elem.nextSibling
while(sibling && sibling.nodeType != 1) {
sibling = sibling.nextSibling
}
return sibling
}
function getPreviousSibling(elem) {
var sibling = elem.previousSibling
while(sibling && sibling.nodeType != 1) {
sibling = sibling.previousSibling
}
return sibling
}
All you need to do is push both items into an array, then flip between indexes on click.
var elems = [];
$(document).on("click", ".first", function(event) {
elems = elems.length == 0 ? [event.originalEvent.target, $(event.originalEvent.target).next()] : elems;
$(elems[event.originalEvent.target === elems[0] ? 1 : 0]).addClass("first");
$(elems[event.originalEvent.target === elems[0] ? 0 : 1]).removeClass("first");
});
.first {
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="first">x</div>
<div>y</div>
How do I programatically change a jQuery Switchery checkbox state from checked to unchecked (and vice versa)?
I tried using global_switch_sound.prop('checked', true) on the checkbox element but it doesn't work.
HTML:
<input id="sound-active-input" type="checkbox" />
JavaScript:
global_switch_sound = new Switchery(document.querySelector('#sound-active-input'));
Try this:
$('.switchery').click();
It should trigger a click and switch.
OR this:
$('.switchery').trigger('click');
If anyone is like me and wanted a solution that goes beyond ".click()"ing the DOM. The following function takes the Switchery object and a boolean to indicate whether the switch should be checked or unchecked(true/ false respectively):
function setSwitchery(switchElement, checkedBool) {
if((checkedBool && !switchElement.isChecked()) || (!checkedBool && switchElement.isChecked())) {
switchElement.setPosition(true);
switchElement.handleOnchange(true);
}
}
Example usage:
var mySwitch = new Switchery($('#mySwitchCheck')[0], {
size:"small",
color: '#0D74E9'
});
//Checks the switch
setSwitchery(mySwitch, true);
//Unchecks the switch
setSwitchery(mySwitch, false);
Hope this helps someone else
Try this:
function changeSwitchery(element, checked) {
if ( ( element.is(':checked') && checked == false ) || ( !element.is(':checked') && checked == true ) ) {
element.parent().find('.switchery').trigger('click');
}
}
Example usage:
var element = $('#sound-active-input');
changeSwitchery(element, false);
First you have to store all the switches in an array during initialization
var elems = Array.prototype.slice.call(document.querySelectorAll('.js-switch'));
elems.forEach(function(html) {
switchery[html.getAttribute('id')] = new Switchery(html);
});
and create a local function to toggle switch like this
toggleSwitchery(id)
{
var s = switchery[id];
s.setPosition(true);
s.handleOnchange(true);
}
this worked for me.
In case you face any UI issue i.e. switch moves some extra pixels then open switchery.js and replace jack.offsetWidth by 30 in Switchery.prototype.setPosition function
You can simplify this:
// Uncheck: first set checked property to 'true', then uncheck to force UI update
$(".switchery").prop('checked', false).trigger("click");
// Check
$(".switchery").prop('checked', true).trigger("click");
function toggleSwitch(switch_elem, on) {
if (on){ // turn it on
if ($(switch_elem)[0].checked){ // it already is so do
// nothing
}else{
$(switch_elem).trigger('click').attr("checked", "checked"); // it was off, turn it on
}
}else{ // turn it off
if ($(switch_elem)[0].checked){ // it's already on so
$(switch_elem).trigger('click').removeAttr("checked"); // turn it off
}else{ // otherwise
// nothing, already off
}
}
}
call by using
toggleSwitch("#switch_element", true);
toggleSwitch("#switch_element", false);
Needs error checking and stuff but works well, requires jQuery and tested on Switchery 0.8.1 which came packaged with a prebuilt theme I've been using (Altair Admin)
Simple set like this with your checkbox id,
$('#sound-active-input').prop('checked', true);
DEMO http://jsfiddle.net/yeyene/VHZY8/2/
When you need to check/uncheck all switchery checkboxes the solution with JQuery is:
$( '.js-switches' ).each( function() {
// for checking
if ( !this.checked ) $( this ).trigger( 'click' );
// for unchecking
if ( this.checked ) $( this ).trigger( 'click' );
} );
hope it helps.
try this:
function changeSwitch(switch_id,active) {
var check = document.querySelector(switch_id);
//console.log("check",switch_id,check.checked,"to",active);
if ( !check.checked && active ){
var c = $(check).next('span').attr("class").replace("switchery ","");
var l = {"switchery-large":"26px","switchery-small":"13px","switchery-default":"20px"};
$(check).prop("checked",true).next('span').attr("style","box-shadow: rgb(38, 185, 154) 0px 0px 0px 16px inset; border-color: rgb(38, 185, 154); background-color: rgb(38, 185, 154); transition: border 0.4s, box-shadow 0.4s, background-color 1.2s;").find('small').attr("style","left: "+l[c]+"; transition: background-color 0.4s, left 0.2s; background-color: rgb(255, 255, 255);");
}else if ( check.checked && !active ){
$(check).prop("checked",false).next('span').attr("style","box-shadow: rgb(223, 223, 223) 0px 0px 0px 0px inset; border-color: rgb(223, 223, 223); background-color: rgb(255, 255, 255); transition: border 0.4s, box-shadow 0.4s;").find('small').attr("style","left: 0px; transition: background-color 0.4s, left 0.2s;");
}
}
changeSwitch(".js-switch",true);
If you try this to reset form, use it before:
changeSwitch(".js-switch",true);
$("#frm_id").trigger("reset");
Combined a few answers, works with v0.8.2.
function setSwitchery(switchElement, checkedBool) {
if (checkedBool && !switchElement.checked) { // switch on if not on
$(switchElement).trigger('click').attr("checked", "checked");
} else if (!checkedBool && switchElement.checked) { // switch off if not off
$(switchElement).trigger('click').removeAttr("checked");
}
}
Example usage:
var switchElement = $('#mySwitchInput');
setSwitchery(switchElement, false);
I found the solution from native github issue tracker link. Here is the working example: http://jsfiddle.net/3am89/
This is the piece of code you need to add in and manually call this function to re-render the button:
function onChange(el) {
if (typeof Event === 'function' || !document.fireEvent) {
var event = document.createEvent('HTMLEvents');
event.initEvent('change', true, true);
el.dispatchEvent(event);
} else {
el.fireEvent('onchange');
}
}
The issue that describes this scenoario is
https://github.com/abpetkov/switchery/issues/27
If you are using the switches with Bootstrap collapse, programmatically setting the state fails to expand the data-target every second time. Timing issues with the click handler I assume. This makes it work
function setSwitchery(switchElement, checkedBool) {
if (checkedBool && !switchElement.checked) { // switch on if not on
$(switchElement).trigger('click').prop("checked", false);
// make sure the data target shows
$($(switchElement).data('target')).addClass('show');
} else if (!checkedBool && switchElement.checked) { // switch off if not off
$(switchElement).trigger('click').prop("checked", false);
$($(switchElement).data('target')).removeClass('show');
}
}
If the $('#sound-active-input').click() did not work you, you can try triggering a click on the span that switchery creates after the checkbox.
$('#sound-active-input').next('span').click();
That was the only way it worked for me. Hope it helps.
My answer: because I don't want to trigger the change event that will execute a defined function
var myCheckbox = $("id_your_checkbox")
// your new value true or false
myCheckbox.checked = true;
//remove the old switchery
$('#' + myCheckbox.id).siblings("span.switchery").remove();
//and recreate the switchery
new Switchery(document.querySelector('#' + myCheckbox.getAttribute('id') + ''), {
color: '#1abc9c',
jackColor: '#fff'
});
$('selector').click(function () {
$("selector").toggle(this.checked);
});
if you are using jquery version <1.6
use this
$('#checkMeOut').attr('checked');
I am not sure if you found a solution to this problem, as I too had the same problem and after reading through your discussion with #Rickdep, though he was not able to help you (even though the solution he posted has a check next to it), you guys did point me in the right direction and I was able to come up with a solution, so thank you. Anyway, here is the solution I came up with.
First, you need to be using the class set on the span element you're generating with switchery.js, on your $('.class').click(); function: so for example, the span being generating in my solution looks as such:
<span class="switcher-questionnaire" style="border-color: rgb(121, 186, 97); box-shadow: rgb(121, 186, 97) 0px 0px 0px 16px inset; transition: border 0.7s, box-shadow 0.7s, background-color 2.0999999999999996s; -webkit-transition: border 0.7s, box-shadow 0.7s, background-color 2.0999999999999996s; background-color: rgb(121, 186, 97);">
<small style="left: 50px; transition: left 0.35s; -webkit-transition: left 0.35s;"></small>
</span>
Since the class I am telling switchery.js to generate in this solution is "switcher-questionnaire", that is the class I want to use in my click function, which looks like this:
$('.switcher-questionnaire').click( function() {
if ($(this).children('small').css("left") === '50px') {
$('.questionnaire-overlay').show();
} else {
$('.questionnaire-overlay').hide();
}
console.log('Clicked');
});
For my solution, I wanted to be able to use the switch to hide and show an overlay layer that disables access to specified content the user is viewing if the user determines the section 'does not apply'. Since switchery.js hides the checkbox and replaces that checkbox with a span that creates the Apple-esque switch we all want, but since switchery.js does not actually change the checked/unchecked state of the hidden checkbox, you are unable to use a boolean statement that is actively validating against the checkbox 'checked' attribute. This being the case, I most significant change I noticed the switch does when being toggled is changing the left position of the 'small' element from 50px to 0px when it is clicked:
<small style="left: 50px; transition: left 0.35s; -webkit-transition: left 0.35s;"></small>
I chose this as what I would use as a boolean solution to check against with a little bit of jQuery's magical sauce.
I am pretty much a noob when it comes to programming, but I felt it would be helpful if I explained some of my thought process when solving this problem.
For the AngularJS version, the uiSwitch directive is incomplete to support this.
You must to add a $formatter for the ngModel in the uiSwitch directive that update the switcher value.
ngModel.$formatters.push(function(value) {
$timeout(function() {
ngModel.$setViewValue(value);
switcher.setPosition(value);
});
});
With this, when you update the model in your code will be reflected in the ui-switch directive.
JSFiddle demo
Please Checkit!
function changeSwitch(sltor,active) {
var check = $(sltor).get(0);
if ( (!check.checked && active) || (check.checked && !active) ){
$(check).next('span').trigger('click')
}
}
changeSwitch('.onlyOnThisDate',false);
elems.forEach(function(html) {
let switchery = new Switchery(html, {
size: 'medium',
secondaryColor: '#DC3545'
});
});
Html
<input type="checkbox" class="form-check-input-switchery radio-checkbox" id="chkId">
Javascript
new Switchery("#chkId");
chkId.element.checked = true; //true or false
chkId.handleOnchange();
I made this script, which opens a div with the right class and close the others.
function showhide(id) {
if (document.getElementById) {
var divid = document.getElementById(id);
var divs = document.getElementsByClassName("hideable");
for (var i = 0; i < divs.length; i = i + 1) {
divs[i].style.display = "none";
}
divid.style.display = "block";
}
return false;
}
Is it possible to make some animation, like fadout, easeout instead of just showing it by display options?
You could try this
function showhide(id) {
if (document.getElementById) {
var divid = document.getElementById(id);
var divs = document.getElementsByClassName("hideable");
for (var i = 0; i < divs.length; i = i + 1) {
$(divs[i]).fadeOut("slow");
}
$(divid).fadeIn("slow");
}
return false;
}
Have a look at this fiddle "http://jsfiddle.net/9jtd3/"
There are many more techniques provided by Jquery library, You should have a look at that too.
You can use slideDown() and slidUp() of jQuery
$( document.body ).click(function () {
if ( $( "div:first" ).is( ":hidden" ) ) {
$( "div" ).slideDown( "slow" );
} else {
$( "div" ).slideUp("slow");
}
});
This example will toggle multiple elements with the same class name. This example does not need jquery.
HTML:
<button onclick="fadeInAndOut(this)" style="width:100%">Toggle 1</button>
<div class="accordianPanel acordianPanelHidden accordianPanelStyle">Panel 1</div>
<button onclick="fadeInAndOut(this)" style="width:100%">Toggle 2</button>
<div class="accordianPanel acordianPanelHidden accordianPanelStyle">Panel 2</div>
Javascript:
function fadeInAndOut(thz) {
var elmt = thz.nextElementSibling;//Get the element that is below the button that
//was just clicked
elmt.classList.toggle("acordianPanelHidden");//Toggle the class which changes
//attributes which triggers the `transition` CSS
}
CSS
.accordianPanel {
opacity: 1;
height:100%;
transition: all 1s;
}
.accordianPanel.acordianPanelHidden {
opacity: 0;
height: 0px;
visibility:hidden;/* This must be used or some strange things happen -
What happens is that even though the content of the panel is not shown
any buttons in the content can still be clicked -
So basically there are invisible buttons that can accidently get clicked -
if the visibility is not set to hidden - And the visibility doesn't need to be explicitly changed to visible
from hidden in order to show the content
because if visibility:hidden is not used then by default the content is
displayed -
*/
}
.acordianPanelShown {
height: 100%;
width: 100%;
opacity: 1;
}
.accordianPanelStyle {
background:red;
}
This will surely solve your problem.
You can use .fadeOut() directly if you have included jQuery library in your script.
This is way easier with only CSS.
You make a class
div {
display:block;
transition: all .2s ease-out;
}
.hidden {
display:none;
}
And with javascript, you apply or remove the class hidden when you want to. jQuery animation lib is wayyyy far from good to be used. It's clunky, and ressource eating for your user. CSS works with your GPU instead, allowing a more fluid animation.
If You are using Jquery then another way to do this is
function showhide(id) {
$(".hideable").fadeOut("slow");
$("#" + id).fadeIn("slow");
}
Assuming "hideable" as className in your group of divs
Good luck.
You can do that using a Library like jQuery or something.
You can sure make it using plain javascript, but there's no point doing that since jQuery is an amazing library.
See some examples of show and hide
Is this possible? I've tried visibility:hidden/visibility:visible and display:none/display:block on the classes to switch between, but both result in the element popping in at the end.
When styling the two classes, use the opacity property. .swithClass will be able to transition smoothly between varying opacities.
Example:
.FadeFrom {
opacity: 0.0;
}
.FadeTo {
opacity: 1.0;
}
Look here on how to implement JQuery Fading
http://api.jquery.com/category/effects/fading/
You can handle other events in the fade in and out using the call back function like this:
$('.someClass').fadeIn('slow', function() {
// run extra code here
});
$('.someClass').fadeOut('slow', function() {
// run extra code here
});
Use .animate()
$("#myElement").animate({ opacity: 1, left: 0 }, 1000);
To get .switchClass() to work, you'll have to edit the jQuery code. Find function getElementStyles(). In the else, after if (typeof style[key] === 'string') { add this code:
if (key == "filter" && /^alpha\(opacity=(\d+)\)$/.test(style[key])) {
newStyle.opacity = parseFloat(RegExp.$1) / 100;
}
That should do it.