MozillaZine

JavaScript change event question.

Discuss how to use and promote Web standards with the Mozilla Gecko engine.
Bethrezen
 
Posts: 397
Joined: September 13th, 2003, 11:56 am

Post Posted June 6th, 2019, 8:54 am

Hi all

So I'm trying to write a simple show hide script that will upon checking a given radio button show the container that has the same id as the radio button that was checked, however this is where I'm stuck because the process only seems to work 1 way.

I can set the default state to make things hidden and I can make each of those hidden elements visible again upon clicking the corresponding radio button the problem is once there corresponding radio button is no longer checked those elements don’t switch back to the default state and thus remain visible and I don't understand why? because I had amused that the change event would work the same way as the :checked pseudo-class does in css

So all i would have to do is set the default state and then define when happens when one of the radio buttons is checked and then each time the script is fired the targeted element would be made viable and the previously targeted element would be made invisible again.

however the change event does seem to work this way and i cant figure out how to make all the containers except the one that is selected one invisible.

ok so here is a simplified version of the page I'm working on

Code: Select all
<!DOCTYPE html>
<html>
<head>
<title></title>
<style>
div.container
{
display:none
}
</style>
</head>

<body>

<main>

  <div id="left">

    <input type="radio" name="button" id="foo">
    <label for="foo">foo</label>

    <br><input type="radio" name="button" id="bar">
    <label for="bar">bar</label>

  <div id="right">

    <div class="container" data-name='foo'>
      <p>some content that should be hidden by default</p>
    </div>

    <div class="container" data-name='bar'>
      <p>some content that should be hidden by default</p>
    </div>

  </div>

</main>

<script>

function checked(event)
{
  var id = event.target.id;
  var selected = document.querySelector('[data-name="'+ id +'"]');

  selected.style.cssText="display:block";
}

var inputs = document.querySelectorAll("input");
for (i = 0; i < inputs.length; i++)
{
  inputs[i].addEventListener("change", checked);
}

</script>

</body>
</html>


what should happen when i check the radio button with the id foo is that the box with the data-name="foo" should appear which it does

what should happen when i check the radio button with the id bar is that the box with the data-name="bar" should appear which it does however since the radio button with the id foo is no longer checked the box with the data-name="foo" should become invisible again which it doesn't and as i already mentioned I don't understand why because i though the change event was supposed to work like the :checked pseudo-class so when the radio button is no linger checked it should automatically switch back to the default state.

anyone have any idea what I'm missing ?

mightyglydd

User avatar
 
Posts: 9434
Joined: November 4th, 2006, 7:07 pm
Location: Hollywood Ca.

Post Posted June 6th, 2019, 10:07 am

Bethrezen wrote:anyone have any idea what I'm missing ?

Er the correct forum?

Which is here https://forum.palemoon.org/index.php
#KeepFightingMichael

morat
 
Posts: 3196
Joined: February 3rd, 2009, 6:29 pm

Post Posted June 6th, 2019, 12:00 pm

Add the following code snippet to the beginning of the checked function.

Code: Select all
var divs = document.querySelectorAll("div.container");
for (var i = 0; i < divs.length; i++)
  divs[i].style.cssText = "display:none";

Dynamic Tabs Example
http://jsfiddle.net/t8zbh0pa/

Bethrezen
 
Posts: 397
Joined: September 13th, 2003, 11:56 am

Post Posted June 10th, 2019, 3:37 pm

Er the correct forum?

Which is here https://forum.palemoon.org/index.php


Web Development / Standards Evangelism is the correct forum, since it's a question is related to web development, the browser that i used to post the question is irrelevant, and for the record just because i post using pale moon doesn't mean I'm developing in pale moon, in fact i use a portable version of Firefox for that.

Dynamic Tabs Example
http://jsfiddle.net/t8zbh0pa/


i had a look at the jsfiddle and that's not really what I'm trying to do.

Add the following code snippet to the beginning of the checked function.

Code: Select all
var divs = document.querySelectorAll("div.container");
    for (var i = 0; i < divs.length; i++)
      divs[i].style.cssText = "display:none";p




after a bit of tinkering that's almost the solution i came up with, which you can see below.

Code: Select all
<!DOCTYPE html>
<html lang="en">
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">

<style>
div.container
{
display:none
}
</style>

</head>

<body>

<main>

  <div id="left">

    <input type="radio" name="button" id="foo">
    <label for="foo">show foo</label>

    <br><input type="radio" name="button" id="bar">
    <label for="bar">show bar</label>

    <br><input type="radio" name="button" id="choo">
    <label for="bar">show choo</label>

  <div id="right">

    <div class="container" data-name='foo'>
      <p>some content that should be hidden by default foo</p>
    </div>

    <div class="container" data-name='bar'>
      <p>some content that should be hidden by default bar</p>
    </div>

    <div class="container" data-name='choo'>
      <p>some content that should be hidden by default choo</p>
    </div>

  </div>

</main>

<script>

function checked(event)
{
  var id = event.target.id;
  var selected = document.querySelector('[data-name="'+ id +'"]');

  selected.style.cssText="display:block";

  var notchecked = document.querySelectorAll('input:not(:checked)');

  for (i = 0; i < notchecked.length; i++)
  {
    var id = notchecked[i].id;
    document.querySelector('[data-name="'+ id +'"]').style.cssText="display:none";
  }
}

var inputs = document.querySelectorAll("input");
for (i = 0; i < inputs.length; i++)
{
  inputs[i].addEventListener("change", checked);
}

</script>

</body>
</html>


while the above works fine, doing things this way is something of a blunt instrument, and not particularly efficient, and i was actually hoping for a solution with a little more finesse.

aka I want to get only the previously checked element since only the previously checked element will be set to display:block; therefore there is no reason to get every other element that is not currently checked as they are already set to be hidden by default, unfortunately my knowledge of JavaScript is pretty limited so I'm unsure how i would store which element was checked previously and then switch only that element back to hidden when its no longer checked.

Also this still doesn't explain why if i set the default state to hidden and the checked state to viable elements are not automatically switched back to there default state when they become unchecked, since i though the onchange event was supposed to fire when the element is checked and when the element is unchecked and therefore it should work like the :checked pseudo-class and automatically switch back to the default state upon becoming unchecked.

humm... and just when i start to think I'm finally beginning to understand this stuff, why there aren't just separate checked and unchecked events just like there are for hover I'll never know it would make life so much easier.

jscher2000

User avatar
 
Posts: 10578
Joined: December 19th, 2004, 12:26 am
Location: Silicon Valley, CA USA

Post Posted June 11th, 2019, 6:11 pm

Try using a unique class name for the selected/visible tab. For example add this to your style block:

Code: Select all
.currentTab {
  display: block !important;
}

Then you can shorten your script to:

Code: Select all
function checked(event){
  var id = event.target.id;
  var elOld = document.querySelector('.currentTab');
  if (elOld) elOld.classList.remove('currentTab');
  var elNew = document.querySelector('[data-name="' + id + '"]');
  if (elNew) elNew.classList.add('currentTab'); else console.log('Did not find data-name: ' + id);
}

You raise a good question about why there isn't a change fired when a radio button becomes unchecked. I don't know, but my code wouldn't work correctly in that case.

Return to Web Development / Standards Evangelism


Who is online

Users browsing this forum: No registered users and 2 guests