You are here

function socialfield_field_widget_form in Social field 7

Implements hook_field_widget_form().

File

./socialfield.module, line 646
Provides a field for adding social services links.

Code

function socialfield_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
  $value_key = key($field['columns']);
  $all_services = variable_get('socialfield_services');

  // Settings to be accessed from ajax callback.
  $form_state['socialfield']['field_data'] = array(
    'field_name' => $field['field_name'],
    'parents' => $element['#field_parents'],
    'langcode' => $langcode,
  );

  // A service (option) from select list was accessed.
  if (isset($form_state['triggering_element']['#value']) && isset($form_state['triggering_element']['#socialfield_add'])) {
    if ($form_state['triggering_element']['#value'] != '_none') {
      $form_state['services'][] = $form_state['triggering_element']['#value'];
    }
  }

  // Remove button was pressed.
  if (isset($form_state['clicked_button']['#name']) && isset($form_state['clicked_button']['#socialfield_delete'])) {
    $element_array = explode('_', $form_state['clicked_button']['#name']);
    $remove_element = (int) end($element_array);
    unset($form_state['values'][$field['field_name']][$langcode][$remove_element]);
    unset($form_state['services'][$remove_element]);
  }

  // Setting number of form elements.
  if (!isset($form_state['services'])) {
    if (count($items)) {

      // Edit page. Showing all saved elements.
      $form_state['num_elements'] = count($items) - 1;
      $form_state['services'] = array();
      foreach ($items as $item) {
        $form_state['services'][] = $item['service'];
      }
    }
    else {

      // Create page. Showing only default elements (aplying instance settings).
      $form_state['num_elements'] = count($instance['settings']['services']) - 1;
      $form_state['services'] = array_values($instance['settings']['services']);
    }
  }

  // Setting the number of services on widget.
  $form_state['num_elements'] = count($form_state['services']);

  // Creating wrapper and setting theme (table) on it.
  $element['social_buttons'] = array(
    '#prefix' => '<div id="social-field-wrapper">',
    '#suffix' => '</div>',
    '#tree' => TRUE,
    '#theme' => 'socialfield_drag_components',
    '#num_elements' => $form_state['num_elements'],
  );

  // Getting maximum weight from existing services.
  $weights = array(
    -11,
  );
  if (!empty($items)) {
    foreach ($items as $item) {
      $weights[] = $item['weight'];
    }
  }
  $weight = max($weights);
  unset($weights);

  // Creating form.
  foreach ($form_state['services'] as $i => $service) {

    // Checking if service was deleted from module settings.
    if (!isset($all_services[$service])) {
      $form_state['num_elements']--;
      $element['social_buttons']['#num_elements']--;
      continue;
    }
    $element['social_buttons']['element_' . $i] = array(
      'url' => array(
        '#type' => 'textfield',
        '#default_value' => isset($items[$i]) && $service == $items[$i]['service'] ? $items[$i]['url'] : '',
        '#value_key' => $value_key,
      ),
      'weight' => array(
        '#type' => 'weight',
        '#title' => t('Weight'),
        '#title_display' => 'invisible',
        '#default_value' => isset($items[$i]['weight']) ? $items[$i]['weight'] : ++$weight,
        '#attributes' => array(
          'class' => array(
            'item-row-weight',
          ),
        ),
      ),
      '#service' => $service,
      'operation' => array(
        '#type' => 'button',
        '#value' => t('Remove'),
        '#name' => 'element_ ' . $i,
        '#socialfield_delete' => TRUE,
        '#validate' => array(),
        '#limit_validation_errors' => array(),
        '#ajax' => array(
          'callback' => 'socialfield_remove_one_element_callback',
          'wrapper' => 'social-field-wrapper',
        ),
      ),
    );
  }

  // Validate on elements.
  $element['#element_validate'] = array(
    'socialfield_service_validate',
  );

  // Getting services for the select list.
  $options = array_keys($all_services);
  $options = array_combine($options, $options);
  if (isset($instance['settings']['used_services'])) {
    $options = array_intersect($options, $instance['settings']['used_services']);
  }
  $options = array_diff($options, $form_state['services']);
  $options = array_map('ucfirst', $options);

  // Select for adding new element (service and url) to form. Done with Ajax Forms.
  $element['social_buttons']['add_one_social'] = array(
    '#type' => 'select',
    '#options' => array(
      '_none' => t('Add more'),
    ) + $options,
    '#socialfield_add' => TRUE,
    '#access' => !empty($options),
    '#validate' => array(),
    '#limit_validation_errors' => array(),
    '#attributes' => array(
      'class' => array(
        'add_one_social_service',
      ),
    ),
    '#ajax' => array(
      'callback' => 'socialfield_add_one_element_callback',
      'wrapper' => 'social-field-wrapper',
    ),
  );

  // Add help description.
  $element['social_buttons']['description'] = array(
    '#markup' => $instance['description'],
  );

  // Attaching css and js files.
  $path = drupal_get_path('module', 'socialfield');
  $element['#attached']['js'][] = $path . '/js/socialfield.js';
  $element['#attached']['css'][] = $path . '/css/socialfield.css';
  return $element;
}