1

I would like to create rated inteterests for each user. Until now what I have is a taxonomy term vocabulary defined and a field in the user account attached to this vocabulary. Until here what a user can do is to check or not each term of the vocabulary, using the widget options_list. What I would like to do is to let the user select the level (0-10) of preference for each term.

I've tried to create a custom field with two columns, tid and value, then linking each tid with taxonomy term in hook_field_widget_form, but no luck as I'm not an expert in fields, so I'm confused about how to implement:

/**
 * Implements hook_field_widget_form().
 */
function taxonomy_value_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
  $tids = isset($items[$delta]['tid']) ? $items[$delta]['tid'] : array();
  $values = isset($items[$delta]['value']) ? $items[$delta]['value'] : array();
  $element += array(
    '#delta' => $delta,
  );

  switch ($instance['widget']['type']) {

    case 'taxonomy_value_widget':
      if ($vocabulary = taxonomy_vocabulary_machine_name_load('tags')) {
        if ($terms = taxonomy_get_tree($vocabulary->vid)) {
          foreach ($terms as $term) {
            if ($term->depth == 0) {
              $element[$term->tid] = array(
                '#markup'  => '</br><strong>' . $term->name . '</strong>',
              );
            } else {
              $element[$term->tid]['term'] = array(
                '#markup'  => '</br>' . $term->name,
              );

              $element[$term->tid]['tid'] = array(
                '#type'          => 'value',
                '#value'         => $term->tid,
              );

              $element[$term->tid]['value'] = array(
                '#type'          => 'textfield',
                '#value'         => in_array($term->tid, $values) ? $values[$term->tid] : 5,
              );

            }
          }
        }
      }

      break;
  }

  return $element;
}

2 Answers 2

0

what not using Field Collection ?

1
  • Just tried, but then the problem is how to associate a taxonomy term with the corresponding value: taxonomy term has its own widget and can be select, options, autocomplete. So in one field you will have the list of all terms and on the other field the list of all values. You could iterate and make all terms appear, but it is a waste of space in db because all users would have all terms even if they where default value. The ideal scenario you just store terms that are different from standard (let's say 5)
    – Miquel
    Dec 12, 2012 at 21:37
0

The problem was with values: they had to be trasposed. This solution uses transfer_slider from jquery.

/**
 * Implements hook_field_widget_form().
 */
function taxonomy_value_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
  $values = taxonomy_value_traspose_values($items);
  $element += array(
    '#delta' => $delta,
  );

  switch ($instance['widget']['type']) {

    case 'taxonomy_value_widget':

      if ($vocabulary = taxonomy_vocabulary_machine_name_load('tags')) {
        if ($terms = taxonomy_get_tree($vocabulary->vid)) {
          foreach ($terms as $term) {
            if ($term->depth == 0) {
              $element[$term->tid] = array(
                '#markup'  => '</br><strong>' . $term->name . '</strong>',
              );
            } else {
              $element[$term->tid]['term'] = array(
                '#markup'  => '<span class="taxonomy_value-taxonomy-string">' .  $term->name . '</span>',
              );

              $element[$term->tid]['tid'] = array(
                '#type'          => 'value',
                '#value'         => $term->tid,
              );

              $element[$term->tid]['slidervalue'] = array(
                '#type'          => 'transfer_slider',
                '#title'         => '',
                '#left_value'    => array_key_exists($term->tid, $values) ? $values[$term->tid] : 5,
                '#right_value'   => array_key_exists($term->tid, $values) ? 10 - $values[$term->tid] : 5,
                '#left'          => '',
                '#right'         => '',
              );

              // Tengo que hacerlo así ya que transfer_slider está diseñado para tener 2 textfields. Este campo lo actualizo en presave.
              $element[$term->tid]['value'] = array(
                '#type'          => 'value',
                '#value'         => array_key_exists($term->tid, $values) ? $values[$term->tid] : 5
              );
            }
          }
        }
      }

      break;
  }

  return $element;
}

/**
 * Dado un array 'delta' => ('tid' => X, 'value' => Y), devuelve un array associativo 'X' => Y.
 * @param unknown_type $items
 */
function taxonomy_value_traspose_values($items) {
  $values = array();
  foreach ($items as $item) {
    $values[$item['tid']] = $item['value'];
  }

  return $values;
}

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.