Adding attribute to option element using forms api : drupal 7
Solution 1
I'm afraid you're going to have to dig quite far down to do this, the #options
array is flattened in form_select_options()
and it doesn't currently include any way of adding attributes. This is the code:
$options .= '<option value="' . check_plain($key) . '"' . $selected . '>' . check_plain($choice) . '</option>';
As you can see there's simply no scope for attributes in there. You will be able to override this though, but it will involve implementing your own version of theme_select()
and your own FAPI property.
I haven't got time to flesh the entire thing out but in your theme file you would be doing something like this:
function MYTHEME_select($variables) {
$element = $variables['element'];
element_set_attributes($element, array('id', 'name', 'size'));
_form_set_class($element, array('form-select'));
return '<select' . drupal_attributes($element['#attributes']) . '>' . MYTHEME_form_select_options($element) . '</select>';
}
function MYTHEME_form_select_options($element) {
// Build up your own version of form_select_options here
// that takes into account your extra attribute needs.
// This will probably involve inspecting your custom FAPI property,
// which we'll call #extra_option_attributes
}
Refer to form_select_options for constructing MYTHEME_form_select_options
And your code in the form would be something like:
$form['select'] = array(
'#type' => 'select',
'#options' => array(1 => 'One', 2 => 'Two'),
'#extra_option_attributes' => array(
1 => array('title' => 'Test title'), // Attributes for option with key "1",
2 => array('title' => 'Test title'), // Attributes for option with key "2",
)
);
In MYTHEME_form_select_options()
you can then inspect the element's #extra_option_attributes
key (if one exists) to see if you need to physically add any more attributes in the HTML you create.
Hope that helps, I know it seems like a crazily long-winded way of doing what you need to but as far as I know it's the only way.
Solution 2
Tested
Try:
$form["tid"][1]['#attributes'] = array('title' => t('nooo chatter'));
instead of:
$form["tid"]
['#options']
[1]['#attributes'] = array('title' => t('nooo chatter'));
It is possible to add arbitrary attributes to elements this way. I discovered this after performing some tests based on this answer.
Vishal Khialani
I am a web developer and I work on drupal most of the time. I have travelled the world and worked in china, Taiwan and Indonesia for 7 years. Please feel free to connect with me at my BLOG
Updated on June 27, 2022Comments
-
Vishal Khialani almost 2 years
I want to add title="icons/icon_cart.gif" for each of the below options in my select list which is rendered using views.
After trying and reading many articles I can't seem to find the way to add this html into my form.
Below is my code.
function customchatter_form_alter(&$form, &$form_state, $form_id) { $form["tid"]["#options"][1]=t("nooo chatter"); // this works to change the label of the option but how do I add title="icons/icon- cart.gif" ? }
My html code:
<select id="edit-tid" name="tid" class="form-select"> <option value="All">- Any -</option> <option value="1">nooo chatter</option> <option value="2">Complaints Complaints</option> <option value="3">Gear & Gadgets</option> </select>
Cheers, Vishal
UPDATE I tried to update the code as per Clive's advice but the values are still not coming up right. Below is my story.
So below is the html output I am able to achieve but the title always seems to be the number 1.
<select id="edit-select" class="form-select" name="select"> <option value="1" title="1">One</option> <option value="2" title="1">Two</option> </select>
As you can see title is there but the value is wrong. Below is my form and the functions which I wrote.
My form:
$form['select'] = array( '#type' => 'select', '#options' => array(1 => 'One', 2 => 'Two'), '#title' => array(1 => 'One', 2 => 'Two') // I tried many combinations but nothing seems to work. );
My Theme functions.
function kt_vusers_select($variables) { $element = $variables['element']; element_set_attributes($element, array('id', 'name', 'size')); _form_set_class($element, array('form-select')); return '<select' . drupal_attributes($element['#attributes']) . '>' . kt_vusers_form_select_options($element) . '</select>'; } function kt_vusers_form_select_options($element, $choices = NULL) { if (!isset($choices)) { $choices = $element['#options']; } // array_key_exists() accommodates the rare event where $element['#value'] is NULL. // isset() fails in this situation. $value_valid = isset($element['#value']) || array_key_exists('#value', $element); // @vishal so there I have declared the variable to accept the values. $vtitle = isset($element['#title']) || array_key_exists('#title', $element); $value_is_array = $value_valid && is_array($element['#value']); $options = ''; foreach ($choices as $key => $choice) { if (is_array($choice)) { $options .= '<optgroup label="' . $key . '">'; $options .= form_select_options($element, $choice); $options .= '</optgroup>'; } elseif (is_object($choice)) { $options .= form_select_options($element, $choice->option); } else { $key = (string) $key; if ($value_valid && (!$value_is_array && (string) $element['#value'] === $key || ($value_is_array && in_array($key, $element['#value'])))) { $selected = ' selected="selected"'; } else { $selected = ''; } // @vishal this is where the variable is being used. $options .= '<option title="'.$vtitle.'" value="' . check_plain($key) . '"' . $selected . '>' . check_plain($choice) . '</option>'; } } return $options; }
below is the correct code for the last theme function
function kt_vusers_form_select_options($element, $choices = NULL, $vtitles=NULL) { // Build up your own version of form_select_options here // that takes into account your extra attribute needs. // This will probably involve inspecting your custom FAPI property, // which we'll call #extra_option_attributes if (!isset($choices)) { $choices = $element['#options']; $vtitles = array(); $vtitles = $element['#title']; } // array_key_exists() accommodates the rare event where $element['#value'] is NULL. // isset() fails in this situation. $value_valid = isset($element['#value']) || array_key_exists('#value', $element); $value_is_array = $value_valid && is_array($element['#value']); $options = ''; // print_r($vtitles);
while ( (list($key, $choice) = each($choices)) && (list($keytwo, $vtitle) = each($vtitles)) ) { // printf("%s => %s, %s => %s \n", $key1, $value1, $key2, $value2);
if (is_array($choice)) { $options .= '<optgroup label="' . $key . '">'; $options .= kt_vusers_form_select_options($element, $choice); $i++; // $options .= form_select_options($element, $vtitle); $options .= '</optgroup>'; } // end if if is_array elseif(is_object($choice)) { $options .= form_select_options($element, $choice->option); } // end of else if else { $key = (string) $key; if ($value_valid && (!$value_is_array && (string) $element['#value'] === $key || ($value_is_array && in_array($key, $element['#value'])))) { $selected = ' selected="selected"'; } else { $selected = ''; } // $options .= '<option title="'.$vtitle.'" value="' . check_plain($key) . '"' . $selected . '>' . check_plain($choice) . '</option>'; } $options .= '<option value="'. check_plain($key) .'" title="' . $vtitle . '"' . $selected .'>'. check_plain($choice) .'</option>'; } // end of choice return $options; } // end of function
-
SpaceBeers about 12 yearsYou win this round @Clive. You win this round. +1 for effort.
-
Vishal Khialani about 12 yearsclive I have updated the post I am able to get the title there in the html but the value always seem to be one.
-
Sharique almost 12 yearsIn my case I'm getting error "Undefined index: render element in theme() " on $element = $variables['element']; in theme.inc file.
-
Matt Fletcher about 11 years+1 because I don't think having negative rep on an answer that was in good faith is fair!
-
OhkaBaka over 10 yearsDamned depressing... theme solutions always feel dirty. Oh well.
-
Druvision over 10 yearsThanks @Clive for the inspiration. Here is how I did the same thing for checkboxes: drupal.stackexchange.com/questions/89226/…
-
Collins over 7 yearsThis didnt work for me, it added them outside of the options array, so nothing rendered for each element.