1

I have an instance here where an existing textfield in a node form should be limited to enter only three possible values. I though it might be possible to alter the field to #type => 'select' and attach my '#options' as well. So I altered the form to:

function MYMODULE_form_alter(&$form, &$form_state, $form_id) {
  if ($form_id == 'MYCONTENTTYPE_node_form') {
    // dpm($form);
    $form['field_MYFIELD']['#type'] = 'select';
    $form['field_MYFIELD']['#title'] = 'Enter a value';
    $form['field_MYFIELD']['#options'] = array(
      1 => 'Value 1',
      2 => 'Value 2',
      3 => 'Value 3'
    );
  }
}

But when I now try to create a form like that, all I get is this error:

Fatal error: Cannot create references to/from string offsets nor overloaded objects in /Users/Shared/www/drupal.dev/includes/common.inc on line 6606

Is it even possible to change an existing field type like I want with a small custom module? Do I have to alter the submit function then as well? Please help!

3
  • 1
    Have a read through this, it's likely you need something more like $form['field_MYFIELD'][LANGUAGE_NONE][0]['value']['#type'] = 'select'];, etc
    – Clive
    Commented Apr 28, 2014 at 13:01
  • @Clive - Thank you a thousand times! I still was in the container ... Should I delete this question or attach the correct code in an answer?
    – leymannx
    Commented Apr 28, 2014 at 13:02
  • I think an answer with the code you used would be useful :)
    – Clive
    Commented Apr 28, 2014 at 13:06

2 Answers 2

3

The answer is: Yes! It is possible. All I did wrong when altering the form is that I changed the '#type' of the container instead of changing the type of the textfield itself. I had to go one level deeper:

function MYMODULE_form_alter(&$form, &$form_state, $form_id) {
  if ($form_id == 'MYCONTENTTYPE_node_form') {
    // dpm($form);
    $form['field_MYFIELD'][LANGUAGE_NONE][0]['value']['#type'] = 'select';
    $form['field_MYFIELD'][LANGUAGE_NONE][0]['value']['#options'] = array(
      1 => 'Value 1',
      2 => 'Value 2',
      3 => 'Value 3'
    );
    // #select doesn't need #size and #maxlength
    unset($form['field_MYFIELD'][LANGUAGE_NONE][0]['value']['#size']);
    unset($form['field_MYFIELD'][LANGUAGE_NONE][0]['value']['#maxlength']);
  }
}
3
  • 1
    Ah, that pesky value; I am always perplexed when I work with Form API as to which level attributes and other options should be changed on, even after a decade of Drupal development :P Commented May 8, 2018 at 2:52
  • I used you sample but in setting default_value, I have problem. although I set #default_value but there is no item selected in rendered field.
    – Mehrdad201
    Commented Oct 7, 2018 at 21:40
  • @leymannx Is this the same goes to drupal8 as well? I'm trying to convert select type field to 'textfield' by using $form['field_control_number'][LANGUAGE_NONE][0]['value']['#type'] = 'textfield'; but not working. Any idea on what is missing here?
    – Suraj
    Commented Aug 11, 2021 at 8:54
0

You can write a field formatter that will render select box for this field. It's very simple and didn't take many time to use it. API here: https://api.drupal.org/api/drupal/modules!field!field.api.php/group/field_formatter/7

I can help with this if you need.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.