You are here

function addressfield_autocomplete_field_widget_form in Addressfield Autocomplete 7

Implements hook_field_widget_form().

File

./addressfield_autocomplete.module, line 280
The Addressfield Autocomplete module code.

Code

function addressfield_autocomplete_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
  if ($instance['widget']['type'] != 'addressfield_autocomplete') {
    return $element;
  }
  module_load_include('php', 'gmap', 'lib/Drupal/gmap/GmapDefaults');
  $gmap_defaults = GmapDefaults::getInstance()
    ->getDefaults();
  switch ($gmap_defaults['maptype']) {
    case 'Map':
      $gmap_defaults['maptype'] = 'roadmap';
      break;
    case 'Physical':
      $gmap_defaults['maptype'] = 'terrain';
      break;
  }
  $gmap_defaults['maptype'] = strtolower($gmap_defaults['maptype']);
  $form_ui = $form_state['build_info']['form_id'] == 'field_ui_field_edit_form';
  $fields =& drupal_static(__FUNCTION__, array());
  $settings = $instance['widget']['settings'];

  // This field name is updated after build with the complete field name.
  $fields[$field['field_name']] = $settings;
  $path = drupal_get_path('module', 'addressfield_autocomplete');
  $default_value = !empty($items[$delta]['data']) ? $items[$delta] : array();
  $data = isset($default_value['data']) ? unserialize($default_value['data']) : array();
  $lat = isset($data['latitude']) && $data['latitude'] ? $data['latitude'] : 0;
  $lng = isset($data['longitude']) && $data['longitude'] ? $data['longitude'] : 0;
  $zoom = isset($data['zoom']) && $data['zoom'] ? $data['zoom'] : 0;
  $formatted_address = isset($data['formatted_address']) ? $data['formatted_address'] : t('Manual');

  /*
   * This has been added so that we can remove the default completely
   * in the form ui admin settings.
   */
  if ($form_ui && $lat == 0 && $lng == 0) {
    $default_value = array();
  }
  $js = GmapDefaults::getInstance()
    ->getBaseJs();
  $js[$path . '/addressfield_autocomplete.js'] = array(
    'type' => 'file',
    'weight' => 3,
  );
  $js[] = array(
    'data' => array(
      'addressfield_autocomplete' => array(
        'gmap' => $gmap_defaults,
        'fields' => $fields,
      ),
    ),
    'type' => 'setting',
  );
  $attachments['js'] = $js;
  $attachments['libraries_load'][] = array(
    'geocomplete',
  );
  $attachments['css'] = array(
    $path . '/addressfield_autocomplete.css',
  );
  $instance['widget']['type'] = 'addressfield_standard';
  $address_field = addressfield_field_widget_form($form, $form_state, $field, $instance, $langcode, $items, $delta, $element);
  $address_field += array(
    'latitude' => array(
      '#type' => 'hidden',
      '#default_value' => $lat,
      '#attributes' => array(
        'class' => array(
          'latitude',
        ),
        'data-geo' => 'lat',
      ),
    ),
    'longitude' => array(
      '#type' => 'hidden',
      '#default_value' => $lng,
      '#attributes' => array(
        'class' => array(
          'longitude',
        ),
        'data-geo' => 'lng',
      ),
    ),
    'zoom' => array(
      '#type' => 'hidden',
      '#default_value' => $zoom,
      '#attributes' => array(
        'class' => array(
          'zoom',
        ),
      ),
    ),
  );

  // Add data-geo data to the address fields.
  $data_geo = array(
    'organisation_block' => array(
      'organisation_name' => 'organisation_name',
    ),
    'street_block' => array(
      'thoroughfare' => 'subpremise street_number route',
    ),
    'locality_block' => array(
      'locality' => 'administrative_area_level_3 postal_town locality',
      'dependent_locality' => 'sublocality_level_1 sublocality',
      'administrative_area' => 'administrative_area_level_2_short administrative_area_level_1_short administrative_area_level_2 administrative_area_level_1',
      'postal_code' => 'postal_code_prefix postal_code',
    ),
  );

  /*
   * If reveal widget is not chosen we must remove the required
   * fields otherwise people wont be able to submit an incomplete
   * address. This is the same if both cities or region types
   * have been selected. However for these we need to set either
   * locality or administrative area to required respectively.
   */
  foreach ($data_geo as $key => $data) {
    foreach ($data as $field => $geo) {
      if (isset($address_field[$key][$field])) {
        $address_field[$key][$field]['#attributes']['data-geo'] = $geo;
        $remove_required = $form_ui || !$settings['reveal'] || in_array($settings['types'], array(
          '(regions)',
          '(cities)',
        ));
        $cities = $settings['types'] == '(cities)' && $field == 'locality';
        $regions = $settings['types'] == '(regions)' && $field == 'administrative_area';
        if ($cities || $regions) {
          $address_field[$key][$field]['#required'] = TRUE;
        }
        if ($remove_required) {
          $address_field[$key][$field]['#required'] = FALSE;
        }
      }
    }
  }

  // Map markup.
  $map_variables = array(
    'attributes' => array(
      'id' => drupal_html_id('addressfield-autocomplete-map'),
      'style' => 'width:' . $gmap_defaults['width'] . ';height:' . $gmap_defaults['height'],
    ),
  );
  $link_variables = array(
    'external' => TRUE,
    'attributes' => array(
      'class' => array(
        'addressfield-autocomplete-reveal',
      ),
    ),
  );
  if (module_exists('i18n_field')) {
    $field_label = check_plain(i18n_field_translate_property($instance, 'label'));
  }
  else {
    $field_label = check_plain($instance['label']);
  }
  $element += array(
    '#type' => 'container',
    $element['#field_name'] => array(
      '#type' => 'container',
      '#after_build' => array(
        '_addressfield_autocomplete_widget_after_build',
      ),
      '#element_validate' => array(
        '_addressfield_autocomplete_widget_transform',
      ),
      '#attached' => $attachments,
      'reveal' => array(
        '#type' => 'hidden',
        '#default_value' => $default_value && $settings['reveal'] ? 1 : 0,
        '#attributes' => array(
          'class' => array(
            'addressfield-autocomplete-hidden-reveal',
          ),
          'autocomplete' => 'off',
        ),
      ),
      'autocomplete' => array(
        '#type' => 'textfield',
        '#title' => $field_label,
        '#required' => $delta == 0 && !$form_ui ? $instance['required'] : FALSE,
        '#default_value' => $default_value ? $formatted_address : '',
        '#maxlength' => 200,
        '#description' => field_filter_xss($instance['description']),
        '#attributes' => array(
          'placeholder' => '',
          'class' => array(
            'addressfield-autocomplete-input',
          ),
          'autocomplete' => 'off',
        ),
      ),
      'link_container' => array(
        '#type' => 'container',
        '#access' => $settings['reveal'],
        '#attributes' => array(
          'class' => array(
            'addressfield-autocomplete-link',
          ),
        ),
        'link' => array(
          '#markup' => l(t('@manual_text', array(
            '@manual_text' => $settings['manual_text'],
          )), 'javascript:void(0);', $link_variables),
        ),
      ),
      'widget' => array(
        '#type' => 'container',
        '#weight' => 10,
      ),
      'map' => array(
        '#access' => $settings['map'],
        '#markup' => theme('addressfield_autocomplete_map', $map_variables),
        '#weight' => 11,
      ),
    ),
  );
  if (!$settings['reveal']) {
    $element[$element['#field_name']]['widget']['#attributes']['class'] = array(
      'element-invisible',
    );
  }
  if ($instance['required'] && $delta == 0 && !$form_ui) {
    $element[$element['#field_name']]['#element_validate'][] = '_addressfield_autocomplete_widget_validate';
  }
  $element[$element['#field_name']]['widget'] += $address_field;
  return $element;
}