Error message

Deprecated function: implode(): Passing glue string after array is deprecated. Swap the parameters in drupal_get_feeds() (line 394 of /home1/tylerfra/public_html/includes/common.inc).

Drupal Location Form Alter

Category: 

If you need to modify the Location module's form on a node, try something like this:

function my_module_form_alter (&$form, &$form_state, $form_id) {
  switch ($form_id) {
    case "my_node_form":
      $location = array(
        'street' => '123 Fake Street',
        'city' => 'Ann Arbor',
        'province' => 'MI',
        'postal_code' => '48123',
        'country' => 'us',
        'province_name' => 'Michigan',
        'country_name' => 'United States',
        'latitude' => '42.27634',
        'longitude' => '-83.73782',
        'locpick' = array(
          'user_latitude' => '42.27634',
          'user_longitude' => '-83.73782'
        )
      );
      $form['locations'][0]['#default_value'] = $location;
      break;
    }
}

In the example above, I am setting the default form inputs for a node's location.

Additionally for my use case, I needed to prevent the user from changing the location form input values on the node edit form since this data was being dynamically loaded from an external source. I was unable to use the #disabled propertly on the location form elements during hook_form_alter and #after_build, so I used some JQuery instead from hook_form_alter:

// add javascript to disable the location form elements
// (was unable to use hook_form_alter and/or #after_build to disable these)
$disable_js = 
  "$('#edit-locations-0-street').attr('disabled', 'disabled');" .
  "$('#edit-locations-0-additional').attr('disabled', 'disabled');" .
  "$('#edit-locations-0-city').attr('disabled', 'disabled');" .
  "$('#edit-locations-0-province').attr('disabled', 'disabled');" .
  "$('#edit-locations-0-postal-code').attr('disabled', 'disabled');" .
  "$('#gmap-auto1map-locpick_latitude0').attr('disabled', 'disabled');" .
  "$('#gmap-auto1map-locpick_longitude0').attr('disabled', 'disabled');";
drupal_add_js($disable_js,"inline","footer");

// add javascript to re-enable the location form elements before submission, 
// otherwise the values will not be saved to the node
$enable_js = 
  "$('form#node-form').submit(function(){" . 
    "$('#edit-locations-0-street').removeAttr('disabled');" .
    "$('#edit-locations-0-additional').removeAttr('disabled');" .
    "$('#edit-locations-0-city').removeAttr('disabled');" .
    "$('#edit-locations-0-province').removeAttr('disabled');" .
    "$('#edit-locations-0-postal-code').removeAttr('disabled');" .
    "$('#gmap-auto1map-locpick_latitude0').removeAttr('disabled');" .
    "$('#gmap-auto1map-locpick_longitude0').removeAttr('disabled');" . 
  "});";
drupal_add_js($enable_js,"inline","footer");

 

Comments

Hey Tyler

I'm trying to do something similar as your first piece code by grabbing the users location and setting the default location fo the node based on the user instead of them filling it in every time. I just can't get it right. It's in drupal 7. Can you help?

Thanks

Rick

tyler's picture

I haven't attempted this yet in D7. However, I would first use the Devel module and call dpm($form); from my module's hook_form_alter to inspect the way the Location module builds itself inside the $form.

I would then fill in a fake location for a fake user, save it, then load up that user's location form. The dpm($form); call should reveal the location information you entered on the user somewhere in the $form. Insepct the dpm output again to view the mapping of arrays/objects bundled in the $form variable, then rebuild the mapping to each of the location variables (From there, I would copy that structure exactly and adjust the code in section 1 above accordingly).

A random guess at a possible solution would be, in D7 you may need to adjust the $form['locations'][0]['#default_value'] = $location; to something like:

$form['locations']['und'][0]['#default_value'] = $location;

I hope this helps!

Hey Tyler

Thanks for getting back to me on this. I've been able to get this right partially from gabbing code from everywhere but I just cannot get the latitide and longitude due to the parent case (locpick). The module I have at the moment is

