1

This is a problem that's been bugging me for days now and haven't yet found a solution in Drupal 7.

I'll be more specific:

I have a content type named Debate and another one called Vote. Vote type has a node reference field to Debate type.

Debate type has a term reference field (autocomplete widget, 4 values, Voting choices vocabulary) where user inserts the voting choices of his Debate node.

Vote type has a term reference field (select list, 1 value, Voting choices vocabulary) where user can choose a term to vote.

My problem is that the select list of the term reference field of the Vote node shows all the terms of the Voting choices vocabulary. What I want is the select list of the Vote node to show only the terms that come from the Debate node it's referring to.

In other words I need to filter out the terms of the Vote node based on the Debate node it's referring to, when I'm at the node/add/Vote form of course.

4
  • this would require a bit of back end coding is that something you are comfortable with? – Mohammed Shameem Feb 1 '13 at 12:28
  • Hello Mohammed thanks for the prompt reply. Please feel free to show me the code and i'll give my best to understand and apply it. – Billy Feb 1 '13 at 12:48
  • You can use the hook_form_alter() to restrict the values from this field in the node form. api.drupal.org/api/drupal/modules!system!system.api.php/… – revagomes Feb 1 '13 at 13:07
  • Thanks but please be more specific. Also note the following link: voices.yahoo.com/… which describes exactly what i want to accomplish but in Drupal 6. – Billy Feb 1 '13 at 13:13
1

First you would create a form alter function and make the taxonomy field as hidden and add ajax functionality to the node reference field. I am assuming that then node reference field widget is a select list.

For the following example I am assuming your fields are in the Basic Page. you can change the function name to suite your requirement by changing the mymodulename and page.

I am assuming the field name of the term reference field is field_vote and the node reference field is field_debate

function mymodulename_form_page_node_form_alter(&$form, &$form_state, $form_id) {
  // We add the ajax functionality to the node reference field.
  $form['field_debate']['#ajax'] = array(
    // #ajax has two required keys: callback and wrapper.
    // 'callback' is a function that will be called when this element changes.
    'callback' => 'vote_field_return',
    // 'wrapper' is the HTML id of the page element that will be replaced.
    'wrapper' => 'replace_vote_div',
  );

  // Add a wrapper around the taxonomy field.
  $form['#prefix'] = '<div id="replace_vote_div">';
  $form['#suffix'] = '</div>';

  // Check the form state to see if the debate field is filled.
  if (!empty($form_state['values']['field_debate'])) {
    // Load the debate node.
    $debate = node_load($form_state['values']['field_debate']);

    $form['field_vote']['#type'] = 'select';

    // Assuming the taxonomy field in debate content type is field_vote_debate
    // Some times the language for the field might be different from the language of
    // the node itself in this case you might want to look at a dump of the $date
    // field and make the required changes. 
    foreach($debate->field_vote_debate['$debate->language'] as $vote_term) {
      $form['field_vote']['#options'][$vote_term['taxonomy_term']->tid] = $vote_term['taxonomy_term']->name;
    }
  }
  else {
    // Hide the taxonomy field to start of with.
    $form['field_vote']['#type'] = 'hidden';
  }
}

The call back function is pretty straight forward we simply return the field_vote so that it can be rendered again in the form

function vote_field_return($form, $form_state) {
  // The form has already been submitted and updated. We can return the replaced
  // item as it is.
  return $form['field_vote'];
}

Note: As per the comment Please find below the updated code if the node ID is coming from url

I am assuming that the url to add the vote node is as follows

http://example.com/node/add/vote/23

where 23 is the node ID of the debate content type.

function mymodulename_form_vote_node_form_alter(&$form, &$form_state, $form_id) {
  // We use the arg() function to get the argument from the url. The numbering
  // starts from 0 and the one we need would be at 3. 
  $debate = node_load(arg(3));



  // Assuming the taxonomy field in debate content type is field_vote_debate.
  // Some times the language for the field might be different from the language of
  // the node itself in this case you might want to look at a dump of the $date
  // field and make the required changes. 

  foreach($debate->field_please_vote['$debate->language'] as $vote_term) {
    $term = taxonomy_term_load($vote_term['tid']); 
    $form['field_vote']['und']['#options'][$vote_term['tid']] = $term->name;
  }  
}
33
  • Hey Mohammed thanks for the code. I forgot to mention though that my node reference field has the "from URL widget" and not select list. SO how does this change your code? – Billy Feb 1 '13 at 19:07
  • aha that would make it even more easier. since we might not need the ajax at all. and just one function would be enough. Just the form alter function. I have added that as well. – Mohammed Shameem Feb 2 '13 at 4:00
  • Thanks again Mohammed. So i assume that i will create a module and add the above code correct? Sorry with the dumb question just need to be sure. A last thing. What do you mean by: // Some times the language for the field might be different from the language of // the node itself in this case you might want to look at a dump of the $date // field and make the required changes. – Billy Feb 2 '13 at 8:13
  • you can create in either in a module or in template.php. As for language the main language of the node and the field might be different. – Mohammed Shameem Feb 2 '13 at 8:15
  • Hello there Mohammmed. I tried in template.php but gives me some errors. Here's the code i use: function bartik_form_vote_node_form_alter(&$form, &$form_state, $form_id) { $debate = node_load(arg(3)); $form['field_please_vote']['#type'] = 'select'; foreach($debate->field_voting_choices['$debate->language'] as $vote_term) { $form['field_please_vote']['#options'][$vote_term['taxonomy_term']->tid] = $vote_term['taxonomy_term']->name; } } – Billy Feb 2 '13 at 14:28

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.