Jonathan Lin
Jonathan Lin

Reputation: 124

Collapse many sections

I want to have many collapsing sections on a page, at the moment I can collapse one section like this, but how would I have many collapsing sections? Would I have to write a new function for each collapsible section? As my current code collapses a section based on the section ID.

Here is some code that is basically what I have:

<html>
<body>

Some text before

<div id=tbl name=tbl style="overflow:hidden;display:none">
<table border=1>
<tr><td>test</td></tr>
<tr><td>test</td></tr>
<tr><td>test</td></tr>
</table>
</div>

some text after

<script language="JavaScript" type="text/javascript">
<!--
function sizeTbl(h) {
  var tbl = document.getElementById('tbl');
  tbl.style.display = h;
}
// -->
</script> 
<br>
<a href="javascript:sizeTbl('none')">Hide</a>

<a href="javascript:sizeTbl('block')">Expand</a>

</body>
</html>

Upvotes: 0

Views: 623

Answers (5)

Mike Horstmann
Mike Horstmann

Reputation: 588

function sizeTbl(h, id) {
  var tbl = document.getElementById(id);
  tbl.style.display = h;
}
.checkStyleSheet{
  font-size: 20px;
  font-weight: strong;
  background-color: black;
  color: white;
  /*You can make your style by section if you find jQuery too hard, or just not
  pertinent to learn at the moment and you are forced to use PureJS and id each 
  element on an individual basis.*/

}

.firstGroup table{
  color: red;
}
<head>
<title>Pure JS - No jQuery</title>
</head>

<body>
<div>
for tbl
<a href="javascript:sizeTbl('none', 'tbl')">Hide</a>
<a href="javascript:sizeTbl('block', 'tbl')">Expand</a>
<p>
Some text before
</p>
<div id="tbl" name="tbl" style="overflow:hidden;display:none">
<table border="1">
<tr><td>test</td></tr>
<tr><td>test</td></tr>
<tr><td>test</td></tr>
</table>
</div>
<p>
some text after
</p>
</div>

<div>
for tbl2
<a href="javascript:sizeTbl('none', 'tbl2')">Hide</a>
<a href="javascript:sizeTbl('block', 'tbl2')">Expand</a>
<p>
Some text before
</p>
<p> Still fine with nesting </p>
<div>
<div id="tbl2" name="tbl2" style="overflow:hidden;display:none">
<table border="1">
<tr><td>test</td></tr>
<tr><td>test</td></tr>
<tr><td>test</td></tr>
</table>
</div>
<p>
some text after
</p>
</div>
</div>

<!-- Here, we style a group with red -->  
<section class="firstGroup">

  <div>
for tbl3 - RED
<a href="javascript:sizeTbl('none', 'tbl3')">Hide</a>
<a href="javascript:sizeTbl('block', 'tbl3')">Expand</a>
<p>
Some text before
</p>
<div id="tbl3" name="tbl3" style="overflow:hidden;display:none">
<table border="1">
<tr><td>test</td></tr>
<tr><td>test</td></tr>
<tr><td>test</td></tr>
</table>
</div>
<p>
some text after
</p>
</div>

<div>
for tbl4 - RED
<a href="javascript:sizeTbl('none', 'tbl4')">Hide</a>
<a href="javascript:sizeTbl('block', 'tbl4')">Expand</a>
<p>
Some text before
</p>
<div id="tbl4" name="tbl4" style="overflow:hidden;display:none">
<table border="1">
<tr><td>test</td></tr>
<tr><td>test</td></tr>
<tr><td>test</td></tr>
</table>
</div>
<p>
some text after
</p>
</div>

<div>
for tbl5 - RED
<a href="javascript:sizeTbl('none', 'tbl5')">Hide</a>
<a href="javascript:sizeTbl('block', 'tbl5')">Expand</a>
<p>
Some text before
</p>
<div id="tbl5" name="tbl5" style="overflow:hidden;display:none">
<table border="1">
<tr><td>test</td></tr>
<tr><td>test</td></tr>
<tr><td>test</td></tr>
</table>
</div>
  
