You are here

addressfield_autocomplete.module in Addressfield Autocomplete 7

The Addressfield Autocomplete module code.

Allows the user to pick a new type of Addressfield Autocomplete widget.

File

addressfield_autocomplete.module
View source
<?php

use Drupal\gmap\GmapDefaults;

/**
 * @file
 * The Addressfield Autocomplete module code.
 *
 * Allows the user to pick a new type of Addressfield Autocomplete widget.
 */

/**
 * Implements hook_gmap().
 */
function addressfield_autocomplete_gmap($op, &$map) {
  switch ($op) {
    case 'libraries':
      return array(
        'places',
      );
  }
}

/**
 * Implements hook_libraries_info().
 */
function addressfield_autocomplete_libraries_info() {
  $libraries['geocomplete'] = array(
    'name' => 'Geocomplete',
    'vendor url' => 'http://ubilabs.github.io/geocomplete/',
    'download url' => 'https://github.com/ubilabs/geocomplete/archive/master.zip',
    'version arguments' => array(
      'file' => 'jquery.geocomplete.js',
      'pattern' => '/V\\s+([0-9\\.\\ \\-]+)/',
      'lines' => 5,
    ),
    'files' => array(
      'js' => array(
        'jquery.geocomplete.js' => array(
          'type' => 'file',
          'weight' => 2,
        ),
      ),
    ),
    'variants' => array(
      'minified' => array(
        'files' => array(
          'js' => array(
            'jquery.geocomplete.min.js',
          ),
        ),
        'variant arguments' => array(
          'variant' => 'minified',
        ),
      ),
    ),
  );
  return $libraries;
}

/**
 * Implements hook_field_widget_info().
 */
function addressfield_autocomplete_field_widget_info() {
  return array(
    'addressfield_autocomplete' => array(
      'label' => t('Address Autocomplete'),
      'field types' => array(
        'addressfield',
      ),
      'settings' => array(
        'available_countries' => array(),
        'default_country' => '',
        'format_handlers' => array(
          'address',
        ),
        'map' => TRUE,
        'reveal' => TRUE,
        'manual_text' => t('Enter one manually'),
        'visible_markers' => TRUE,
        'draggable' => TRUE,
        'geolocation' => TRUE,
        'reverse_geocode' => FALSE,
        'html5_geocode' => TRUE,
        'types' => 'geocode',
        'restrict_country' => array(),
      ),
    ),
    'addressfield_autocomplete_latlng' => array(
      'label' => t('Fill from Addressfield Autocomplete'),
      'field types' => array(
        'geofield',
        'geolocation_latlng',
        'location',
      ),
      'settings' => array(
        'addressfield_autocomplete_field' => '',
        'delta_handling' => 'default',
      ),
      'behaviors' => array(
        'multiple values' => FIELD_BEHAVIOR_CUSTOM,
        'default value' => FIELD_BEHAVIOR_NONE,
      ),
    ),
  );
}

/**
 * Implements hook_field_widget_settings_form().
 */