<?php

function location_alter($argument){
$location_alter = array();
global $user;
$uid = $user->uid;
$location_alter = user_load($uid);
$location_alter = $location_alter->location;
return $location_alter[$argument];
}

/**
* Implementation of hook_locationapi().
*/
function locnodeauthor_locationapi(&$obj, $op, $a3 = NULL, $a4 = NULL, $a5 = NULL) {
switch ($op) {
case 'field_expand':
switch ($a3) {
case 'name':
return array(
'#type' => 'textfield',
'#title' => t('Location name'),
'#default_value' => $obj != '' ? $obj : location_alter('name'),
'#size' => 64,
'#maxlength' => 64,
'#description' => t('e.g. a place of business, venue, meeting point'),
'#attributes' => NULL,
'#required' => ($a4 == 2),
);

case 'street':
return array(
'#type' => 'textfield',
'#title' => t('Street'),
'#default_value' => $obj != '' ? $obj : location_alter('street'),
'#size' => 64,
'#maxlength' => 64,
'#required' => ($a4 == 2),
);

// Additional is linked to street.
case 'additional':
return array(
'#type' => 'textfield',
'#title' => t('Additional'),
'#default_value' => $obj != '' ? $obj : location_alter('additional'),
'#size' => 64,
'#maxlength' => 64,
// Required is forced OFF because this is technically part of street.
);

case 'city':
return array(
'#type' => 'textfield',
'#title' => t('City'),
'#default_value' => $obj != '' ? $obj : location_alter('city'),
'#size' => 64,
'#maxlength' => 64,
'#description' => NULL,
'#attributes' => NULL,
'#required' => ($a4 == 2),
);

case 'province':
drupal_add_js(drupal_get_path('module', 'location') .'/location_autocomplete.js');
$country = $a5['country'] ? $a5['country'] : variable_get('location_default_country', 'us');
return array(
'#type' => 'textfield',
'#title' => t('State/Province'),
'#autocomplete_path' => 'location/autocomplete/'. $country,
'#default_value' => $obj != '' ? $obj : location_alter('province'),
'#size' => 64,
'#maxlength' => 64,
'#description' => NULL,
// Used by province autocompletion js.
'#attributes' => array('class' => array('location_auto_province')),
'#required' => ($a4 == 2),
);

case 'country':
// Force default.
if ($a4 == 4) {
return array(
'#type' => 'value',
'#value' => variable_get('location_default_country', 'us'),
);
}
else {
$options = array_merge(array('' => t('Please select'), 'xx' => 'NOT LISTED'), location_get_iso3166_list());
return array(
'#type' => 'select',
'#title' => t('Country'),
'#default_value' => $obj,
'#options' => $options,
'#description' => NULL,
'#required' => ($a4 == 2),
// Used by province autocompletion js.
'#attributes' => array('class' => array('location_auto_country')),
);
}
break;

case 'postal_code':
return array(
'#type' => 'textfield',
'#title' => t('Postal code'),
'#default_value' => $obj != '' ? $obj : location_alter('postal_code'),//$location_alter['postal_code'],//location_alter('postal_code'),
'#size' => 16,
'#maxlength' => 16,
'#required' => ($a4 == 2),
);
}
break;

case 'isunchanged':
switch ($a3) {
case 'lid':
// Consider 0, NULL, and FALSE to be equivilent.
if (empty($obj[$a3]) && empty($a4)) {
return TRUE;
}
break;

case 'country':
// Consider ' ' and '' to be equivilent, due to us storing country
// as char(2) in the database.
if (trim($obj[$a3]) == trim($a4)) {
return TRUE;
}
break;

case 'province_name':
case 'country_name':
case 'map_link':
case 'coords':
// Always considered unchanged.
return TRUE;
}
break;

}
}

Any idea how I would use the scenario to change getr the latitide and longitude as well?

Thanks for the help

Rick