Follow-up to https://forum.backdropcms.org/forum/how-set-values-form:

  1. When setting the values of a short-text field which is allowed to have multiple values, the first value I set shows up on the form, but the second does not.

    I see in the dpm output that there is an 'add_more' form element for that field (the form has an 'Add more' button for additional values) but I don't know if that's relevant to my problem.
     

  2. The taxonomy (entity reference) fields have a structure like
    $form['taxonomy_vocabulary_1']['und'][0]['target_id'][#default_value] but setting the value to the term ID doesn't show anything on the form.

I did try saving the form to see if the values are saved even though they don't show up on the form, but they are not. Help?

Accepted answer

I did some improvement on the logic in my code and the select-list field is working now. So ... maybe it before wasn't getting to the right place to set the value. Sorry about that! :facepalm: But on the bright side, we can set that aside now.

Also the pictures are for a "normal" multi-valued short-text field, not an entity reference at all.

ETA: This is a kludge, but I can get it to work by copying over the 0th value's settings and then setting the ith value:

if ($i > 0) {
  $form[$field][LANGUAGE_NONE][$i] = $form[$field][LANGUAGE_NONE][0];
}
$form[$field][LANGUAGE_NONE][$i]['value']['#default_value'] = $value;

I don't know if this might create other problems though.

Most helpful answers

> I don't know if this might create other problems though.

This will create other problems. If you are editing a field with values in it, you will be removing the values set by the form builder - you will overwrite them with the values in the first element of the field.

[EDIT]

Actually, what I wrote above is not quite so. I mean, setting #default_value for those form elements will replace the existing value of the field (when editing an existing node), and instead it will prepopulate the form element with the default value you are setting there - but that's the normal and expected behavior when setting #default_value, anyway.  If you want to avoid that, you have to use a conditional assignment like

$form[MY_FIELD]['und'][0]['value']['#default_value'] = !empty($form[MY_FIELD]['und'][0]['value']['#default_value']) ? $form[MY_FIELD]['und'][0]['value']['#default_value'] : 'A new default value';

I just tried it with an Entity Reference field that references a Taxonomy Term, with unlimited cardinality, and this works for me:

$form['field_term_ref']['und'][0]['target_id']['#default_value'] = 'one (13)';

Where the default value matches the value shown in the widget when you type term "one" and then click to select it (this term has a tid of 13).

SO, just be sure the number in parenthesis IS the correct TID for the term, and be sure the name also matches. 

Lastly, it may be that your alter form is faulty. A very common rookie mistake I still make is to forget the have the ampersand in front of &$form in the list of parameters received by the alter function. This will result in any values not persist beyond the function itself. 

Comments

Please clarify:

Is the form element "taxonomy_vocabulary_1" a field? That's a weird name for a field. Fields usually start with "field_". 

If it is a field attached to a node, what kind of field is it? Taxonomy term reference? Entity reference? 

Yes, it is a field attached to one of my (node) content types, and yes, I agree that it is a weird name. In the D7 version of my site, before I converted it over, it did have a name like 'field_something'.

It is an Entity reference field that connects to taxonomy. The field is allowed to have multiple values.

I can paste the dpm output for this form field if it would help.

> I can paste the dpm output for this form field if it would help.

That would be helpful.

The structure looks correct for an Entity Reference field. The default value has to be a number, basically the Term ID that you are referencing, but this might depend on the widget. If you are using a Select list, then yes, it's the entity ID. If you are using an autocomplete widget, or something else (a View e.g.), the default value has to match what the widget returns to the submit handler (for example, for autocomplete, it's often something like "Term name [term_id]" 

Here you go:

taxonomy_vocabulary_1 (Array, 7 elements)

  • #type (String, 9 characters container

  • #attributes (Array, 1 element)

    • class (Array, 3 elements)

      • 0 (String, 26 characters field-type-entityreference

      • 1 (String, 32 characters field-name-taxonomy-vocabulary-1

      • 2 (String, 41 characters field-widget-entityreference-autocomplete

  • #weight (String, 1 characters 9

  • #tree (BooleanTRUE

  • #language (String, 3 characters und

  • und (Array, 14 elements)

  • #access (BooleanTRUE

 

Good to know re the expected value. One of the fields does use the Select List widget and the code is setting to a valid value, but it doesn't show on the form as entered, nor does it save. The other one (pasted above) uses an autocomplete ... I can certainly change the value set (once I figure out what it should be). Thanks.

I just tried it with an Entity Reference field that references a Taxonomy Term, with unlimited cardinality, and this works for me:

$form['field_term_ref']['und'][0]['target_id']['#default_value'] = 'one (13)';

Where the default value matches the value shown in the widget when you type term "one" and then click to select it (this term has a tid of 13).

SO, just be sure the number in parenthesis IS the correct TID for the term, and be sure the name also matches. 

Lastly, it may be that your alter form is faulty. A very common rookie mistake I still make is to forget the have the ampersand in front of &$form in the list of parameters received by the alter function. This will result in any values not persist beyond the function itself. 

Thanks! I was able to also get it to work on an autocomplete taxonomy field.

Unfortunately, the select list ones are still not working. As well as the multi-valued "normal" fields. 

The form for the latter ends up looking like this:

You can see the extra lines added for the additional names, but the names themselves are missing....

I used dpm after populating the form and it's showing that the additional value fields are deficient, e.g. the [0]['value'] of a multi-valued short-text field has all these entries:

But the [1+] equivalent have only the value that I set:

This must have something to do with the problem I'm having. No idea how to fix it though. :)

Let's tackle one at a time. Select list: what cardinality are you using for that field?

As for your picture: I've seen this in my sites a couple of weeks as well, and I think it's an entity reference bug, but I'm not sure. I switched to autocomplete (tags) in that case, which seemed to work. We can take a closer look and file a bug report on that one. 

OK, sounds good. I don't see a cardinality on the select list fields in the dpm output, nor on the autocomplete (tags) one.

I do see a cardinality entry on the short-text field pictured above and on the autocomplete (NOT tags) taxonomy fields that can have multiple values. Cardinality is -1 in both cases.

I am looking under $field_name['und'] for #cardinality. I actually checked the whole structure for the select-list fields and couldn't find it anywhere.

ETA: more details.

I did some improvement on the logic in my code and the select-list field is working now. So ... maybe it before wasn't getting to the right place to set the value. Sorry about that! :facepalm: But on the bright side, we can set that aside now.

Also the pictures are for a "normal" multi-valued short-text field, not an entity reference at all.

ETA: This is a kludge, but I can get it to work by copying over the 0th value's settings and then setting the ith value:

if ($i > 0) {
  $form[$field][LANGUAGE_NONE][$i] = $form[$field][LANGUAGE_NONE][0];
}
$form[$field][LANGUAGE_NONE][$i]['value']['#default_value'] = $value;

I don't know if this might create other problems though.

> I don't know if this might create other problems though.

This will create other problems. If you are editing a field with values in it, you will be removing the values set by the form builder - you will overwrite them with the values in the first element of the field.

[EDIT]

Actually, what I wrote above is not quite so. I mean, setting #default_value for those form elements will replace the existing value of the field (when editing an existing node), and instead it will prepopulate the form element with the default value you are setting there - but that's the normal and expected behavior when setting #default_value, anyway.  If you want to avoid that, you have to use a conditional assignment like

$form[MY_FIELD]['und'][0]['value']['#default_value'] = !empty($form[MY_FIELD]['und'][0]['value']['#default_value']) ? $form[MY_FIELD]['und'][0]['value']['#default_value'] : 'A new default value';

OK, so in my case, I am creating a new node, so there shouldn't be any issue with over-writing existing data. I looked at the form for a node with multiple entries added via the GUI in such a field, and there are differences between the other entries for the 0th vs the 1st vs the 2nd value, e.g.

For zeroth:

  und (Array, 15 elements)
    0 (Array, 15 elements)
      #entity_type (String, 4 characters ) node
      #entity (Object) Node
      #bundle (String, 6 characters ) review
      #field_name (String, 12 characters ) field_author
      #language (String, 3 characters ) und
      #field_parents (Array, 0 elements)
      #columns (Array, 2 elements)
      #title (String, 9 characters ) Author(s)
      #description (String, 0 characters )
      #required (Boolean) FALSE
      #delta (Integer) 0
      #weight (Integer) 0
      #title_display (String, 9 characters ) invisible
      value (Array, 18 elements)
        #entity_type (String, 4 characters ) node
        #entity (Object) Node
        #bundle (String, 6 characters ) review
        #field_name (String, 12 characters ) field_author
        #language (String, 3 characters ) und
        #field_parents (Array, 0 elements)
        #columns (Array, 2 elements)
        #title (String, 9 characters ) Author(s)
        #description (String, 0 characters )
        #required (Boolean) FALSE
        #delta (Integer) 1
        #weight (Integer) 1
        #title_display (String, 9 characters ) invisible
        #type (String, 9 characters ) textfield
        #default_value (String, 10 characters) John Smith
        #size (Integer) 60
        #attributes (Array, 1 element)
        #maxlength (String, 2 characters ) 35
      _weight (Array, 6 elements)

Vs for first:

    1 (Array, 15 elements)
      #entity_type (String, 4 characters ) node
      #entity (Object) Node
      #bundle (String, 6 characters ) review
      #field_name (String, 12 characters ) field_author
      #language (String, 3 characters ) und
      #field_parents (Array, 0 elements)
      #columns (Array, 2 elements)
      #title (String, 19 characters ) Author(s) (value 2)
      #description (String, 0 characters )
      #required (Boolean) FALSE
      #delta (Integer) 1
      #weight (Integer) 1
      #title_display (String, 9 characters ) invisible
      value (Array, 18 elements)
        #entity_type (String, 4 characters ) node
        #entity (Object) Node
        #bundle (String, 6 characters ) review
        #field_name (String, 12 characters ) field_author
        #language (String, 3 characters ) und
        #field_parents (Array, 0 elements)
        #columns (Array, 2 elements)
        #title (String, 19 characters ) Author(s) (value 2)
        #description (String, 0 characters )
        #required (Boolean) FALSE
        #delta (Integer) 1
        #weight (Integer) 1
        #title_display (String, 9 characters ) invisible
        #type (String, 9 characters ) textfield
        #default_value (String, 10 characters) Jane Smith
        #size (Integer) 60
        #attributes (Array, 1 element)
        #maxlength (String, 2 characters ) 35
      _weight (Array, 6 elements)

The #title, #delta, #weight, and value[#title] are different as I've marked in bold. Again, I don't know if this matters. It does seem to work.

Is there a better / more official way to add a second value to a multi-valued form field? If using the UI, I would have to click the button to "add another" and I'm guessing that's when the next entry gets populated.