Adding attribute to option element using forms api : drupal 7
Asked Answered
V

3

7

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 &amp; 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
Valeriavalerian answered 13/2, 2012 at 13:17 Comment(1)
Their is an open issue about that drupal.org/node/342316Jesuit
S
14

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.

Scuba answered 13/2, 2012 at 17:0 Comment(5)
You win this round @Clive. You win this round. +1 for effort.Ob
clive I have updated the post I am able to get the title there in the html but the value always seem to be one.Valeriavalerian
In my case I'm getting error "Undefined index: render element in theme() " on $element = $variables['element']; in theme.inc file.Caul
Damned depressing... theme solutions always feel dirty. Oh well.Asshur
Thanks @Scuba for the inspiration. Here is how I did the same thing for checkboxes: drupal.stackexchange.com/questions/89226/…Wildwood
R
1

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.

Also mentioned here and here.

Ruyle answered 14/4, 2014 at 22:23 Comment(1)
This didnt work for me, it added them outside of the options array, so nothing rendered for each element.Wyattwyche
O
0

Untested, but have you tried:

$form["tid"]["#options"][1]['#attributes'] = array('title' => t('YOUR NEW TITLE'));

You might need to mess around with the name of the element etc but the #attributes tag should work.

EDIT: As pointed out in Clive's answer, this won't work but I'll leave it up in case anyone wants to know how to add attributes to other fields (textboxes etc).

Ob answered 13/2, 2012 at 15:20 Comment(1)
+1 because I don't think having negative rep on an answer that was in good faith is fair!Gulosity

© 2022 - 2024 — McMap. All rights reserved.