function addressfield_autocomplete_field_widget_settings_form($field, $instance) {
  $widget = $instance['widget'];
  if ($widget['type'] == 'addressfield_autocomplete') {
    $settings = $widget['settings'];
    $types = array(
      'geocode',
      'establishment',
      '(regions)',
      '(cities)',
    );
    $form['available_countries'] = array(
      '#type' => 'select',
      '#multiple' => TRUE,
      '#title' => t('Available countries'),
      '#description' => t('If no countries are selected, all countries will be available. If one country is selected the google autocomplete search will be restricted to just that one specific country.'),
      '#options' => _addressfield_country_options_list(),
      '#default_value' => $settings['available_countries'],
      '#weight' => 1,
    );
    $form['default_country'] = array(
      '#type' => 'select',
      '#title' => t('Default country'),
      '#options' => _addressfield_country_options_list(),
      '#default_value' => $settings['default_country'],
      '#empty_value' => '',
      '#weight' => 1,
    );
    $form['format_handlers'] = array(
      '#type' => 'checkboxes',
      '#title' => t('Format handlers'),
      '#options' => addressfield_format_plugins_options(),
      '#default_value' => $settings['format_handlers'],
      '#weight' => 1,
    );
    $form['map'] = array(
      '#type' => 'checkbox',
      '#title' => t('Show map'),
      '#description' => t('Uncheck this box to remove the map, if you want draggable markers this must be selected.'),
      '#default_value' => $settings['map'],
      '#weight' => 2,
    );
    $form['reveal'] = array(
      '#type' => 'checkbox',
      '#title' => t('Reveal widget'),
      '#description' => t('Reveal the addressfield widget after the geocomplete has returned an address.'),
      '#default_value' => $settings['reveal'],
      '#weight' => 2,
    );
    $form['manual_text'] = array(
      '#type' => 'textfield',
      '#title' => t('Manual text'),
      '#description' => t('The text to display for the link to enter an address manually.'),
      '#default_value' => $settings['manual_text'],
      '#weight' => 3,
      '#states' => array(
        'visible' => array(
          ':input[name="instance[widget][settings][reveal]"]' => array(
            'checked' => TRUE,
          ),
        ),
      ),
    );
    $form['visible_markers'] = array(
      '#type' => 'checkbox',
      '#title' => t('Visible markers'),
      '#description' => t('Choose whether or not the markers should be shown.'),
      '#default_value' => $settings['visible_markers'],
      '#weight' => 4,
    );
    $form['draggable'] = array(
      '#type' => 'checkbox',
      '#title' => t('Draggable markers'),
      '#description' => t('Alter the location of the pointer on the map. Will only work if show map and visible markers are checked.'),
      '#default_value' => $settings['draggable'],
      '#weight' => 4,
    );
    $form['reverse_geocode'] = array(
      '#type' => 'checkbox',
      '#title' => t('Reverse geocode'),
      '#description' => t('Enable this to update the address when the marker is moved.'),
      '#default_value' => $settings['reverse_geocode'],
      '#weight' => 4,
    );
    $form['html5_geocode'] = array(
      '#type' => 'checkbox',
      '#title' => t('HTML5 geocode'),
      '#description' => t('Enable HTML5 browser location share when user is entering a manual address.'),
      '#default_value' => $settings['html5_geocode'],
      '#weight' => 4,
    );
    $form['types'] = array(
      '#type' => 'select',
      '#title' => t('Place types'),
      '#description' => t('The autocomplete service will return results that match any of the specified types, default is geocode.'),
      '#options' => drupal_map_assoc($types),
      '#default_value' => $settings['types'],
      '#weight' => 4,
    );
    return $form;
  }
  $settings = $instance['widget']['settings'];
  $fields = field_info_instances($instance['entity_type'], $instance['bundle']);
  $options = array();
  $geophp_installed = module_exists('geophp');
  foreach ($fields as $field) {
    if ($field['widget']['type'] == 'addressfield_autocomplete') {
      $options[$field['field_name']] = $field['label'];
    }
  }
  $form['addressfield_autocomplete_field'] = array(
    '#type' => 'select',
    '#title' => t('Fill from addressfield autocomplete'),
    '#empty_option' => t('- Select -'),
    '#default_value' => $settings['addressfield_autocomplete_field'],
    '#options' => $options,
    '#description' => t('Select which address autocomplete field to pick from.'),
    '#required' => TRUE,
    '#disabled' => !$geophp_installed,
  );
  $items = array(
    'Matched with each input (e.g. One POINT for each address field)',
    'Aggregated into a single MULTIPOINT geofield (e.g. One MULTIPOINT polygon from multiple address fields)',
  );
  $form['delta_handling'] = array(
    '#type' => 'select',
    '#title' => t('Multi-value input handling'),
    '#description' => t('Should geometries from multiple inputs be: !list', array(
      '!list' => theme('item_list', array(
        'items' => $items,
      )),
    )),
    '#default_value' => $settings['delta_handling'],
    '#options' => array(
      'default' => 'Match Multiples (default)',
      'm_to_s' => 'Multiple to Single',
    ),
    '#required' => TRUE,
    '#disabled' => !$geophp_installed,
  );
  if (!$geophp_installed) {
    form_set_error('addressfield_autocomplete_field', t('You need to have installed the <a href="@project_page">geophp</a> module before you can use this feature.', array(
      '@project_page' => 'http://drupal.org/project/geophp',
    )));
  }
  return $form;
}

