Link to home
Start Free TrialLog in
Avatar of smfmetro10
smfmetro10Flag for United States of America

asked on

how do you have collapsible div's span multiple table cells

Hi,

I have a function that works but I need it to either open two div's based on one click or one div that spans two table cells.

Heres what I have:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript">

$(document).ready(function () {
    $("#toggle_all_dates").on('click', function () {
        var $this = $(this);
        
        if($this.hasClass('showAll')){
            $('#dates_list li div.moredates')
                .not(':visible')
                .prev()
                .each(function(idx,item){ toggleDate(item); });
        }else{
            $('#dates_list li div.moredates:visible')
                .prev()
                .each(function(idx,item){ toggleDate(item); });
        }
        
        $this.toggleClass('showAll');
        $(this).html($(this).text() == 'Hide all Dates and Locations' ? 'Show all  Dates and Locations' : 'Hide all Dates and Locations');
    });    
    
    $("#dates_list li a").on('click', function () {
        toggleDate(this);
    });
    
    function toggleDate(elem){
        var $elem = $(elem);
        $elem.next().slideToggle();
        $elem.html($elem.text() == '[-] Dates and Locations' ? '[+] Dates and Locations' : '[-] Dates and Locations');
    }
})

</script>



<style>
ul#dates_list{
    list-style-type: none;
    margin: 0;
    padding: 0;
}
ul#dates_list a{
    cursor: pointer;
}
ul#dates_list div.moredates {
    display: none;
} 
</style>
</head>

<body>

<a id="toggle_all_dates" class="moredates showAll">Show all Dates and Locations</a>

<ul id="dates_list">
<table id="mytable">
<tr>
<td>
    <li>
        <a>[+]Dates and Locations</a>
        <div class="moredates" data-collapsed="true">More dates one...</div> 
    </li>
    </td>
    <td>
    <li>
        <a>[+]Dates and Locations</a>
        <div class="moredates" data-collapsed="true">More dates two...</div> 
    </li>
    </td>
</tr></table>
</ul> 
</body>
</html>

Open in new window


Picture just clicking one of the "+ Dates and Locations" and opening both div's.

Thanks!
Avatar of quizwedge
quizwedge
Flag of United States of America image

I'm a bit confused. Are you looking for what happens when you click "Show all Dates and Locations"?

If so, just look at the following part of the code

("#toggle_all_dates").on('click', function () {
        var $this = $(this);
        
        if($this.hasClass('showAll')){
            $('#dates_list li div.moredates')
                .not(':visible')
                .prev()
                .each(function(idx,item){ toggleDate(item); });
        }else{
            $('#dates_list li div.moredates:visible')
                .prev()
                .each(function(idx,item){ toggleDate(item); });
        }
        
        $this.toggleClass('showAll');
        $(this).html($(this).text() == 'Hide all Dates and Locations' ? 'Show all  Dates and Locations' : 'Hide all Dates and Locations');
    });    

Open in new window


That code could be simplified a bit, but that's the part that is figuring out what needs to be hidden or shown. The actual hiding/showing is done by the toggleDate function.
Avatar of smfmetro10

ASKER

Hi. Thanks for the response. I would like the code to function the way it is. With the  show all dates and locations opening all divs( even when some are all ready open)

The trick is I need it to function across two table cells. So clicking one of the <a>date links will open two divs ( or one div doesn't really matter) that lives in two separate table cells.

Right now each div lives in its own table cell

I know that seems odd, it's just the way the code is written now. I can clarify more if need be.

Thanks!
If you just want "+ Dates and Locations" to open the same divs that Show all Dates and Locations does, you can update the on click function for $("#dates_list li a") to the following

$("#dates_list li a").on('click', function () {
        $('#dates_list li div.moredates')
                .not(':visible')
                .prev()
                .each(function(idx,item){ toggleDate(item); });
        
    });

Open in new window


Do you want to support closing as well? Did I miss what you're asking for again?
A div spanning more than one cell would be invalid markup and be prone to reliability issues.

I would just take the simple approach of giving each of the divs an id so you can just directly address the two divs affected by the click. There is no need for complex or convoluted solutions; it is a simple effect.

Cd&
Why don't you use a <td> that has a colspan of 2 instead?
Sorry if I haven't explained it well enough.

How about this?  I would like it to function like this with one difference.  There should only be one "[+] Dates and Locations" for every two divs... One will hold the dates and the other div holds the locations.  (the locations is part of an inner loop).

However the id's (if there are any) have to be dynamic because this first checks to see if there is more than one record for a particular date and if so will put this in so the user can see more dates and locations for a particular seminar.

Also the show all dates and locations can't just toggle the div's. Because then they could get "out of secquence". So "Show all Dates and Locations" will be displayed until all the div's are open. THEN the hide all dates will appear:

So If I could figure out how to make only  one [+] Dates and Locations open up both the dates div and the locations div, I think I would have it.

Here is what I have so far:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript">

$(document).ready(function () {
    $("#toggle_all_dates").on('click', function () {
        var $this = $(this);
        
        if($this.hasClass('showAll')){
            $('#dates_list li div.moredates')
                .not(':visible')
                .prev()
                .each(function(idx,item){ toggleDate(item); });
        }else{
            $('#dates_list li div.moredates:visible')
                .prev()
                .each(function(idx,item){ toggleDate(item); });
        }
        
        $this.toggleClass('showAll');
        $(this).html($(this).text() == 'Hide all Dates and Locations' ? 'Show all  Dates and Locations' : 'Hide all Dates and Locations');
    });    
    
    $("#dates_list li a").on('click', function () {
        toggleDate(this);
    });
    
    function toggleDate(elem){
        var $elem = $(elem);
        $elem.next().slideToggle();
        $elem.html($elem.text() == '[-] Dates and Locations' ? '[+] Dates and Locations' : '[-] Dates and Locations');
    }
})

</script>



<style>
ul#dates_list{
    list-style-type: none;
    margin: 0;
    padding: 0;
}
ul#dates_list a{
    cursor: pointer;
}
ul#dates_list div.moredates {
    display: none;
} 
</style>
</head>

