You are here

function makemeeting_field_widget_form in Make Meeting Scheduler 7.2

Implements hook_field_widget_form().

File

./makemeeting.field.inc, line 63
This file is mostly about the field configuration.

Code

function makemeeting_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
  $element += array(
    '#type' => 'fieldset',
  );
  $item =& $items[$delta];

  // Simple options form elements about the poll
  $element['hidden'] = array(
    '#title' => t('Hidden poll'),
    '#description' => t('Confidential participation: only you and administrators can see the answers.'),
    '#type' => 'checkbox',
    '#default_value' => isset($item['hidden']) ? $item['hidden'] : '',
  );
  $element['one_option'] = array(
    '#title' => t('Participant can only choose one option'),
    '#description' => t('By default all options are selectable. This setting limits the choice to one option per participant.'),
    '#type' => 'checkbox',
    '#default_value' => isset($item['one_option']) ? $item['one_option'] : '',
  );
  $element['limit'] = array(
    '#title' => t('Limit the number of participants per option'),
    '#description' => t('Poll as registration form: As soon as the indicated limit has been reached, the respective option is no longer available. 0 for unlimited'),
    '#type' => 'textfield',
    '#default_value' => isset($item['limit']) ? $item['limit'] : 0,
    '#element_validate' => array(
      'element_validate_integer',
    ),
  );
  $element['yesnomaybe'] = array(
    '#title' => t('Provide a "Maybe" option'),
    '#description' => t('Provide a third "Maybe" option in case users may be available.'),
    '#type' => 'checkbox',
    '#default_value' => isset($item['yesnomaybe']) ? $item['yesnomaybe'] : '',
    // Hide if one_option is checked
    '#states' => array(
      'visible' => array(
        ':input[name$="[one_option]"]' => array(
          'checked' => FALSE,
        ),
      ),
    ),
  );
  $element['timezone'] = array(
    '#title' => t('Timezone'),
    '#description' => t('Set this to your timezone so that dates can be converted for users in other parts of the world.'),
    '#type' => 'select',
    '#default_value' => isset($item['timezone']) ? $item['timezone'] : drupal_get_user_timezone(),
    '#options' => system_time_zones(),
  );
  $element['closed'] = array(
    '#title' => t('Closed'),
    '#description' => t('Check this when you want to close the poll.'),
    '#type' => 'checkbox',
    '#default_value' => isset($item['closed']) ? $item['closed'] : '',
  );

  // Now let's take care of the choices part
  // $process is a callback that we will attach to the wrapper in order
  // to add parents to the form elements. This is so we can store
  // nested values in the DB table with field storage API.
  $fieldset_info = element_info('fieldset');
  $process = array_merge($fieldset_info['#process'], array(
    '_makemeeting_rebuild_parents',
  ));
  $element['choices_wrapper'] = array(
    '#tree' => FALSE,
    '#prefix' => '<div class="clearfix" id="makemeeting-choices-wrapper">',
    '#suffix' => '</div>',
    '#process' => $process,
  );

  // Container just for the poll choices.
  $element['choices_wrapper']['choices'] = array(
    '#prefix' => '<div id="makemeeting-choices">',
    '#suffix' => '</div>',
    '#theme' => 'makemeeting_choices',
  );

  // Fill the item values with previously submitted values
  if (!empty($form_state['values'])) {
    $submitted_values = drupal_array_get_nested_value($form_state['values'], $element['#field_parents']);
    $submitted_values = $submitted_values[$element['#field_name']][$element['#language']][$element['#delta']];
    if (isset($submitted_values['choices'])) {
      $item['choices'] = $submitted_values['choices'];
    }
  }

  // Calculate the suggestion count
  if (empty($form_state['suggestion_count'])) {
    $form_state['suggestion_count'] = 1;
  }
  if (isset($item['choices'])) {
    foreach ($item['choices'] as $choice) {
      if ($form_state['suggestion_count'] < count($choice['chsuggestions'])) {
        $form_state['suggestion_count'] = count($choice['chsuggestions']);
      }
    }
  }

  // Determine choice count if not provided
  if (!isset($form_state['choice_count'])) {
    try {
      list($entity_id) = entity_extract_ids($element['#entity_type'], $element['#entity']);
    } catch (Exception $e) {

      // Fail silently if the field is not attached to any entity yet.
    }

    // If the entity isn't created yet, offer the default number of choices,
    // else the number of previous choices, or 0 if none
    if (!isset($entity_id)) {
      $widget = $instance['widget'];
      $settings = $widget['settings'];
      $form_state['choice_count'] = isset($settings['size']) ? $settings['size'] : 1;
    }
    else {
      $form_state['choice_count'] = isset($item['choices']) ? count($item['choices']) : 0;
    }
  }

  // Add the current choices to the form.
  $delta = 0;
  if (isset($item['choices']) && $form_state['choice_count']) {

    // Sort choices by their dates
    asort($item['choices']);
    $delta = count($item['choices']);
    foreach ($item['choices'] as $key => $choice) {
      $element['choices_wrapper']['choices'][$key] = _makemeeting_choice_form($key, $choice['chdate'], $choice['chsuggestions'], $form_state['suggestion_count']);
      if ($form_state['choice_count'] == 1) {
        $element['choices_wrapper']['choices'][$key]['chremove']['#access'] = FALSE;
      }
    }
  }

  // Add choices as required.
  if ($form_state['choice_count']) {

    // Add a day to the last option's timestamp for the new default date
    $date = isset($choice['chdate']) ? _makemeeting_date_timestamp($choice['chdate']) : new DateTime();
    $existing_delta = $delta;
    for (; $delta < $form_state['choice_count']; $delta++) {
      $date
        ->add(new DateInterval('P1D'));

      // Build default date
      $default_date = array(
        'month' => $date
          ->format('n'),
        'day' => $date
          ->format('j'),
        'year' => $date
          ->format('Y'),
      );
      $key = 'new:' . ($delta - $existing_delta);
      $element['choices_wrapper']['choices'][$key] = _makemeeting_choice_form($key, $default_date, NULL, $form_state['suggestion_count']);
      if ($form_state['choice_count'] == 1) {
        $element['choices_wrapper']['choices'][$key]['chremove']['#access'] = FALSE;
      }
    }
  }

  // We prefix our buttons with 'makemeeting' to avoid conflicts
  // with other modules using Ajax-enabled buttons with the id 'more'.
  $default_submit = array(
    '#type' => 'submit',
    '#limit_validation_errors' => array(
      array(
        'choices',
      ),
    ),
    '#submit' => array(
      'makemeeting_choices_submit',
    ),
    '#ajax' => array(
      'callback' => 'makemeeting_choice_js',
      'wrapper' => 'makemeeting-choices-wrapper',
      'effect' => 'fade',
    ),
  );
  $element['choices_wrapper']['makemeeting_more_choices'] = $default_submit + array(
    '#value' => t('More choices'),
    '#attributes' => array(
      'title' => t("If the amount of rows above isn't enough, click here to add more choices."),
    ),
    '#weight' => 1,
  );
  $element['choices_wrapper']['makemeeting_more_suggestions'] = $default_submit + array(
    '#value' => t('More suggestions'),
    '#attributes' => array(
      'title' => t("If the amount of boxes above isn't enough, click here to add more suggestions."),
    ),
    '#weight' => 2,
  );
  if ($form_state['choice_count'] > 1) {
    $element['choices_wrapper']['makemeeting_copy_suggestions'] = $default_submit + array(
      '#value' => t('Copy and paste first row'),
      '#attributes' => array(
        'title' => t("Copy the suggestions from the first to the other rows."),
      ),
      '#weight' => 3,
    );
  }
  return $element;
}