Johny Bony
Johny Bony

Reputation: 373

How to correct height of element after I have hidden its children?

I have a form which I run when I click on some radio input button.

<section>  
<Label>Question</Label>
<p> 
<input name='a' type='radio' value=1>value A<br/>
<input name='a' type='radio' value=2>value B<br/>
<input name='a' type='radio' value=3>value C<br/>
<input name='a' type='radio' value=4>valueD</p>
</section>

Also a css rules which I apply:

div.hidden {
    display: none;
    height: 0px;    
    };

The JS code:

$("input[type='radio']").on("click", function(){
 var allInputs = $(this).parent().find("input");
 var NonChk = $(allInputs).not("input:checked");
 hideSiblings(NonChk,"BR");       
});

When I click on some button all I want to see is the current line: input, text, br. The other lines should be hidden ... That successfuly happens but the height of the parent (tag p) not auto corrected (it seems like the inputs still have incorrect size - but IDK if this is the problem.

The question is simple: How do hide the lines of the inputs which are not selected?

This is the function which I write to hide siblings on the lines to be hidden.

function hideSiblings(o, tilNextTagName, hideCurrentTag = true, tilNextTagHide = true){
var i, n, si;
var maxTries = 10;
if ( hideCurrentTag==true )
 {
 $(o).hide();
 // console.log("this node input radio :");
 // console.log(o.nodeName);
 }

for (i=0; i<o.length; i++){
  si = o[i];
  for (n=0; n<maxTries; n++){
    si = si.nextSibling;
    if (typeof si.nodeName === "undefined" )
      return false; 
    if ( si.nodeName == tilNextTagName ){
      // console.log( si.nodeName+" === " + tilNextTagName );
      if ( tilNextTagHide == true )
        $(si).hide();
      return true;
      }
    else
     {
     $(si).wrap("<div class=hidden></div>").hide();
     break; // break inner loop
     }
    }
  }
}

Upvotes: 2

Views: 78

Answers (2)

John Boe
John Boe

Reputation: 3611

I have tested the code. The solution was very easy. The reason why br was not hidden was that the function returned before the br tag could be hidden. So I added one line and condition with $(si.nextSibling).hide(); on the right place. This way there is no need for structural changes.

function hideSiblings(o, tilNextTagName, hideCurrentTag = true, tilNextTagHide = true){
    var i, n, si;
    var maxTries = 10;
    if ( hideCurrentTag==true ) {
     $(o).hide();
     }

    for (i=0; i<o.length; i++){
      si = o[i];
      for (n=0; n<=maxTries; n++){
        si = si.nextSibling;
        if ( !si )
          break; // prevent crash
        if ( si.nextSibling.nodeName="BR" ){
             $(si.nextSibling).hide();
            }
        if ( si.nodeName == tilNextTagName ){
          if ( tilNextTagHide == tilNextTagName ){
            $(si).wrap("<div class=hidden></div>").hide();
            }
          return true;
          }
        else
         {
         $(si).wrap("<div class=hidden></div>").hide();
         }
        }
      }
}

Upvotes: 1

Furkan Poyraz
Furkan Poyraz

Reputation: 692

Your code should work if you make some minor changes like instead of using break tags I wrapped each radio button in a label and setting it's display to block. That now means that your allInputs selector doesn't work anymore since the html structure changed. To fix that just use the same selector that you used in your click event listener.

Example:

function hideSiblings(o, tilNextTagName, hideCurrentTag = true, tilNextTagHide = true){
var i, n, si;
var maxTries = 10;
if ( hideCurrentTag==true )
 {
 $(o).hide();
 // console.log("this node input radio :");
 // console.log(o.nodeName);
 }

for (i=0; i<o.length; i++){
  si = o[i];
  for (n=0; n<maxTries; n++){
    si = si.nextSibling;
    if (typeof si.nodeName === "undefined" )
      return false; 
    if ( si.nodeName == tilNextTagName ){
      // console.log( si.nodeName+" === " + tilNextTagName );
      if ( tilNextTagHide == true )
        $(si).hide();
      return true;
      }
    else
     {
     $(si).wrap("<div class=hidden></div>").hide();
     break; // break inner loop
     }
    }
  }
}

$("input[type='radio']").on("click", function(){
 var allInputs = $("input[type='radio']");
 var NonChk = $(allInputs).not("input:checked");
 hideSiblings(NonChk,"BR");       
});
div.hidden {
    display: none;
    height: 0px;    
}

p { background: orange; } 

label { display: block; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section>  
  <label>Question</label>
  <p>
    <label>
      <INPUT name='a' type='radio' value='1' /> value A
    </label>
    <label>
    <INPUT name='a' type='radio' value='2' /> value B
    </label>
    <label>
      <INPUT name='a' type='radio' value='3' /> value C
    </label>
    <label>
      <INPUT name='a' type='radio' value='4' /> valueD
    </label>
  </p>
</section>

Upvotes: 1

Related Questions