diff --git a/geofield.elements.inc b/geofield.elements.inc index bf87279..d3c7844 100644 --- a/geofield.elements.inc +++ b/geofield.elements.inc @@ -61,7 +61,103 @@ function geofield_element_info() { '#theme_wrappers' => array('geofield_proximity'), '#process' => array('geofield_proximity_element_process'), ), + 'geofield_latlon_proximity' => array( + '#input' => TRUE, + '#process' => array('geofield_latlon_proximity_element_process'), + '#element_validate' => array('geofield_latlon_proximity_element_validate'), + '#theme' => array('theme_geofield_latlon'), + '#theme_wrappers' => array('fieldset'), + ), + ); +} + + +/** + * Process function for geofield_latlon_proximity. + */ +function geofield_latlon_proximity_element_process($element, &$form_values){ + $element['#tree'] = TRUE; + $element['#input'] = TRUE; + // set origin text field + $element['origin'] = array( + '#type' => (!empty($element['#origin_element'])) ? $element['#origin_element'] : 'textfield', + '#title' => t('Origin'), + '#title_display' => 'invisible', + '#required' => !empty($element['#required']) ? $element['#required'] : FALSE, + '#default_value' => !empty($element['#default_value']['origin']) ? $element['#default_value']['origin'] : FALSE, + ); + $element['lat'] = array( + '#type' => 'hidden', + '#default_value' => (!empty($element['#default_value']['lat'])) ? $element['#default_value']['lat'] : '', + '#attributes' => array( + 'class' => array('geofield-lat'), + ), ); + + $element['lon'] = array( + '#type' => 'hidden', + '#default_value' => (!empty($element['#default_value']['lon'])) ? $element['#default_value']['lon'] : '', + '#attributes' => array( + 'class' => array('geofield-lon'), + ), + ); + + unset($element['#value']); + // Set this to false always to prevent notices. + $element['#required'] = FALSE; + + if (!empty($element['#geolocation']) && $element['#geolocation'] == TRUE) { + $element['#attached']['js'][] = drupal_get_path('module', 'geofield') . '/js/geolocation.js'; + $element['geocode_submit_buttom'] = array( + '#type' => 'submit', + '#value' => t('Find my location'), + '#name' => 'geofield-html5-geocode-button', + ); + $element['#attributes']['class'] = array('auto-geocode'); + } + return $element; +} + +/** + * Element validation function for geofield_latlon_proximity. + */ +function geofield_latlon_proximity_element_validate($element, &$form_values) { + $components = array( + 'lat' => array( + 'title' => 'Latitude', + 'range' => 90, + ), + 'lon' => array( + 'title' => 'Longitude', + 'range' => 180, + ), + ); + + $allFilled = TRUE; + $anyFilled = FALSE; + foreach ($components as $key => $component) { + if (!empty($element[$key]['#value'])) { + if (!is_numeric($element[$key]['#value'])) { + form_error($element[$key], t('@title: @component_title is not numeric.', array('@title' => $element['#title'], '@component_title' => $component['title']))); + } + elseif (abs($element[$key]['#value']) > $component['range']) { + form_error($element[$key], t('@title: @component_title is out of bounds.', array('@title' => $element['#title'], '@component_title' => $component['title']))); + } + } + if ($element[$key]['#value'] == '') { + $allFilled = FALSE; + } + else { + $anyFilled = TRUE; + } + } + if ($anyFilled && !$allFilled) { + foreach ($components as $key => $component) { + if ($element[$key]['#value'] == '') { + form_error($element[$key], t('@title: @component_title must be filled too.', array('@title' => $element['#title'], '@component_title' => $component['title']))); + } + } + } } /** diff --git a/js/geolocation.js b/js/geolocation.js index f5c7656..507e5c1 100644 --- a/js/geolocation.js +++ b/js/geolocation.js @@ -37,8 +37,15 @@ attach: function (context, settings) { // callback for getCurrentPosition function updateLocation(position) { - $fields.find('.auto-geocode .geofield-lat').val(position.coords.latitude); - $fields.find('.auto-geocode .geofield-lon').val(position.coords.longitude); + // we only need to submit the form aftet log value is changed. + $fields.find('.auto-geocode .geofield-lon').change(function(e) { + e.preventDefault(); + if($(this).attr('type') == 'hidden'){ + $fields.find('.auto-geocode').parents('form:first').submit(); + } + }); + $fields.find('.auto-geocode .geofield-lat').val(position.coords.latitude).trigger('change'); + $fields.find('.auto-geocode .geofield-lon').val(position.coords.longitude).trigger('change'); } // don't do anything if we're on field configuration if (!$(context).find("#edit-instance").length) { diff --git a/views/proximity_plugins/geofieldProximityGeocoder.inc b/views/proximity_plugins/geofieldProximityGeocoder.inc index 7eacd87..d638341 100644 --- a/views/proximity_plugins/geofieldProximityGeocoder.inc +++ b/views/proximity_plugins/geofieldProximityGeocoder.inc @@ -8,6 +8,7 @@ class geofieldProximityGeocoder extends geofieldProximityBase implements geofieldProximityPluginInterface { public function option_definition(&$options, $views_plugin) { $options['geofield_proximity_geocoder'] = array('default' => ''); + $options['geofield_proximity_geocoder_html5'] = array('default' => false); $options['geofield_proximity_geocoder_engine'] = array('default' => 'google'); } @@ -21,6 +22,15 @@ class geofieldProximityGeocoder extends geofieldProximityBase implements geofiel ), '#proximity_plugin_value_element' => TRUE, ); + + $form['geofield_proximity_geocoder_html5'] = array( + '#type' => 'checkbox', + '#title' => t('HTML5 Geolocation.'), + '#default_value' => $views_plugin->options['geofield_proximity_geocoder_html5'], + '#dependency' => array( + 'edit-options-source' => array('geocoder'), + ), + ); $geocoders_raw = geocoder_handler_info('text'); $geocoder_options = array(); @@ -43,14 +53,33 @@ class geofieldProximityGeocoder extends geofieldProximityBase implements geofiel if (!empty($form_state['values']['options']['geofield_proximity_geocoder']) && !geocoder($form_state['values']['options']['geofield_proximity_geocoder_engine'], $form_state['values']['options']['geofield_proximity_geocoder'])) { form_set_error('options][geofield_proximity_geocoder', t('Geocoder cannot find this location. Check your connection or add a findable location.')); } + // unset values + unset($views_plugin->value['origin']); + } + + public function value_form(&$form, &$form_state, $views_plugin) { + if($views_plugin->options['geofield_proximity_geocoder_html5']){ + $form['value']['#origin_element'] = 'geofield_latlon_proximity'; + $form['value']['#origin_options']['#geolocation'] = TRUE; + } } public function getSourceValue($views_plugin) { $geocoder_engine = $views_plugin->options['geofield_proximity_geocoder_engine']; $location = (isset($views_plugin->value)) ? $views_plugin->value['origin'] : $views_plugin->options['geofield_proximity_geocoder']; + if($views_plugin->options['geofield_proximity_geocoder_html5']){ + if(isset($location['origin']) && !empty($location['origin'])){ + $location = $location['origin']; + } + else if(!empty($location['lat']) && !empty($location['lon'])){ + return array( + 'latitude' => $location['lat'], + 'longitude' => $location['lon'], + ); + } + } if ($location) { $geocoded_data_raw = geocoder($geocoder_engine, $location); - if ($geocoded_data_raw) { return array( 'latitude' => $geocoded_data_raw->getY(), @@ -58,8 +87,6 @@ class geofieldProximityGeocoder extends geofieldProximityBase implements geofiel ); } } - return FALSE; } - }