<body>

<a id="toggle_all_dates" class="moredates showAll">Show all Dates and Locations</a>

<ul id="dates_list">
<table id="mytable">
<tr>
<td>
    <li>
        <a>[+]Dates and Locations</a>
        <div class="moredates" data-collapsed="true">More dates one...</div> 
    </li>
    </td>
    <td>
    <li>
        <a>[+]Dates and Locations</a>
        <div class="moredates" data-collapsed="true">More Locations two...</div> 
    </li>
    </td>
</tr></table>
</ul> 
</body>
</html>

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of quizwedge
quizwedge
Flag of United States of America 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
Thank You Thank You Thank You!!!!  It's exactly what I need!!!

Just out of curiosity, is it possible to have this work without the <li>'s?

Just wondering.... THANKS!!!!!
NP. Sure, you can do it without the <li>'s. I just took li out of everywhere in the code.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript">

$(document).ready(function () {
    $("#toggle_all_dates").on('click', function () {
        var $this = $(this);
        var setToHideAll = false;
        
        if($this.hasClass('showAll')){
            $('#dates_list div.moredates')
                .not(':visible')
                .prev()
                .each(function(idx,item){ toggleDate(item); });
                setToHideAll = true;
        }else{
            $('#dates_list div.moredates:visible')
                .prev()
                .each(function(idx,item){ toggleDate(item); });
        }
        
        updateShowAll(setToHideAll);
    });    
    
    $("#dates_list a").on('click', function () {
        toggleDate(this);
    });
    
    function updateShowAll(setToHideAll){
        if (setToHideAll) {
            $('#toggle_all_dates').removeClass('showAll');
            $('#toggle_all_dates').html('Hide all Dates and Locations');
        } else {
            $('#toggle_all_dates').addClass('showAll');
            $('#toggle_all_dates').html('Show all  Dates and Locations');
        }
    }

    function toggleDate(elem){
        var $elem = $(elem);
        var setToHideAll = false;
        console.log($elem.closest('tr').find('div.moredates').is(':visible'))
        console.log($('#dates_list div.moredates:visible').length);
        console.log($('#dates_list div.moredates').length);
        if(! $elem.closest('tr').find('div.moredates').is(':visible') && $('#dates_list div.moredates:visible').length === $('#dates_list div.moredates').length - 2){
            setToHideAll = true;
        }
        $elem.closest('tr').find('div.moredates').slideToggle();
        $elem.html($elem.text() == '[-] Dates and Locations' ? '[+] Dates and Locations' : '[-] Dates and Locations');

        updateShowAll(setToHideAll);

    }
})

</script>



<style>
ul#dates_list{
    list-style-type: none;
    margin: 0;
    padding: 0;
}
ul#dates_list a{
    cursor: pointer;
}
ul#dates_list div.moredates {
    display: none;
} 
</style>
</head>

<body>

<a id="toggle_all_dates" class="moredates showAll">Show all Dates and Locations</a>

<ul id="dates_list">
<table id="mytable">
<tr>
<td>
    <a>[+]Dates and Locations</a>
    <div class="moredates" data-collapsed="true">More dates one...</div> 
</td>
<td>
    <div class="moredates" data-collapsed="true">More Locations one...</div> 
</td>
</tr>
<tr>
<td>
    <a>[+]Dates and Locations</a>
    <div class="moredates" data-collapsed="true">More dates two...</div> 
</td>
<td>
    <div class="moredates" data-collapsed="true">More Locations two...</div> 
</td>
</tr></table>
</ul> 
</body>
</html>

Open in new window