/**
 * Implements hook_form_FORMID_alter().
 */
function addressfield_autocomplete_form_field_ui_widget_type_form_alter(&$form, $form_state, $form_id) {
  $instance = $form_state['build_info']['args'][0];
  $field = field_info_field($instance['field_name']);
  if (in_array($field['type'], array(
    'addressfield',
    'geofield',
    'geolocation_latlng',
    'location',
  ))) {
    $form['#submit'][] = '_addressfield_autocomplete_field_ui_widget_type_form_submit';
  }
}

/**
 * Implements hook_help().
 */
function addressfield_autocomplete_help($path, $arg) {
  switch ($path) {
    case 'admin/help#addressfield_autocomplete':
      $output = '';
      $output .= '<p>' . t('<a href="@project_page">Addressfield autocomplete</a> provides a hook into google maps autocomplete API.', array(
        '@project_page' => 'http://drupal.org/project/addressfield_autocomplete',
      )) . '</p>';
      $output .= '<h2>' . t('Usage') . '</h2>';
      $output .= '<p>' . t('Implements a new widget which utilises the addressfield field type and provides an easy to use single box for entering an address') . '</p>';
      $output .= '<h2>' . t('Configuration') . '</h2>';
      $output .= '<p>' . t('The configuration is done on each field instance, choose the address autocomplete widget on an addressfield type and the settings will be made available inside the field ui.') . '</p>';
      $output .= '<h3>' . t('Options') . '</h3>';
      $output .= '<p>' . t('The options include, but are not limited to: specific country searches, disabling the map, adding draggable markers, using browser geolocation and place type searches.') . '</p>';
      return $output;
  }
}

/**
 * Implements hook_field_widget_form().
 */
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;
}

/**
 * Implements hook_theme().
 */
function addressfield_autocomplete_theme() {
  return array(
    'addressfield_autocomplete_map' => array(
      'variables' => array(
        'attributes' => array(
          'class' => array(
            'autocomplete-map',
            'clearfix',
          ),
        ),
      ),
    ),
  );
}

/**
 * Render a container for a set of address fields.
 */
function theme_addressfield_autocomplete_map($variables) {
  $attributes = $variables['attributes'];
  $attributes['class'][] = 'autocomplete-map';
  $attributes['class'][] = 'clearfix';
  return '<div' . drupal_attributes($attributes) . '></div>';
}

/**
 * Implements hook_field_attach_presave().
 *
 * Attaching the latitude and longitude values for geofield is done here.
 */
function addressfield_autocomplete_field_attach_presave($entity_type, $entity) {

  // Loop over any geofield using our geocode widget
  $entity_info = entity_get_info($entity_type);
  $bundle_name = empty($entity_info['entity keys']['bundle']) ? $entity_type : $entity->{$entity_info['entity keys']['bundle']};
  foreach (field_info_instances($entity_type, $bundle_name) as $instance) {
    if ($instance['widget']['type'] !== 'addressfield_autocomplete_latlng') {
      continue;
    }
    $values = _addressfield_autocomplete_widget_get_field_value($entity_type, $entity, $instance);
    if ($values) {
      $entity->{$instance['field_name']} = $values;
    }
  }
}

/**
 * Addressfield autocomplete transform.
 *
 * Transforms data into the structure accepted by addressfield.
 */
function _addressfield_autocomplete_widget_transform($element, &$form_state, $form) {
  $parents = $element['#parents'];
  $values = drupal_array_get_nested_value($form_state['values'], $parents);
  $data = $address = array();
  if (!empty($values['autocomplete'])) {
    $data['latitude'] = $values['widget']['latitude'];
    $data['longitude'] = $values['widget']['longitude'];
    $data['zoom'] = $values['widget']['zoom'];
    $data['formatted_address'] = $values['autocomplete'];
    foreach (array(
      'latitude',
      'longitude',
      'zoom',
    ) as $key) {
      unset($values['widget'][$key]);
    }
    $address = $values['widget'];
    $address['data'] = serialize($data);
  }
  array_pop($parents);
  drupal_array_set_nested_value($form_state['values'], $parents, $address);

  /*
   * From addressfield 7.x-1.0-rc1 we also need to set the input to the value
   * of the widget. Otherwise the form does not appear.
   */
  drupal_array_set_nested_value($form_state['input'], $parents, $address);
}

