Check Mark Tree in PHP

I have a checkmark 'tree'

[ ] a
[ ] a1
[ ] b
[ ] b1
[ ] b2

What HTML edits, as well as javascript or jquery code, can I use to make it so when someone clicks on the parent element the children elements get checked/unchecked.

Code used to generate the checkmark tree:

<?php
$arr = array(
  array('id'=>100, 'parent'=>0, 	'name'=>'a'),
  array('id'=>101, 'parent'=>0,		'name'=>'b'),
  array('id'=>102, 'parent'=>100,	'name'=>'a1'),
  array('id'=>103, 'parent'=>101,	'name'=>'b1'),
  array('id'=>104, 'parent'=>101,	'name'=>'b2')
);


$tree = buildTree($arr);
echo '<pre>';
print_r($tree);
echo '<hr><br>';
printTree($tree);
echo '</pre>';

function buildTree(array $elements, $parent = 0) {
    $branch = array();

    foreach ($elements as $element) {
        if ($element['parent'] == $parent) {
            $children = buildTree($elements, $element['id']);
            if ($children) {
                $element['children'] = $children;
            }
            $branch[] = $element;
        }
    }

    return $branch;
}

function printTree($tree) {
    if(!is_null($tree) && count($tree) > 0) {
        echo '<ul>';
        foreach($tree as $node) {
            echo '<li><input type="checkbox">'.$node['name'];
			if (isset($node['children'])){
				printTree($node['children']);
			}
            echo '</li>';
        }
        echo '</ul>';
    }
}

Open in new window

LVL 22
NerdsOfTechTechnology ScientistAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Julian HansenCommented:
Can we rather see the HTML output. This is an HTML / JavaScript question more than a PHP.
0
NerdsOfTechTechnology ScientistAuthor Commented:
This might not be nested right; thus, the PHP output is slightly involved.

<pre>
<ul>
	<li><input type="checkbox">a
		<ul>
			<li><input type="checkbox">a1</li>
		</ul>
	</li>
	<li><input type="checkbox">b
		<ul>
			<li><input type="checkbox">b1</li>
			<li><input type="checkbox">b2</li>
		</ul>
	</li>
</ul>
</pre>

Open in new window

0
Chris StanyonWebDevCommented:
Based on your HTML output, this should do what you need:

$(':checkbox', 'li').click(function() {
    var isChecked = $(this).is(':checked');
    $(this).next('ul').find(':checkbox').each(function () {
        $(this).prop('checked', isChecked);
    });
});

Open in new window

0
Determine the Perfect Price for Your IT Services

Do you wonder if your IT business is truly profitable or if you should raise your prices? Learn how to calculate your overhead burden with our free interactive tool and use it to determine the right price for your IT services. Download your free eBook now!

Julian HansenCommented:
Previous post did not take
Here is the post
HTML
<ul>
  <li><input type="checkbox">a
    <ul>
      <li><input type="checkbox"> a1</li>
    </ul>
  </li>
  <li><input type="checkbox"> b
    <ul>
      <li><input type="checkbox"> b1</li>
      <li><input type="checkbox"> b2</li>
    </ul>
  </li>
</ul>

Open in new window

jQuery
<script>
$(function() {
  $(':checkbox').click(function() {
    var state = $(this).prop('checked');
    $(this).closest('li').find(':checkbox').prop({checked: state});
  });
});
</script>

Open in new window

Working sample here
0
NerdsOfTechTechnology ScientistAuthor Commented:
It worked until I added label tags:

<ul>
	<li><input type="checkbox" name="org" id="a" value="a" ><label for="a" style="color: #000">a</label></li>
	<ul>
		<li><input type="checkbox" name="org" value="a1" id="a1"><label for="a1" style="color: #000">a1</label></li>
		<li><input type="checkbox" name="org" value="a2" id="a2"><label for="a2" style="color: #000">a2</label></li>
		<li><input type="checkbox" name="org" value="a3" id="a3"><label for="a3"  style="color: #aaa">a3 (d)</label></li>
		<li><input type="checkbox" name="org" value="a4" id="a4"><label for="a4"  style="color: #aaa">a4 (d)</label></li>
	</ul>
	<li><input type="checkbox" name="org" id="b" value="b" ><label for="b" style="color: #000">b</label></li>
	<li><input type="checkbox" name="org" id="c" value="c" ><label for="c"  style="color: #aaa">c (d)</label></li>
	<ul>
		<li><input type="checkbox" name="org" value="c1" id="c1"><label for="c1"  style="color: #aaa">c1 (d)</label></li>
	</ul>
</ul>
<br><hr>

Open in new window


How should I modify the jQuery to account for the nested labels and label's click function?
0
Chris StanyonWebDevCommented:
Couple of points. Firstly, the HTML that you've just posted is NOT valid HTML. You need to fix that first. The only element that can be a child of a UL is an LI. In your code you have a UL as a child of a UL. Here's what it should look like:

<ul>
    <li><input type="checkbox" name="org" id="a" value="a" ><label for="a" style="color: #000">a</label>
       <ul>
            <li><input type="checkbox" name="org" value="a1" id="a1"><label for="a1" style="color: #000">a1</label></li>
            <li><input type="checkbox" name="org" value="a2" id="a2"><label for="a2" style="color: #000">a2</label></li>
            <li><input type="checkbox" name="org" value="a3" id="a3"><label for="a3"  style="color: #aaa">a3 (d)</label></li>
            <li><input type="checkbox" name="org" value="a4" id="a4"><label for="a4"  style="color: #aaa">a4 (d)</label></li>
        </ul>
    </li>
    <li><input type="checkbox" name="org" id="b" value="b" ><label for="b" style="color: #000">b</label></li>
    <li><input type="checkbox" name="org" id="c" value="c" ><label for="c"  style="color: #aaa">c (d)</label>
        <ul>
            <li><input type="checkbox" name="org" value="c1" id="c1"><label for="c1"  style="color: #aaa">c1 (d)</label></li>
        </ul>
    </li>
</ul>

Open in new window

Once you've got that sorted, just change the next() call in the script to nextAll():

$(':checkbox', 'li').click(function() {
    var isChecked = $(this).is(':checked');
    $(this).nextAll('ul').find(':checkbox').each(function () {
        $(this).prop('checked', isChecked);
    });
});

Open in new window

1

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
NerdsOfTechTechnology ScientistAuthor Commented:
Thank you for the corrections and solutions! It works!
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
HTML

From novice to tech pro — start learning today.