</section>
<p>
some text after
</p>
</div>

<div>
for tbl6
<a href="javascript:sizeTbl('none', 'tbl6')">Hide</a>
<a href="javascript:sizeTbl('block', 'tbl6')">Expand</a>
<p>
Some text before
</p>
<div id="tbl6" name="tbl6" style="overflow:hidden;display:none">
<table border="1">
<tr><td>test</td></tr>
<tr><td>test</td></tr>
<tr><td>test</td></tr>
</table>
</div>
<p>
some text after
</p>
</div>
<!-- Note, that this solution is fine, and you can place your anchor tags anywhere.
     the same capabilty exists to find the table regardless of nesting however, you
     must ID every individual table, and therefore provide individual CSS for each.
     if you were to change your tables and your JS calls from your anchors to class
     based styling, then you would "show" or "hide" ALL tables from any anchor click
     of expand/hide.  You could probably solve that with classing your actual tables
     elements, and handle individual styling by id if necessary.  You could also create
     a "section" tag in html to class groups of tables (or as you're calling them columns?)

     If you do truly mean "columns" and you want to know how to have 1 table, with mult.
     columns you can selectively Hide/Show that's slightly different. See below:
     
--> 


<section class="checkStyleSheet">
  <!-- Notice the "section tag, which you can use to style groups of tables with individual id's if necessary -->
<div>
for tbl7
<a href="javascript:sizeTbl('none', 'tbl7')">Hide</a>
<a href="javascript:sizeTbl('block', 'tbl7')">Expand</a>
<p>
Some text before
</p>
<div id="tbl7" name="tbl7" columns="3" style="overflow:hidden;display:none">
<table border="1">
<tr>
  <td><a href="javascript: alert('JS to hide col');">H :</a><a href="javascript: alert('JS to show col');"> S</a></td>
  <td><a href="javascript: alert('JS to hide col');">H :</a><a href="javascript: alert('JS to show col');"> S</a></td>
  <td><a href="javascript: alert('JS to hide col');">H :</a><a href="javascript: alert('JS to show col');"> S</a></td>
</tr>
<tr><td>test</td><td>test</td><td>test</td></tr>
<tr><td>test</td><td>test</td><td>test</td></tr>
<tr><td>test</td><td>test</td><td>test</td></tr>
</table>
</div>
<p>
some text after
</p>
</div>

</section>

Hopefully this helps you with your Pure JS solution. :) Just keep in mind, that the more sections/columns you have, the more your code is going to fragment and become hard to maintain. If you want to learn how to show-remove columns let me know, and I can show you that as well. You just need to get your element's array position in the table, and then create a for loop on the parent table that goes into each following tr - (td) position and sets the style to "none" or back to "show." It's not that complex once you've seen it once or twice. Happy Coding!

Upvotes: 0

Mike Horstmann
Mike Horstmann

Reputation: 588

    $(document).ready(function(){
    	$('.fadeButton').on("click", function(){
       		$(this).closest("div").find("table").fadeToggle();
        });
    });d
table {
  display: hidden;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>

    <p>
        Some text before
    </p>

    <div id="table2">
      <button class="fadeButton">fader</button>
        <table class="table">
            <tr><td>test</td></tr>
            <tr><td>test</td></tr>
            <tr><td>test</td></tr>
        </table>
    </div>

    <div id="table3">
      <button class="fadeButton">fader</button>
        <p>inbetween some more text if you'd like?</p>
        <table class="table">
            <tr><td>test</td></tr>
            <tr><td>test</td></tr>
            <tr><td>test</td></tr>
        </table>
    </div>

    <div id="table4">
      <button class="fadeButton">fader</button>
        <table class="table">
            <tr><td>test</td></tr>
            <tr><td>test</td></tr>
            <tr><td>test</td></tr>
        </table>
    </div>

    <div id="table5">
      <button class="fadeButton">fader</button>
        <p>inbetween some more text if you'd like?</p>
        <h2>And some big words before</h2>
        <table class="table">
            <tr><td>test</td></tr>
            <tr><td>test</td></tr>
            <tr><td>test</td></tr>
        </table>
        <h2>or more after</h2>
    </div>

    <div id="table6">
      <button class="fadeButton">fader</button>
          <div> you could class this is a modal if you'd like
            <table class="table">
              <tr><td>test</td></tr>
              <tr><td>test</td></tr>
              <tr><td>test</td></tr>
            </table>
          <button> Even add buttons in your modals or whatever! </button>
          </div>
    </div>

    <p>
    some text after
    </p>

    <p> Now isn't that easier for 6 columns, and it's got some nesting flexibility too!</br> 
        I actually am trying to make it as easy as possible for you. I've been in the "just </br>
        get it done easier" but this function will handle as many </br>
        elements as you need! ;) 
    </p>