/**
 * Address autocomplete widget validation function.
 *
 * Validate to see if lat and lng have been added for addresses which
 * do not reveal the widget.
 */
function _addressfield_autocomplete_widget_validate($element, &$form_state, $form) {
  $parents = $element['#parents'];
  array_pop($parents);
  $values = drupal_array_get_nested_value($form_state['values'], $parents);
  if (!isset($values['data'])) {
    return;
  }
  $data = unserialize($values['data']);
  if (empty($data['latitude']) && empty($data['latitude'])) {
    form_error($element, t('This address is invalid please try again.'));
  }
}

/**
 * Adds the states and JS settings to the correct form element by name.
 *
 * @param $form_element
 *   The form element containing the parents array.
 */
function _addressfield_autocomplete_widget_after_build($form_element) {
  $parents = $form_element['#parents'];
  $name = array_shift($parents) . '[' . implode('][', $parents) . ']';

  // Update fields in JS settings with complete field name from parents.
  $attached_js_fields =& $form_element['#attached']['js'][0]['data']['addressfield_autocomplete']['fields'];
  $renamed_field_settings = array();
  foreach ($attached_js_fields as $key => $settings) {
    $renamed_field_settings[$name] = $settings;
  }
  $attached_js_fields = $renamed_field_settings;
  $form_element['autocomplete']['#states'] = array(
    'visible' => array(
      ':input[name="' . $name . '[reveal]"]' => array(
        'value' => '0',
      ),
    ),
  );
  $form_element['link_container']['#states'] = array(
    'visible' => array(
      ':input[name="' . $name . '[reveal]"]' => array(
        'value' => '0',
      ),
    ),
  );
  $form_element['widget']['#states'] = array(
    'visible' => array(
      ':input[name="' . $name . '[reveal]"]' => array(
        'value' => '1',
      ),
    ),
  );
  return $form_element;
}

/**
 * Function to get the geofield information from the autocomplete.
 */
function _addressfield_autocomplete_widget_get_field_value($entity_type, $entity, $instance) {
  if (!isset($instance['widget']['settings']['addressfield_autocomplete_field'])) {
    return;
  }
  $values = $field_values = $geometries = array();
  list(, , $bundle_name) = entity_extract_ids($entity_type, $entity);
  $field_name = $instance['widget']['settings']['addressfield_autocomplete_field'];
  $field_instance = field_info_instance($entity_type, $field_name, $bundle_name);
  if ($field_instance['widget']['type'] != 'addressfield_autocomplete') {
    return $values;
  }
  $delta_hanlding = $instance['widget']['settings']['delta_handling'];
  $target_info = field_info_field($instance['field_name']);
  $target_type = $target_info['type'];
  $field_values = field_get_items($entity_type, $entity, $field_name, isset($entity->language) ? $entity->language : NULL);
  if ($field_values) {
    geophp_load();
    foreach ($field_values as $delta => $item) {
      $data = unserialize($item['data']);
      $geometry = array();
      if (isset($data['latitude']) && isset($data['longitude'])) {
        $geometry = new Point($data['longitude'], $data['latitude']);
      }
      $geometries[$delta] = $geometry;
    }
  }
  if ($geometries) {
    $values = _addressfield_autocomplete_widget_resolve_deltas($geometries, $target_type, $delta_hanlding);
  }
  return $values;
}

/**
 * Address autocomplete resolve deltas for handling geofield.
 *
 * Given a list of geometries, and user configuration on how to handle deltas,
 * we created a list of items to be inserted into the fields.
 */
