-1

I'm looking for some assistance with a website I'm coding. I have an HTML and CSS switch button (or label):

HTML:

<label class="switch">
  <input type="checkbox"></input>
  <div class="slider round"></div>
</label>

CSS:

/* The switch - the box around the slider */
.switch {
  position: relative;
  display: inline-block;
  width: 60px;
  height: 34px;
}

/* Hide default HTML checkbox */
.switch input {display:none;}

/* The slider */
.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: #2196F3;
}

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

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%;
}

Here is just what the button looks like: https://jsfiddle.net/pbxn2egc/

Essentially what I want or am trying to do is when the button is toggled, I would like for it to show the price of 5 items (that I hard-coded in, so like standard html) and then when you toggle the button it hides that text and shows the competitors price by showing that text.

So if the button is left, I want Walmart's prices. If the button gets toggled to the right, Walmart's prices hide, and Target's appear in the same location.

Can someone assist me with this? Thanks!

Speakmore
  • 69
  • 2
  • 11

3 Answers3

2

One approach is to listen for the onchange event on your <input> element.

Then, when the box is checked/unchecked, you can determine which element (price) is visible and display the other.

document.getElementById("mySwitch").onchange = function() {
  var priceA = document.getElementById("priceA");
  var priceB = document.getElementById("priceB");
  if (priceA.classList.contains("hidden")) {
    priceA.className = "shown";
    priceB.className = "hidden";
  } else if (priceB.classList.contains("hidden")) {
    priceB.className = "shown";
    priceA.className = "hidden";
  }
}
.shown {
}

.hidden {
  display: none;
}
<input type="checkbox" id="mySwitch"></input>
<div class="slider round"></div>

<div id="priceA" class="shown">Price A</div>
<div id="priceB" class="hidden">Price B</div>

If you're using jQuery, there's a toggleClass() method that will automatically toggle an element between two classes.