Upvotes: 0

Mike Horstmann
Mike Horstmann

Reputation: 588

I agree with @StephenTG about not necessarily needing an additional framework if you haven't asked. With that in mind you could instead go to the following link where you can relate all of the jQuery code I gave you to vanilla JS. :)

For your exact process however, I would recommend learning the very basic most command of "fadeToggle" in jQuery. It may take you a day to learn and interact with, but it is very extensible as where the code you're writing in vanilla JS is not.

"I want to have many collapsing sections on a page, at the moment I can collapse one section like this, but how would I have many collapsing sections? - jQuery is your fastest, and easiest process to save tons of hand coding and redundant typing, and pepper in some animations as well. - Would I have to write a new function for each collapsible section? - Either language will allow you to do this with 1 function, jQuery gives you more extensible ways to do it. my current code collapses a section based on the section ID. - jQuery can consume id's, classes, element names, objects, skip to parent or child objects, and reference siblings, closest, or find withing a tree. It's pretty much made for what you're asking. But again, per exact response in the code you're using, I would say that it can all be done in much more code than in jQuery.
- Also, if you were to look at the actual jQuery (unminified) you could reference the functions I mentioned, and read out the vanilla JS code as well.

Upvotes: 0

Mike Horstmann
Mike Horstmann

Reputation: 588

Even if you don't really know any jQuery, it would be in your best interest to use it in this event as it's really easy and focuses on what you want to do.

Here is a code sample showing you for an individual table below, if you want to perform the same general concept for multiple tables, you can do so by event delegation, or by adding another function for each new table, and id'ing those tables, you can also id your buttons and tables to work 1:1 if you'd like) There's more complex concepts that work better, but this is the simplest move into jQuery I could consider for you to get your feet wet since you weren't already using it.

Hope it helps!

/*
function sizeTbl(h) {
  var tbl = document.getElementById('tbl');
  tbl.style.display = h.val;
};
*/

//instead of your code above you jQuery would look like this below:
$(document).ready(function(){
	$('#fadeButton').on("click", function(){
   		$("#table2").fadeToggle(); 
	});
});

/* If you read more into event delegation you can figure out the way to
clearly define the tables and add triggers on buttons, mouseover events, click events etc, 
wherever and as often as you'd like. */

//This focuses on the jQuery fadeToggle function, link below:
//https://api.jquery.com/fadeToggle/
#table2 {
  display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<!--
withing the head of your html pages add as below:
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
this will bring in jQuery from the CDN-->  
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>

<p>
    Some text before
</p>

<div id="table2">
    <table>
        <tr><td>test</td></tr>
        <tr><td>test</td></tr>
        <tr><td>test</td></tr>
    </table>
</div>

<p>
some text after
</p>
<br>
    <button id="fadeButton">fader</button>

I added the CDN link and some links in the code you can use to see it in action or understand better. :)

Upvotes: 0

StephenTG
StephenTG

Reputation: 2657

Change your sizing function to something like:

function sizeTbl(h, id) {
  var tbl = document.getElementById(id);
  tbl.style.display = h;
}

and then pass it the id of the section you want it to control when you invoke it, like so:

<a href="javascript:sizeTbl('none', 'tbl')">Hide</a>

<a href="javascript:sizeTbl('block', 'tbl')">Expand</a>

Upvotes: 1

Related Questions