Creating embedded unordered lists of checkboxes
I have a need to create a two-level unordered list of checkboxes from a two level taxonomy vocabulary. So for instance, if my vocabulary is - Level 1 term 1 -- Level 2 term 1 -- Level 2 term 2 -- Level 2 term 3 - Level 1 term 2 -- Level 2 term 4 -- Level 2 term 5 - Level 1 term 3 I want to create the following: <ul> <li><input type = checkbox">Level 1 term 1</li> <ul> <li><input type = checkbox">.Level 2 term 1</li> <li><input type = checkbox">Level 2 term 2</li> <li><input type = checkbox">Level 2 term 3</li> </ul> <li><input type = checkbox">Level 1 term 2</li> <ul> <li><input type = checkbox">Level 2 term 4</li> <li><input type = checkbox">Level 2 term 5</li> <ul> <li><input type = checkbox">Level 1 term 3<li> </ul> What is the best way to do this? Just use a checkboxes element type and create my own theme function for the form? Modify something like theme_item_list? Or is there a better (and easier) way that I'm missing? What I tried doing was to create a theme function for my checkboxes element by setting the #theme property for the element to my custom theme function (and registering the function in hook_theme). I then just made a copy of theme_checkboxes() (and theme_form_element since it's called from theme_form_checkboxes) and renamed to match hook_theme and the #theme property. However, when doing that, none of my checkboxes are rendered at all. On stepping through the code, I found the problem in drupal_render starting at line 2868: if (!isset($elements['#children'])) { $children = element_children($elements); // Render all the children that use a theme function. if (isset($elements['#theme']) && empty($elements['#theme_used'])) { $elements['#theme_used'] = TRUE; $previous = array(); foreach (array('#value', '#type', '#prefix', '#suffix') as $key) { $previous[$key] = isset($elements[$key]) ? $elements[$key] : NULL; } // If we rendered a single element, then we will skip the renderer. if (empty($children)) { $elements['#printed'] = TRUE; } else { $elements['#value'] = ''; } $elements['#type'] = 'markup'; unset($elements['#prefix'], $elements['#suffix']); $content = theme($elements['#theme'], $elements); foreach (array('#value', '#type', '#prefix', '#suffix') as $key) { $elements[$key] = isset($previous[$key]) ? $previous[$key] : NULL; } } // Render each of the children using drupal_render and concatenate them. if (!isset($content) || $content === '') { foreach ($children as $key) { $content .= drupal_render($elements[$key]); } } } So basically, because I have #theme set for the checkboxes field, it skips the rendering of the individual checkbox elements. To me, it makes sense that I override the theme function for the checkboxes type since that's the element type, but that doesn't seem to be the case. So what do I need to do to be able to simply theme my checkboxes element? Thanks. Steve
You can build multi-level select lists using the "children" element (read theme_list for a description). That should allow multi-level checkboxes. I've never tried it though. Nancy E. Wichmann, PMP Injustice anywhere is a threat to justice everywhere. -- Dr. Martin L. King, Jr. -----Original Message----- From: development-bounces@drupal.org [mailto:development-bounces@drupal.org] On Behalf Of Steve Edwards Sent: Wednesday, January 13, 2010 7:54 PM To: Drupal Development Subject: [development] Creating embedded unordered lists of checkboxes I have a need to create a two-level unordered list of checkboxes from a two level taxonomy vocabulary. So for instance, if my vocabulary is - Level 1 term 1 -- Level 2 term 1 -- Level 2 term 2 -- Level 2 term 3 - Level 1 term 2 -- Level 2 term 4 -- Level 2 term 5 - Level 1 term 3 I want to create the following: <ul> <li><input type = checkbox">Level 1 term 1</li> <ul> <li><input type = checkbox">.Level 2 term 1</li> <li><input type = checkbox">Level 2 term 2</li> <li><input type = checkbox">Level 2 term 3</li> </ul> <li><input type = checkbox">Level 1 term 2</li> <ul> <li><input type = checkbox">Level 2 term 4</li> <li><input type = checkbox">Level 2 term 5</li> <ul> <li><input type = checkbox">Level 1 term 3<li> </ul> What is the best way to do this? Just use a checkboxes element type and create my own theme function for the form? Modify something like theme_item_list? Or is there a better (and easier) way that I'm missing? What I tried doing was to create a theme function for my checkboxes element by setting the #theme property for the element to my custom theme function (and registering the function in hook_theme). I then just made a copy of theme_checkboxes() (and theme_form_element since it's called from theme_form_checkboxes) and renamed to match hook_theme and the #theme property. However, when doing that, none of my checkboxes are rendered at all. On stepping through the code, I found the problem in drupal_render starting at line 2868: if (!isset($elements['#children'])) { $children = element_children($elements); // Render all the children that use a theme function. if (isset($elements['#theme']) && empty($elements['#theme_used'])) { $elements['#theme_used'] = TRUE; $previous = array(); foreach (array('#value', '#type', '#prefix', '#suffix') as $key) { $previous[$key] = isset($elements[$key]) ? $elements[$key] : NULL; } // If we rendered a single element, then we will skip the renderer. if (empty($children)) { $elements['#printed'] = TRUE; } else { $elements['#value'] = ''; } $elements['#type'] = 'markup'; unset($elements['#prefix'], $elements['#suffix']); $content = theme($elements['#theme'], $elements); foreach (array('#value', '#type', '#prefix', '#suffix') as $key) { $elements[$key] = isset($previous[$key]) ? $previous[$key] : NULL; } } // Render each of the children using drupal_render and concatenate them. if (!isset($content) || $content === '') { foreach ($children as $key) { $content .= drupal_render($elements[$key]); } } } So basically, because I have #theme set for the checkboxes field, it skips the rendering of the individual checkbox elements. To me, it makes sense that I override the theme function for the checkboxes type since that's the element type, but that doesn't seem to be the case. So what do I need to do to be able to simply theme my checkboxes element? Thanks. Steve No virus found in this incoming message. Checked by AVG - www.avg.com Version: 9.0.725 / Virus Database: 270.14.133/2612 - Release Date: 01/13/10 02:35:00
I think you're on the right track. Check out: http://drupal.org/node/197578 which shows you how to render a checkboxes control into a table. You shouldn't technically need the form-item theme function to do what you're doing, but rather just a custom checkboxes theming form. I've done that successfully in D5, but it looks like it would work in D6. Note the direct calls to theme_checkbox in that function so that it renders each of the checkboxes properly Hope that helps, Dave On Jan 13, 2010, at 4:54 PM, Steve Edwards wrote:
I have a need to create a two-level unordered list of checkboxes from a two level taxonomy vocabulary. So for instance, if my vocabulary is
- Level 1 term 1 -- Level 2 term 1 -- Level 2 term 2 -- Level 2 term 3 - Level 1 term 2 -- Level 2 term 4 -- Level 2 term 5 - Level 1 term 3
I want to create the following:
<ul> <li><input type = checkbox">Level 1 term 1</li> <ul> <li><input type = checkbox">.Level 2 term 1</li> <li><input type = checkbox">Level 2 term 2</li> <li><input type = checkbox">Level 2 term 3</li> </ul> <li><input type = checkbox">Level 1 term 2</li> <ul> <li><input type = checkbox">Level 2 term 4</li> <li><input type = checkbox">Level 2 term 5</li> <ul> <li><input type = checkbox">Level 1 term 3<li> </ul>
What is the best way to do this? Just use a checkboxes element type and create my own theme function for the form? Modify something like theme_item_list? Or is there a better (and easier) way that I'm missing?
What I tried doing was to create a theme function for my checkboxes element by setting the #theme property for the element to my custom theme function (and registering the function in hook_theme). I then just made a copy of theme_checkboxes() (and theme_form_element since it's called from theme_form_checkboxes) and renamed to match hook_theme and the #theme property. However, when doing that, none of my checkboxes are rendered at all. On stepping through the code, I found the problem in drupal_render starting at line 2868:
if (!isset($elements['#children'])) { $children = element_children($elements); // Render all the children that use a theme function. if (isset($elements['#theme']) && empty($elements ['#theme_used'])) { $elements['#theme_used'] = TRUE;
$previous = array(); foreach (array('#value', '#type', '#prefix', '#suffix') as $key) { $previous[$key] = isset($elements[$key]) ? $elements [$key] : NULL; } // If we rendered a single element, then we will skip the renderer. if (empty($children)) { $elements['#printed'] = TRUE; } else { $elements['#value'] = ''; } $elements['#type'] = 'markup';
unset($elements['#prefix'], $elements['#suffix']); $content = theme($elements['#theme'], $elements);
foreach (array('#value', '#type', '#prefix', '#suffix') as $key) { $elements[$key] = isset($previous[$key]) ? $previous [$key] : NULL; } } // Render each of the children using drupal_render and concatenate them. if (!isset($content) || $content === '') { foreach ($children as $key) { $content .= drupal_render($elements[$key]); } } }
So basically, because I have #theme set for the checkboxes field, it skips the rendering of the individual checkbox elements. To me, it makes sense that I override the theme function for the checkboxes type since that's the element type, but that doesn't seem to be the case. So what do I need to do to be able to simply theme my checkboxes element?
Thanks.
Steve
There is a similar post somewhere on how to do radios in columns. The method I posted in a comment is much simpler than what that author suggests. It's really simple CSS. Nancy E. Wichmann, PMP Injustice anywhere is a threat to justice everywhere. -- Dr. Martin L. King, Jr. -----Original Message----- From: development-bounces@drupal.org [mailto:development-bounces@drupal.org] On Behalf Of David Metzler Sent: Wednesday, January 13, 2010 10:40 PM To: development@drupal.org Subject: Re: [development] Creating embedded unordered lists of checkboxes I think you're on the right track. Check out: http://drupal.org/node/197578 which shows you how to render a checkboxes control into a table. You shouldn't technically need the form-item theme function to do what you're doing, but rather just a custom checkboxes theming form. I've done that successfully in D5, but it looks like it would work in D6. Note the direct calls to theme_checkbox in that function so that it renders each of the checkboxes properly Hope that helps, Dave On Jan 13, 2010, at 4:54 PM, Steve Edwards wrote:
I have a need to create a two-level unordered list of checkboxes from a two level taxonomy vocabulary. So for instance, if my vocabulary is
- Level 1 term 1 -- Level 2 term 1 -- Level 2 term 2 -- Level 2 term 3 - Level 1 term 2 -- Level 2 term 4 -- Level 2 term 5 - Level 1 term 3
I want to create the following:
<ul> <li><input type = checkbox">Level 1 term 1</li> <ul> <li><input type = checkbox">.Level 2 term 1</li> <li><input type = checkbox">Level 2 term 2</li> <li><input type = checkbox">Level 2 term 3</li> </ul> <li><input type = checkbox">Level 1 term 2</li> <ul> <li><input type = checkbox">Level 2 term 4</li> <li><input type = checkbox">Level 2 term 5</li> <ul> <li><input type = checkbox">Level 1 term 3<li> </ul>
What is the best way to do this? Just use a checkboxes element type and create my own theme function for the form? Modify something like theme_item_list? Or is there a better (and easier) way that I'm missing?
What I tried doing was to create a theme function for my checkboxes element by setting the #theme property for the element to my custom theme function (and registering the function in hook_theme). I then just made a copy of theme_checkboxes() (and theme_form_element since it's called from theme_form_checkboxes) and renamed to match hook_theme and the #theme property. However, when doing that, none of my checkboxes are rendered at all. On stepping through the code, I found the problem in drupal_render starting at line 2868:
if (!isset($elements['#children'])) { $children = element_children($elements); // Render all the children that use a theme function. if (isset($elements['#theme']) && empty($elements ['#theme_used'])) { $elements['#theme_used'] = TRUE;
$previous = array(); foreach (array('#value', '#type', '#prefix', '#suffix') as $key) { $previous[$key] = isset($elements[$key]) ? $elements [$key] : NULL; } // If we rendered a single element, then we will skip the renderer. if (empty($children)) { $elements['#printed'] = TRUE; } else { $elements['#value'] = ''; } $elements['#type'] = 'markup';
unset($elements['#prefix'], $elements['#suffix']); $content = theme($elements['#theme'], $elements);
foreach (array('#value', '#type', '#prefix', '#suffix') as $key) { $elements[$key] = isset($previous[$key]) ? $previous [$key] : NULL; } } // Render each of the children using drupal_render and concatenate them. if (!isset($content) || $content === '') { foreach ($children as $key) { $content .= drupal_render($elements[$key]); } } }
So basically, because I have #theme set for the checkboxes field, it skips the rendering of the individual checkbox elements. To me, it makes sense that I override the theme function for the checkboxes type since that's the element type, but that doesn't seem to be the case. So what do I need to do to be able to simply theme my checkboxes element?
Thanks.
Steve
No virus found in this incoming message. Checked by AVG - www.avg.com Version: 9.0.725 / Virus Database: 270.14.133/2612 - Release Date: 01/13/10 02:35:00
Well, the problem with that is I've tried just that (creating my own custom checkboxes function), and as I said in the initial post, when it gets to my custom theme_checkboxes form, the #children have not been rendered since that step was skipped in drupal_render() simply because #theme was set for the checkboxes element. If I could get to my custom theme_checkboxes element with $element['#children'] set, I'd be fine, but that's what's throwing the wrench into things. Thanks. Steve On Jan 13, 2010, at 7:39 PM, David Metzler wrote:
I think you're on the right track. Check out:
which shows you how to render a checkboxes control into a table. You shouldn't technically need the form-item theme function to do what you're doing, but rather just a custom checkboxes theming form. I've done that successfully in D5, but it looks like it would work in D6. Note the direct calls to theme_checkbox in that function so that it renders each of the checkboxes properly
Hope that helps,
Dave
On Jan 13, 2010, at 4:54 PM, Steve Edwards wrote:
I have a need to create a two-level unordered list of checkboxes from a two level taxonomy vocabulary. So for instance, if my vocabulary is
- Level 1 term 1 -- Level 2 term 1 -- Level 2 term 2 -- Level 2 term 3 - Level 1 term 2 -- Level 2 term 4 -- Level 2 term 5 - Level 1 term 3
I want to create the following:
<ul> <li><input type = checkbox">Level 1 term 1</li> <ul> <li><input type = checkbox">.Level 2 term 1</li> <li><input type = checkbox">Level 2 term 2</li> <li><input type = checkbox">Level 2 term 3</li> </ul> <li><input type = checkbox">Level 1 term 2</li> <ul> <li><input type = checkbox">Level 2 term 4</li> <li><input type = checkbox">Level 2 term 5</li> <ul> <li><input type = checkbox">Level 1 term 3<li> </ul>
What is the best way to do this? Just use a checkboxes element type and create my own theme function for the form? Modify something like theme_item_list? Or is there a better (and easier) way that I'm missing?
What I tried doing was to create a theme function for my checkboxes element by setting the #theme property for the element to my custom theme function (and registering the function in hook_theme). I then just made a copy of theme_checkboxes() (and theme_form_element since it's called from theme_form_checkboxes) and renamed to match hook_theme and the #theme property. However, when doing that, none of my checkboxes are rendered at all. On stepping through the code, I found the problem in drupal_render starting at line 2868:
if (!isset($elements['#children'])) { $children = element_children($elements); // Render all the children that use a theme function. if (isset($elements['#theme']) && empty($elements['#theme_used'])) { $elements['#theme_used'] = TRUE;
$previous = array(); foreach (array('#value', '#type', '#prefix', '#suffix') as $key) { $previous[$key] = isset($elements[$key]) ? $elements[$key] : NULL; } // If we rendered a single element, then we will skip the renderer. if (empty($children)) { $elements['#printed'] = TRUE; } else { $elements['#value'] = ''; } $elements['#type'] = 'markup';
unset($elements['#prefix'], $elements['#suffix']); $content = theme($elements['#theme'], $elements);
foreach (array('#value', '#type', '#prefix', '#suffix') as $key) { $elements[$key] = isset($previous[$key]) ? $previous[$key] : NULL; } } // Render each of the children using drupal_render and concatenate them. if (!isset($content) || $content === '') { foreach ($children as $key) { $content .= drupal_render($elements[$key]); } } }
So basically, because I have #theme set for the checkboxes field, it skips the rendering of the individual checkbox elements. To me, it makes sense that I override the theme function for the checkboxes type since that's the element type, but that doesn't seem to be the case. So what do I need to do to be able to simply theme my checkboxes element?
Thanks.
Steve
I figured out the problem with the custom checkboxes theme function and drupal_render. Basically, drupal_render is assuming that I will render all of the children checkboxes in my custom theme function, so it doesn't do it itself. I just took the code from drupal_render and modified it slightly, and my children checkboxes are rendered: // Code from drupal_render() $children = element_children($element); foreach ($children as $key) { $content .= drupal_render($element[$key]); } $element['#children'] = $content; However, now I have another problem, and that is that the #title and #description values are being displayed twice. Stepping through the code shows that two theme functions are being called twice: theme_checkboxes in form.inc AND my custom theme checkboxes function. What I don't understand is why, since I explicitly defined a theme function for my checkboxes form element in my form definition: $form['site_sections'] = array( '#type' => 'checkboxes', '#title' => t('Site Sections'), '#options' => $options, '#description' => t('Test description'), '#theme' => 'section_permissions_checkboxes', ); This is even further demonstrated by looking at the rendered HTML for the form. <form id="section-permissions-admin-form" method="post" accept-charset="UTF-8" action="/user/6/section_permissions"> <div> <div class="form-item"> <label>Site Sections: </label> <div class="form-checkboxes"> <div class="form-item"> <label>Site Sections: </label> <div class="form-checkboxes"> <div id="edit-site-sections-917-wrapper" class="form-item"> </div> <div id="edit-site-sections-918-wrapper" class="form-item"> </div> <div id="edit-site-sections-923-wrapper" class="form-item"> </div> <div id="edit-site-sections-924-wrapper" class="form-item"> </div> <div id="edit-site-sections-925-wrapper" class="form-item"> </div> <div id="edit-site-sections-926-wrapper" class="form-item"> </div> <div id="edit-site-sections-927-wrapper" class="form-item"> </div> <div id="edit-site-sections-928-wrapper" class="form-item"> </div> <div id="edit-site-sections-919-wrapper" class="form-item"> </div> <div id="edit-site-sections-929-wrapper" class="form-item"> </div> <div id="edit-site-sections-930-wrapper" class="form-item"> </div> <div id="edit-site-sections-931-wrapper" class="form-item"> </div> <div id="edit-site-sections-932-wrapper" class="form-item"> </div> <div id="edit-site-sections-920-wrapper" class="form-item"> </div> <div id="edit-site-sections-933-wrapper" class="form-item"> </div> <div id="edit-site-sections-934-wrapper" class="form-item"> </div> <div id="edit-site-sections-921-wrapper" class="form-item"> </div> <div id="edit-site-sections-935-wrapper" class="form-item"> </div> <div id="edit-site-sections-936-wrapper" class="form-item"> </div> <div id="edit-site-sections-937-wrapper" class="form-item"> </div> <div id="edit-site-sections-938-wrapper" class="form-item"> </div> <div id="edit-site-sections-922-wrapper" class="form-item"> </div> </div> <div class="description">Test description</div> </div> </div> <div class="description">Test description</div> </div> Can anyone explain why this is happening? Thanks. Steve Begin forwarded message:
From: Steve Edwards <killshot91@gmail.com> Date: January 14, 2010 7:36:41 AM PST To: development@drupal.org Subject: Re: [development] Creating embedded unordered lists of checkboxes
Well, the problem with that is I've tried just that (creating my own custom checkboxes function), and as I said in the initial post, when it gets to my custom theme_checkboxes form, the #children have not been rendered since that step was skipped in drupal_render() simply because #theme was set for the checkboxes element. If I could get to my custom theme_checkboxes element with $element['#children'] set, I'd be fine, but that's what's throwing the wrench into things.
Thanks.
Steve
On Jan 13, 2010, at 7:39 PM, David Metzler wrote:
I think you're on the right track. Check out:
which shows you how to render a checkboxes control into a table. You shouldn't technically need the form-item theme function to do what you're doing, but rather just a custom checkboxes theming form. I've done that successfully in D5, but it looks like it would work in D6. Note the direct calls to theme_checkbox in that function so that it renders each of the checkboxes properly
Hope that helps,
Dave
On Jan 13, 2010, at 4:54 PM, Steve Edwards wrote:
I have a need to create a two-level unordered list of checkboxes from a two level taxonomy vocabulary. So for instance, if my vocabulary is
- Level 1 term 1 -- Level 2 term 1 -- Level 2 term 2 -- Level 2 term 3 - Level 1 term 2 -- Level 2 term 4 -- Level 2 term 5 - Level 1 term 3
I want to create the following:
<ul> <li><input type = checkbox">Level 1 term 1</li> <ul> <li><input type = checkbox">.Level 2 term 1</li> <li><input type = checkbox">Level 2 term 2</li> <li><input type = checkbox">Level 2 term 3</li> </ul> <li><input type = checkbox">Level 1 term 2</li> <ul> <li><input type = checkbox">Level 2 term 4</li> <li><input type = checkbox">Level 2 term 5</li> <ul> <li><input type = checkbox">Level 1 term 3<li> </ul>
What is the best way to do this? Just use a checkboxes element type and create my own theme function for the form? Modify something like theme_item_list? Or is there a better (and easier) way that I'm missing?
What I tried doing was to create a theme function for my checkboxes element by setting the #theme property for the element to my custom theme function (and registering the function in hook_theme). I then just made a copy of theme_checkboxes() (and theme_form_element since it's called from theme_form_checkboxes) and renamed to match hook_theme and the #theme property. However, when doing that, none of my checkboxes are rendered at all. On stepping through the code, I found the problem in drupal_render starting at line 2868:
if (!isset($elements['#children'])) { $children = element_children($elements); // Render all the children that use a theme function. if (isset($elements['#theme']) && empty($elements['#theme_used'])) { $elements['#theme_used'] = TRUE;
$previous = array(); foreach (array('#value', '#type', '#prefix', '#suffix') as $key) { $previous[$key] = isset($elements[$key]) ? $elements[$key] : NULL; } // If we rendered a single element, then we will skip the renderer. if (empty($children)) { $elements['#printed'] = TRUE; } else { $elements['#value'] = ''; } $elements['#type'] = 'markup';
unset($elements['#prefix'], $elements['#suffix']); $content = theme($elements['#theme'], $elements);
foreach (array('#value', '#type', '#prefix', '#suffix') as $key) { $elements[$key] = isset($previous[$key]) ? $previous[$key] : NULL; } } // Render each of the children using drupal_render and concatenate them. if (!isset($content) || $content === '') { foreach ($children as $key) { $content .= drupal_render($elements[$key]); } } }
So basically, because I have #theme set for the checkboxes field, it skips the rendering of the individual checkbox elements. To me, it makes sense that I override the theme function for the checkboxes type since that's the element type, but that doesn't seem to be the case. So what do I need to do to be able to simply theme my checkboxes element?
Thanks.
Steve
It is quite possible that I don't understand properly what you're trying to do, but I think a slightly different approach is warranted, because you'll have a hard time getting the nesting to work since your children array is only going to be one level deep, and drupal_render is always going to wrap your checkboxes in form item div tags (I think). Option 1 Storing a hierarchical array of values in #options and render the items in a bulleted list using theme_checkbox() calls in your custom theme. Just return the rendered text rather than walking the #children array. This is more akin to the first approach in the document that I sent you, only running bulleted lists instead of using theme_table. This assumes you want a flat array back and not a hierarchy of values. Option 2 would be to think about implementing a custom form element and writing your own expand (or process in D7) function. The expand function would build the right hierarchy with appropriate #tree=TRUE and theme functions for the individual checkboxes theme_li_checkbox maybe and theme_ul_checkbox to build the checkbox array correctly. See the expand_checboxes (d6) for a better example of how #options gets converted to child elements. Hope one of these approaches helps. Dave On Jan 14, 2010, at 10:21 AM, Steve Edwards wrote:
I figured out the problem with the custom checkboxes theme function and drupal_render. Basically, drupal_render is assuming that I will render all of the children checkboxes in my custom theme function, so it doesn't do it itself. I just took the code from drupal_render and modified it slightly, and my children checkboxes are rendered:
// Code from drupal_render() $children = element_children($element); foreach ($children as $key) { $content .= drupal_render($element[$key]); }
$element['#children'] = $content;
However, now I have another problem, and that is that the #title and #description values are being displayed twice. Stepping through the code shows that two theme functions are being called twice: theme_checkboxes in form.inc AND my custom theme checkboxes function. What I don't understand is why, since I explicitly defined a theme function for my checkboxes form element in my form definition:
$form['site_sections'] = array( '#type' => 'checkboxes', '#title' => t('Site Sections'), '#options' => $options, '#description' => t('Test description'), '#theme' => 'section_permissions_checkboxes', );
This is even further demonstrated by looking at the rendered HTML for the form.
<form id="section-permissions-admin-form" method="post" accept- charset="UTF-8" action="/user/6/section_permissions"> <div> <div class="form-item"> <label>Site Sections: </label> <div class="form-checkboxes"> <div class="form-item"> <label>Site Sections: </label> <div class="form-checkboxes"> <div id="edit-site-sections-917-wrapper" class="form-item"> </div> <div id="edit-site-sections-918-wrapper" class="form-item"> </div> <div id="edit-site-sections-923-wrapper" class="form-item"> </div> <div id="edit-site-sections-924-wrapper" class="form-item"> </div> <div id="edit-site-sections-925-wrapper" class="form-item"> </div> <div id="edit-site-sections-926-wrapper" class="form-item"> </div> <div id="edit-site-sections-927-wrapper" class="form-item"> </div> <div id="edit-site-sections-928-wrapper" class="form-item"> </div> <div id="edit-site-sections-919-wrapper" class="form-item"> </div> <div id="edit-site-sections-929-wrapper" class="form-item"> </div> <div id="edit-site-sections-930-wrapper" class="form-item"> </div> <div id="edit-site-sections-931-wrapper" class="form-item"> </div> <div id="edit-site-sections-932-wrapper" class="form-item"> </div> <div id="edit-site-sections-920-wrapper" class="form-item"> </div> <div id="edit-site-sections-933-wrapper" class="form-item"> </div> <div id="edit-site-sections-934-wrapper" class="form-item"> </div> <div id="edit-site-sections-921-wrapper" class="form-item"> </div> <div id="edit-site-sections-935-wrapper" class="form-item"> </div> <div id="edit-site-sections-936-wrapper" class="form-item"> </div> <div id="edit-site-sections-937-wrapper" class="form-item"> </div> <div id="edit-site-sections-938-wrapper" class="form-item"> </div> <div id="edit-site-sections-922-wrapper" class="form-item"> </div> </div> <div class="description">Test description</div> </div> </div> <div class="description">Test description</div> </div>
Can anyone explain why this is happening?
Thanks.
Steve
Begin forwarded message:
From: Steve Edwards <killshot91@gmail.com> Date: January 14, 2010 7:36:41 AM PST To: development@drupal.org Subject: Re: [development] Creating embedded unordered lists of checkboxes
Well, the problem with that is I've tried just that (creating my own custom checkboxes function), and as I said in the initial post, when it gets to my custom theme_checkboxes form, the #children have not been rendered since that step was skipped in drupal_render() simply because #theme was set for the checkboxes element. If I could get to my custom theme_checkboxes element with $element['#children'] set, I'd be fine, but that's what's throwing the wrench into things.
Thanks.
Steve
On Jan 13, 2010, at 7:39 PM, David Metzler wrote:
I think you're on the right track. Check out:
which shows you how to render a checkboxes control into a table. You shouldn't technically need the form-item theme function to do what you're doing, but rather just a custom checkboxes theming form. I've done that successfully in D5, but it looks like it would work in D6. Note the direct calls to theme_checkbox in that function so that it renders each of the checkboxes properly
Hope that helps,
Dave
On Jan 13, 2010, at 4:54 PM, Steve Edwards wrote:
I have a need to create a two-level unordered list of checkboxes from a two level taxonomy vocabulary. So for instance, if my vocabulary is
- Level 1 term 1 -- Level 2 term 1 -- Level 2 term 2 -- Level 2 term 3 - Level 1 term 2 -- Level 2 term 4 -- Level 2 term 5 - Level 1 term 3
I want to create the following:
<ul> <li><input type = checkbox">Level 1 term 1</li> <ul> <li><input type = checkbox">.Level 2 term 1</li> <li><input type = checkbox">Level 2 term 2</li> <li><input type = checkbox">Level 2 term 3</li> </ul> <li><input type = checkbox">Level 1 term 2</li> <ul> <li><input type = checkbox">Level 2 term 4</li> <li><input type = checkbox">Level 2 term 5</li> <ul> <li><input type = checkbox">Level 1 term 3<li> </ul>
What is the best way to do this? Just use a checkboxes element type and create my own theme function for the form? Modify something like theme_item_list? Or is there a better (and easier) way that I'm missing?
What I tried doing was to create a theme function for my checkboxes element by setting the #theme property for the element to my custom theme function (and registering the function in hook_theme). I then just made a copy of theme_checkboxes() (and theme_form_element since it's called from theme_form_checkboxes) and renamed to match hook_theme and the #theme property. However, when doing that, none of my checkboxes are rendered at all. On stepping through the code, I found the problem in drupal_render starting at line 2868:
if (!isset($elements['#children'])) { $children = element_children($elements); // Render all the children that use a theme function. if (isset($elements['#theme']) && empty($elements ['#theme_used'])) { $elements['#theme_used'] = TRUE;
$previous = array(); foreach (array('#value', '#type', '#prefix', '#suffix') as $key) { $previous[$key] = isset($elements[$key]) ? $elements [$key] : NULL; } // If we rendered a single element, then we will skip the renderer. if (empty($children)) { $elements['#printed'] = TRUE; } else { $elements['#value'] = ''; } $elements['#type'] = 'markup';
unset($elements['#prefix'], $elements['#suffix']); $content = theme($elements['#theme'], $elements);
foreach (array('#value', '#type', '#prefix', '#suffix') as $key) { $elements[$key] = isset($previous[$key]) ? $previous [$key] : NULL; } } // Render each of the children using drupal_render and concatenate them. if (!isset($content) || $content === '') { foreach ($children as $key) { $content .= drupal_render($elements[$key]); } } }
So basically, because I have #theme set for the checkboxes field, it skips the rendering of the individual checkbox elements. To me, it makes sense that I override the theme function for the checkboxes type since that's the element type, but that doesn't seem to be the case. So what do I need to do to be able to simply theme my checkboxes element?
Thanks.
Steve
participants (3)
-
David Metzler -
Nancy Wichmann -
Steve Edwards