[development] Fwd: Creating embedded unordered lists of checkboxes

Steve Edwards killshot91 at gmail.com
Thu Jan 14 18:21:53 UTC 2010


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 at gmail.com>
> Date: January 14, 2010 7:36:41 AM PST
> To: development at 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:
>> 
>> 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
>>> 
>> 
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.drupal.org/pipermail/development/attachments/20100114/8ec2813c/attachment-0001.html 


More information about the development mailing list