I am going to try and explain this as clearly as I can.
I am working with some script from @Prabu Parthipan which uses JQuery to open and close child lists of parent lists.
I have a query that returns an array of data. In the array I have two fields:
SeqHeader SeqText
Each SeqHeader has variable number of SeqText items.
Example:
SeqHeader:Bedroom Door & Frame (inside & Outside)
SeqText:Chipped - Scratched - Stained - Needs Paint
SeqText:Chipped - Threshold - Sand/Stain - Repair
SeqText:Door Hinges - Squeaks/Sticks - Requires Oil/Repair
SeqHeader:Entry Door Lock
SeqText:Room Door Handle/Strike plate - Not Secure/Not Working
SeqText:Security Door Chain - Not Working
SeqText:Room Door Dead Lock - Not operating Correctly
SeqHeader:Bathroom Door Lock
SeqText:Door Handle/Strike plate - Not secure/Not Working
SeqText:Door Lock - Inoperable
I could display the above as rows using a PHP do while loop but I though it would be better to produce a list with sublists that open and close.
So adopting Prabu Parthipan code @Prabu Parthipan code is:
$(document).ready(function(){
$('ul li.expanded > a')
.attr('data-active','0')
.click(function(event){
$('.submuneu').hide();
if($(this).attr('data-active')==0){
$(this).parent().find('ul').slideToggle('slow');
$(this).attr('data-active','1');
}
else
$(this).attr('data-active','0');
});
$('a.on').click(function(){
$('a.on').removeClass("active");
$(this).addClass("active");
});
});
In the body of the page I have:
<?php do { ?>
<tr>
<td colspan="3" class="imaindateselleft_padding">
<div class="leftsidebar_templ1">
<ul id="nav">
<li class="expanded"><a class="on"><?php print $row_AuditItems['SeqHeader']; ?></a>
<ul class="submuneu">
<li><a><?php print $row_AuditItems['SeqText']; ?></a> </li>
</ul>
</li>
</ul>
</div>
</td>
<td class="imaindatesel"> </td>
</tr>
<?php } while ($row_AuditItems = mysql_fetch_assoc($AuditItems)); ?>
As it is when the page is loaded it displays a SeqHeader for each SeqText. They are clickable and when clicked they open up the sub list.
What I want to do is have all the SeqText items relating to thier parent SeqHeader as a sublist so when the SeqHeader is clicked all the related sub items show, and click again so they hide.
Sorry if I have rabbled on.
Any help would be great and I thank you for your time.
Cheers.
Wouldn't it make more since to make a simple to use multi-dimensional array of the items you're getting? As I gather, you're using the deprecated mysql
call to get rows of info from a DB. Each row will have the Header and the Text associated. Thus, if you call inline by each, row, you'll have a header for each row. Try the following instead.
<?php
$res = array();
while ($row = mysql_fetch_assoc($AuditItems)) {
if ($row['SeqHeader'] && $row['SeqText']) {
if (!$res[$row['SeqHeader']]) $res[$row['SeqHeader']] = array();
$res[$row['SeqHeader']][] = $row['SeqText'];
}
}
?>
<ul id="nav">
<?php foreach ($res as $k => $v): ?>
<li class="expanded">
<a class="on"><?php echo $k; ?></a>
<ul class="submuneu">
<?php foreach ($v as $item): ?>
<li><a><?php echo $item; ?></a></li>
<?php endforeach; ?>
</ul>
</li>
<?php endforeach; ?>
</ul>
I believe you're biggest problem now is in HTML layout. But this should help that. Fix that and then determine if the JS is still a problem, though what you want in JS is relatively easy.
Example of Easy JavaScript for dealing with opening and closing submenus using HTML Markup as:
UL > LI > A + UL > LI > A
// simply jQuery shorthand for document.ready = function() { ...
$(function() {
// the following is how to add events so that they work for even "dynamically" created elements.
// That is, elements created after code/page load.
$(document).on('click', 'li a', function(e) {
e.preventDefault(); // ensure it doesn't try to follow a link
// close all possible siblings and cousins
$(this).parents('li').each(function(i) { $(this).siblings().find('ul').slideUp(); });
// slide toggle current possible sub menu
$(this).next('ul').slideToggle(function() { if (!$(this).is(':visible')) $(this).find('ul').hide(); });
});
// uncomment the following line to ensure all sublist are closed,
// however, i strongly recommend this should be done using css
// $('ul ul').hide();
// change cursor for li elements having a sub menu
$('li').each(function(i) {
if ($(this).children('ul').length) { // test if it has a submenu
$(this).css({ cursor: 'pointer' });
// just for this test, i'm going to add a background color to A tags on li's having a submenu
$(this).children('a').css({ backgroundColor: '#f8f800' })
}
});
})
/* this simply hides all submenus outright */
ul ul { display: none; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul>
<li><a>test1</a>
<ul>
<li><a>bleh</a></li>
<li><a>bleh Blah</a>
<ul>
<li><a>blo</a></li>
<li><a>bli</a>
<li><a>blu</a>
<ul>
<li><a>orange</a></li>
<li><a>fruit</a></li>
<li><a>apple</a></li>
</ul>
</li>
<li><a>ble</a>
<ul>
<li><a>gravy</a></li>
<li><a>steak</a></li>
<li><a>bra</a></li>
</ul>
</li>
</li>
<li><a>testCc</a></li>
</ul>
</li>
</ul>
</li>
<li><a>test2</a>
<ul>
<li><a>testPrev</a>
<ul>
<li><a>testA</a></li>
<li><a>testB</a></li>
<li><a>testC</a></li>
</ul>
</li>
<li><a>testNext</a>
<ul>
<li><a>testAa</a></li>
<li><a>testBb</a>
<li><a>testPrev2</a>
<ul>
<li><a>testA1</a></li>
<li><a>testB2</a></li>
<li><a>testC3</a></li>
</ul>
</li>
<li><a>testNext4</a>
<ul>
<li><a>testAa4</a></li>
<li><a>testBb5</a></li>
<li><a>testCc6</a></li>
</ul>
</li>
</li>
<li><a>testCc</a></li>
</ul>
</li>
</ul>
</li>
<li><a>test3</a>
<ul>
<li><a>blah</a></li>
</ul>
</li>
</ul>
</div>
You could try:
$(document).ready(function(){
$('ul li.expanded > a')
.attr('data-active','0')
.click(function(event){
$('.submuneu').hide();
if($(this).attr('data-active')==0){
$(this).parent().find('ul').slideToggle('slow');
$(this).attr('data-active','1');
}
else
{
$(this).attr('data-active','0');
}
});
$(document).on('click', 'a.on', function(){
$('a.on').removeClass("active");
$(this).addClass("active");
});
});
Some -code generated- elements need to be "listen" using $(document).on('event', 'element', function(){...});
. Hope it helps.