I found 2 problems when attempting to use existing drupal architecture:
form.inc:
- form_process_radios($element) - does not support the option for specifying a class per radio.
- theme_form_element($variables) - does not support setting a class (per element/div) and is not hookable
Setting a class per input (or parent element div) allows for more advanced javascript interactions and CSS styling. In my case, highlighting certain inputs based on grouped associations and also hiding those grouped inputs. Note that providing multiple groups of grouped inputs was possible but also overkill for my scenario and over complex.
I was able to provide a class per radio input as follows (form_process_radios() change):
// !DD TODO : resolve this CORE hack that allows for class per input radio (workflow_addons is dependant)
if(isset($element['#individual_classes'])) {
// ensure $key exists in #individual_classes ?
$element[$key]['#attributes']['class'][] = $element['#individual_classes'][$key];
}
Usage:
$form['workflow']['workflow_assign_user'] = array(
'#type' => 'radios',
'#title' => 'Assign user: (current: '.$currentUser.')',
'#options' => array('radio-value-1'=>'This could be red', 'radio-value-2'=>'This could be blue'),
'#name' => 'workflow_assign_user',
// !DD TODO : this relies on a hack from me in the core. RESOLVE.
'#individual_classes' => array('radio-value-1' => 'css-class-red', 'radio-value-2' => 'css-class-blue'),
);
This works as desired. Ideally though the class should be applied to the form element div that wraps the input and label.
Full function with change below:
/**
* Expands a radios element into individual radio elements.
*/
function form_process_radios($element) {
if (count($element['#options']) > 0) {
$weight = 0;
foreach ($element['#options'] as $key => $choice) {
// Maintain order of options as defined in #options, in case the element
// defines custom option sub-elements, but does not define all option
// sub-elements.
$weight += 0.001;
$element += array($key => array());
// Generate the parents as the autogenerator does, so we will have a
// unique id for each radio button.
$parents_for_id = array_merge($element['#parents'], array($key));
$element[$key] += array(
'#type' => 'radio',
'#title' => $choice,
// The key is sanitized in drupal_attributes() during output from the
// theme function.
'#return_value' => $key,
// Use default or FALSE. A value of FALSE means that the radio button is
// not 'checked'.
'#default_value' => isset($element['#default_value']) ? $element['#default_value'] : FALSE,
'#attributes' => $element['#attributes'],
'#parents' => $element['#parents'],
'#id' => drupal_html_id('edit-' . implode('-', $parents_for_id)),
'#ajax' => isset($element['#ajax']) ? $element['#ajax'] : NULL,
'#weight' => $weight,
);
// !DD TODO : resolve this CORE hack that allows for class per input radio (workflow_addons is dependant)
if(isset($element['#individual_classes'])) {
// ensure $key exists in #individual_classes ?
$element[$key]['#attributes']['class'][] = $element['#individual_classes'][$key];
}
}
}
return $element;
}
Comments
Comment #1
dynamicdan commentedwith advice, setting to bug. Next step would be to set to 8.x I guess if there's still not attention/interest in this.
Comment #2
attiks commentedThis has to be fixed in Drupal 8 first, if you can provide a patch I'll review it.
Comment #13
catchThis is an API improvement so should be a task.
Comment #14
acbramley commentedIf it's a task then it's not a bug to smash, right? :P