function _addressfield_autocomplete_widget_resolve_deltas($geometries, $field_type, $delta_handling = 'default') {
  $values = array();

  // Default delta handling: just pass one delta to the next
  if ($delta_handling == 'default') {
    foreach ($geometries as $geometry) {
      $values[] = _addressfield_autocomplete_widget_values_from_geometry($geometry, $field_type);
    }
  }

  // For multiple-to-single handling, run it though geometryReduce
  if ($delta_handling == 'm_to_s') {
    $reduced_geom = geoPHP::geometryReduce($geometries);
    $values[] = _addressfield_autocomplete_widget_values_from_geometry($reduced_geom, $field_type);
  }

  // Set the values - geofields do not support languages
  return array(
    LANGUAGE_NONE => $values,
  );
}

/**
 * Address autocomplete get field values from geometry.
 *
 * Given a geometry and the field type, return back a values array for that
 * field.
 */
function _addressfield_autocomplete_widget_values_from_geometry($geometry, $field_type) {
  if ($field_type == 'geofield') {
    return geofield_get_values_from_geometry($geometry);
  }
  if ($field_type == 'geolocation_latlng') {
    $centroid = $geometry
      ->centroid();
    $lat = $centroid
      ->y();
    $lng = $centroid
      ->x();
    return array(
      'lat' => $lat,
      'lng' => $lng,
      'lat_sin' => sin(deg2rad($lat)),
      'lat_cos' => cos(deg2rad($lat)),
      'lng_rad' => deg2rad($lng),
    );
  }
  if ($field_type == 'location') {
    $centroid = $geometry
      ->centroid();
    return array(
      'latitude' => $centroid
        ->y(),
      'longitude' => $centroid
        ->x(),
      'source' => 2,
    );
  }
}

/**
 * Submit function for after widget is saved.
 *
 * Tried to use hook_field_update_instance to fix bugs when update the instance
 * widget. This did not work so it was changed to an extra submission function.
 */
function _addressfield_autocomplete_field_ui_widget_type_form_submit($form, &$form_state) {
  $bundle = $form['#bundle'];
  $entity_type = $form['#entity_type'];
  $field_name = $form['#field_name'];

  // Retrieve the stored instance settings to merge with the incoming values.
  $instance = field_read_instance($entity_type, $field_name, $bundle);
  $widget = $instance['widget'];
  if (!isset($instance['default_value'][0]) && in_array($widget['type'], array(
    'addressfield_autocomplete',
    'addressfield_standard',
  ))) {
    $instance['default_value'][0] = array();
    field_update_instance($instance);
  }
  if ($widget['type'] == 'addressfield_autocomplete_latlng') {
    $admin_path = _field_ui_bundle_admin_path($entity_type, $bundle);
    $form_state['redirect'] = $admin_path . '/fields/' . $field_name;
  }
}

Functions

Namesort descending Description
addressfield_autocomplete_field_attach_presave Implements hook_field_attach_presave().
addressfield_autocomplete_field_widget_form Implements hook_field_widget_form().
addressfield_autocomplete_field_widget_info Implements hook_field_widget_info().
addressfield_autocomplete_field_widget_settings_form Implements hook_field_widget_settings_form().
addressfield_autocomplete_form_field_ui_widget_type_form_alter Implements hook_form_FORMID_alter().
addressfield_autocomplete_gmap Implements hook_gmap().
addressfield_autocomplete_help Implements hook_help().
addressfield_autocomplete_libraries_info Implements hook_libraries_info().
addressfield_autocomplete_theme Implements hook_theme().
theme_addressfield_autocomplete_map Render a container for a set of address fields.
_addressfield_autocomplete_field_ui_widget_type_form_submit Submit function for after widget is saved.
_addressfield_autocomplete_widget_after_build Adds the states and JS settings to the correct form element by name.
_addressfield_autocomplete_widget_get_field_value Function to get the geofield information from the autocomplete.
_addressfield_autocomplete_widget_resolve_deltas Address autocomplete resolve deltas for handling geofield.
_addressfield_autocomplete_widget_transform Addressfield autocomplete transform.
_addressfield_autocomplete_widget_validate Address autocomplete widget validation function.
_addressfield_autocomplete_widget_values_from_geometry Address autocomplete get field values from geometry.