Link to home
Start Free TrialLog in
Avatar of Jon Imms
Jon ImmsFlag for United States of America

asked on

How do i make a toggle switch JS like this?

Hello,

I am trying to create a toggle switch, which will display an Annual or Monthly $price depending on what is's checked. Also some text underneath will change depending on what is checked.

I have it working in my codepen here. 
https://codepen.io/jonimmsCC/pen/mdmxrVa

I have the JS working, as it correctly displays the correct price.  But i want to get the toggle switch to look like the image below.  I've scoured google, and don't find anything.  Could one of you help me get the toggle looking like the image below? 

User generated image
Avatar of leakim971
leakim971
Flag of Guadeloupe image

Avatar of Jon Imms

ASKER

Thank You leakim971.  

How would i modify my JS to use the CSS toggle, to change the text based on what is active?
https://codepen.io/jonimmsCC/pen/mdmxrVa

<div class="can-toggle can-toggle--size-large">
  <input id="c" type="checkbox">
  <label for="c">
    <div class="can-toggle__switch" data-checked="On" data-unchecked="Off"></div>
    <div class="can-toggle__label-text">.can-toggle.can-toggle--size-large</div>
  </label>
</div>

Open in new window

You can create a toggle switch with CSS like this (Working sample here: https://www.marcorpsa.com/ee/t3969.html)
CSS
.toggle-switch {
  cursor: pointer;
  background-color: gray;
  display: inline-block;
  border: 0;
  padding-left: 0;
  padding-right: 0;
}
.toggle-switch input {
  display: none;
}
.toggle-switch,
.toggle-switch span {
  border-radius: 35px;
  border-style: solid;
  border-color: transparent;
  padding-top: .75rem;
  padding-bottom: .75rem;
}
.toggle-switch span {
  border-width: 2px;
  padding-left: .75rem;
  padding-right: .75rem;
}
.toggle-switch input:checked + span + span, 
.toggle-switch input + span  {
  border-color: #444;
  background-color: white;
}

.toggle-switch input + span + span,
.toggle-switch input:checked + span{
  background-color: transparent;
  border-color: transparent;
}

Open in new window

HTML
<label for="toggle" class="toggle-switch">
  <input id="toggle" type="checkbox" name="toggle">
  <span>pay annually</span>
  <span>pay monthly</span>
</label>

Open in new window

Awesome Julian,

I'm falling down understanding the JS,  I found from another codepen.  How can i modify the JS i have, so on Pay annually, it shows the value of var text1, var text2, var text4.  Pay monthly it shows the contents of var text1, var text3, var text5

How about this http://mrcp9/ee/t3969.html
HTML
<form name="myform">
    <div><label>var text 1</label><input type="text" name="vartext1" value="123"></div>
    <div><label>var text 2</label><input type="text" name="vartext2" value="345"></div>
    <div><label>var text 3</label><input type="text" name="vartext3" value="678"></div>
    <div><label>var text 4</label><input type="text" name="vartext4" value="111"></div>
    <div><label>var text 5</label><input type="text" name="vartext5" value="222"></div>

    <label for="toggle" class="toggle-switch">
        <input class="toggle-button" id="toggle" type="checkbox" name="toggle" data-checked="vartext1,vartext2,vartext4" data-not-checked="vartext3,vartext5"">
        <span>pay annually</span>
        <span>pay monthly</span>
    </label>
</form>

Open in new window

JavaScript
(function() {
    // Get all toggle buttons
    const els = document.getElementsByClassName('toggle-button');

    // For each bind the change event handler and initialise by calling show hide
    [...els].forEach(e => {
        showHide({target: e});
        e.addEventListener('change', showHide);
    });

    // Get the elements to show high from the custom data
    function showHide(e) {
        const el = e.target;
        const form = el.form;
        if (el.checked) {
            el.dataset.checked.split(',').forEach(fld => form[fld].parentNode.style.display = 'block');
            el.dataset.notChecked.split(',').forEach(fld => form[fld].parentNode.style.display = 'none');
        } else {
            el.dataset.checked.split(',').forEach(fld => form[fld].parentNode.style.display = 'none');
            el.dataset.notChecked.split(',').forEach(fld => form[fld].parentNode.style.display = 'block');
        }
    }
})();

Open in new window

Hi Julian,  Thank you so much for the help on this.

Does it need to be in a form element?   Just i have the 2 values (Annually/monthly) in a div,   then also want it to change the text of a div further down the page (Core Annual Text / this is a annual text blur) (Core Pro Text / this is a monthly text blurb.) var text4 and var text5

ASKER CERTIFIED SOLUTION
Avatar of Julian Hansen
Julian Hansen
Flag of South Africa image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Hi Julian,

I think i follow, but still unsure about the last part.  The 2 text blubs (this is a monthly text blurb.)  are going to be way down the page.  lots of  Gutenberg blocks in between  the toggle box and the text blurbs.   Do i wrap the

<p class="center_text big-text coreAnnuallyText">this is a annual text blurb</p>
<p class="center_text big-text coreMonthlyText">this is a monthly text blurb.</p>

Open in new window


Inside its own form, with the same form name?
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Hey Julian,

What is the fld?  I've put the names in the data-checked but everything is displaying, not toggling.

https://codepen.io/jonimmsCC/pen/mdmxrVa
Hey Julian,

I still cannot get his to work,  at the moment everything shows, and no toggle.  I do have unique id's for every target. Not sure what i'm doing wrong with it? 

https://codepen.io/jonimmsCC/pen/mdmxrVa
Firstly not sure what I am looking for - CP seems to work?
Secondly, why did you hard code the showHide function - the whole purpose of the design was to make it dynamic based on the id's you specify in the data-checked and data-not-checked fields.
Thirdly, this solution does not require jQuery - jQuery is useful but not as useful as it used to be - which was to handle cross browser issues. In this case it is adding unnecessary weight.

The code I gave you above (the document.getElementId) should work perfectly for your setup.

Let me know what I should be seeing in the CodePen - as it stands it seems to work as expected.