rphv
  • 5,409
  • 3
  • 29
  • 47
  • were you have .style.display = ""; had issue with this. .style.display = "blocked"; seem to work better for me. – Ryan Sanders Oct 18 '16 at 22:16
  • @Ryan it's `block` not `blocked` — @rphv you're better off adding and removing classes on elements instead of directly fiddling with their style attributes, then the style for the class can be `display:block` or `display:none` _**or**_ use visibility or positioning if one of those is more appropriate, without having to re-code your javascript. – Stephen P Oct 18 '16 at 22:33
  • @StephenP Thanks for the advice - I changed the implementation to use classes instead of tweaking the `style` attribute directly. – rphv Oct 18 '16 at 22:44
  • Thanks for this, it does pretty much exactly what I want. I haven't made too much javascript outside of sites on my own. So my question now is I make a .js file, I link the file in the head, and is that it? Does javascript need a skeleton or is that the only necessary code? – Speakmore Oct 18 '16 at 22:46
  • Yep, that's pretty much it. You don't need a skeleton. I've heard it's best to include the .js file right before the closing `` tag, because this gives a chance for the DOM to load before executing your code. You can also embed the js directly in the HTML between ` – rphv Oct 18 '16 at 22:49
  • Thanks @rphv - I know about the in body javascript, just wanted to mess around with linking outside code. Thanks a bunch guys ^_^ – Speakmore Oct 18 '16 at 22:54
  • @rphv So I tried messing with your code and I left the names of items in a different div than the price. So I have 10 divs (5 names and 5 prices). Obv you only use an ID once so I changed them to class="priceA/B" then I changed all but the first JS to getElementByClassName and it wouldn't toggle the two. Can I not use ClassName? – Speakmore Oct 18 '16 at 23:04
  • @Speakmore `/` is an illegal character in class names - [see here](http://stackoverflow.com/questions/448981/which-characters-are-valid-in-css-class-names-selectors)... maybe create a jsfiddle with your edits & I can try & take a look? Also, `getElementsByClassName` returns a collection of elements (as a NodeList) rather than an individual element, so you may need to refer to an individual element in the list - e.g. `var elementsWithClass = getElementsByClassName("priceA"); elementsWithClass[0].className = "shown"` – rphv Oct 18 '16 at 23:06
  • @rphv sorry I didn't use the / in the actual code, just meant respectively priceA vs. priceB to save characters – Speakmore Oct 18 '16 at 23:09
  • @Speakmore oh right I see :) - I'm guessing the problem is that `getElementsByClassName` returns a *collection* of elements, while `getElementById` returns a single element. – rphv Oct 18 '16 at 23:10
  • @rphv Right so I've also tried 'document.getElementsByClassName("priceA").id.style.display = "none";' and 'document.getElementsByClassName("priceA")[0].id.style.display = "none";' -- Ofc I changed all of them, but just an example. So is that not doable? – Speakmore Oct 18 '16 at 23:15
  • @Speakmore I think you can remove the `.id` - e.g. `document.getElementsByClassName("priceA")[0].style.displ‌​ay = "none";` To do a sanity test, you could open a console in your web browser and make sure `document.getElementsByClassName("priceA")` actually returns an array with some values in it. – rphv Oct 18 '16 at 23:18
1

function togglePrices() {  
  Array.from(document.querySelectorAll('.price')).forEach(function (f) {
    f.classList.toggle('hidden');
  });
}
.hidden {
  display: none;
}
<input type="checkbox" onchange="togglePrices()">  Competitors Price

<div class="price">
  <h3>Our Price</h3>
  water $10.00<br/>
  beer $12.00<br/>
  wine $20.00
</div>

<div class="price hidden">
  <h3>Competitors Price</h3>
  water $12.00<br/>
  beer $15.00<br/>
  wine $24.00
</div>
Keith
  • 22,005
  • 2
  • 27
  • 44
1

In comparison with the answer from @rphv, this is how I would do it...

I have a div for pricing; within that is a div for our prices and another for their prices. The pricing container is unique on the page, and I give it an ID to signify its purpose.

I give the two price divs two classes each; they both get the class "price" and then either "ours" or "theirs", again to describe what they are (not how they look)

The HTML is now a descriptive structure of the data it contains, without bothering with appearance (because appearance is the job of CSS, not HTML)

We start off displaying our prices, so things with class "ours" are displayed when they are within the pricing div #pricing .price.ours; things with class "theirs" are not displayed #pricing .price.theirs.

Later, when the pricing div has class theirs we will show their prices, not ours — so let's hook up our toggle.

One should prefer attaching event handlers over using inline "onevent" javascript handlers, so I gave the checkbox an ID to easily select it, then use addEventListener so the change event will call togglePrices The togglePrices could have been a one-liner, I only assigned the var because you often want to do several things with the selected element. Here I simply toggle the class "theirs" on and off.

What happens when that class is toggled is that it just makes a different set of CSS rules apply to the inner price divs. An "ours" within a "theirs" does not display frp, the #pricing.theirs .price.ours rule. A .theirs within a .theirs does display.

I wish the stack snippet showed in reverse the order used — I think this demonstration makes more sense reading the HTML first, then the CSS, and the JS third.

function togglePrices() {
  var pricing = document.getElementById('pricing');
  pricing.classList.toggle('theirs');
}
document.getElementById('competition')
        .addEventListener('change', togglePrices);
#pricing {
  margin-top: 1em;
}
#pricing .price.ours,
#pricing.theirs .price.theirs
{
  display: block;
}

#pricing .price.theirs,
#pricing.theirs .price.ours
{
  display: none;
}
<input type="checkbox" id="competition">
<label for="competition">Competitor's Price</label>

<div id="pricing">
  
  <div class="price ours">
    <strong>Our Price</strong><br>
    water $1.00<br>
    beer $3.00<br>
    wine $4.50
  </div>

  <div class="price theirs">
    <strong>Competitors Price</strong><br>
    water $1.25<br>
    beer $4.00<br>
    wine $5.50
  </div>

</div>
Stephen P
  • 14,422
  • 2
  • 43
  • 67