I have a a taxonomy term select box (called "product_keyword") in a node that gets its options populated via the Reference Field Option Limit module. There are 3 other taxonomy term reference fields in the node that are responsible for limiting the "product_keyword" option list all the way down to a single option, and this part is working beautifully.

The "product_keyword" field is set to Required, so when you actually go in to edit the node, the "product_keyword" field appears to already have this one option selected. However, with the use of the Devel module, I have discovered that this is not the case. There is no #value for the "product_keyword." I have created a custom module (my very first one ever, in fact) to set this #value, but I am having trouble determining how to choose the right properties to set this. This response by Clive is what I'm trying to wrap my brain around.

My module code is using a hook_form_alter function that involves the use of #after_build:

    //Declare the callback for after_build for page node form
function set_keywords_form_alter(&$form, &$form_state, $form_id) {
  if ($form_id == 'part_node_form') {
    $form['#after_build'][] = 'set_keywords_after_build';

function set_keywords_after_build($form, &$form_state) {

The overall goal is to simply allow this field to be displayed in a view, but one complication is that these 7000+ nodes are being imported via the Feeds module, and the clients should not have to edit each node manually just to hit the Save button (which is the only way the problem can be solved now - VBO can't do it, nor can the Resave Nodes module). I'm not even sure if #after_build should be involved, and I am also ok with setting the field's #default_value instead of or in addition to the #value.


In the page array dropdown, for the keyword's select list options:

#options (Array, 1 element) 0 (String, 13 characters ) Inker Parts 

But under '#value," I'm just getting:

#value (String, 8 characters ) - None - 

Under another reference field, "Product Family," where things are functioning normally, I see:

#options (Array, 40 elements) 
_none (String, 8 characters ) - None - 
1401 (String, 5 characters ) AUTOZ

.......and so on

and for the #value:

    0 (String, 2 characters ) 1401 

In this example, "1401" is the tid, and "AUTOZ" is the term name.

  • did you used devel module – Adi Jan 4 '16 at 5:31
  • Yep, I can get you a screenshot if you'd like. – McTwist Jan 4 '16 at 5:54
  • then you can take any value of field using form alter – Adi Jan 4 '16 at 7:11
  • Here's where I'm at now: function set_keywords_after_build($form, &$form_state) { $keyword = $form['field_product_keyword']['und']['#options']; $form['field_product_keyword']['und']['#value'] = $keyword; $form['field_product_keyword']['und']['#default_value'] = $keyword; return $form; } I can set the #value and the #default_value in the node/edit form, but it doesn't appear when viewing the node. Running a VBO "Save Content" on the nodes doesn't update them; only manually clicking Save on the node/edit form will work. It feels like I'm missing one final piece. – McTwist Jan 4 '16 at 7:28
  • Any ideas? Should I have a hook_form_submit function in there, or maybe some simple like a rule? – McTwist Jan 5 '16 at 17:30

This question looks a little old, but here is an answer for you. Reading your comments you have

//Declare the callback for after_build for page node form
function set_keywords_form_alter(&$form, &$form_state, $form_id) {
    if ($form_id == 'part_node_form') {
        $form['#after_build'][] = 'set_keywords_after_build';

function set_keywords_after_build($form, &$form_state) {
    $keyword = $form['field_product_keyword']['und']['#options']; 
    $form['field_product_keyword']['und']['#value'] = $keyword;
    $form['field_product_keyword']['und']['#default_value'] = $keyword; 
    return $form; 

I applaud your efforts, especially that you are attempting to do this clean and proper with a hook_after_build. The hook_after_build allows your value setting code to run after the Reference Field Option Limit has done its adjustments, so you are certain to be getting the value you want.
I see one mistake in your code, and that is that #options is an array of Label => Value so that the form can display language in the select field instead of raw values. I think all you need is this one adjustment:

// remove the -None- option from the start, then set the next option
$keyword = array_shift(array_keys($form['field_product_keyword']['und']['#options']));
// this is safe because $form is not passed by reference, 
// do not do this on $form_state

When trying to do things like this, I find it helpful to look inside what it is I am manipulating. If you know the string of references that you need to access some data, you can print it on the form like this:

//Declare the callback for after_build for page node form
function set_keywords_form_alter(&$form, &$form_state, $form_id) {
    if ($form_id == 'part_node_form') {
        $form['#after_build'][] = 'set_keywords_after_build';

        // see what our options are, print them as text on the form:
        $form['some_text'] = array(
            '#markup' => '<p>'. $form['field_product_keyword']['und']['#options'][0] .'</p>',
            '#weight' => '-80'

As you have mentioned you are using the devel module, you could easily throw the #options array into a dpm() or krumo() inside the form alter and get it printed to your form page also.

  • Thanks for responding, as I am indeed still working on this problem. I tried this out, and it does appear to set the select list to the option. However, looking at the page array on the node edit page, it's listing the #default_value and #value as "-None-". There are three other term reference select lists in my form which are not involved in any funny business, so I've been looking at them for reference. Those fields' #default_value and #value are: #default_value (Array, 1 element) 0 (String, 2 characters ) 38 where "38" is the tid. What am I missing? – McTwist Jan 16 '16 at 8:13
  • Answer updated. It looks like you need to shift and discard the first thing off the options array, and then shift the second thing into your value. Also I added a link to the print tool I really like. Dpm() and krumo() are pretty nice, but some times I want a little different of a tool. – DeveloperWeeks Jan 18 '16 at 17:43
  • Eh, I'm getting server errors trying to plug this in, which means that I've reached my level of comprehension regarding Drupal code :( Where do I add in the set_keywords_explain function? – McTwist Jan 18 '16 at 19:29
  • You said that you built your first module for this solution, right? I am assuming from your code that this module is named set_keywords.module. Add a third function to that named set_keywords_explain and using the code from my github, or if you have the devel module enabled you could use dpm – DeveloperWeeks Jan 18 '16 at 19:34
  • Yes, and I've been looking at the Devel output, so I'll throw in a dpm. What will you be looking for? – McTwist Jan 18 '16 at 19:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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