remove Delete checkbox from user location form
Dave Cohen - February 23, 2009 - 20:57
| Project: | Location |
| Version: | 6.x-3.x-dev |
| Component: | Code |
| Category: | feature request |
| Priority: | normal |
| Assigned: | Unassigned |
| Status: | active |
| Issue tags: | location theme edit form, Location theming |
Description
I'd like to remove the "Check this box to delete this location" checkbox from some forms. As far as I can tell, there's no way to do this either with hook_form_alter or hook_locationapi. Any suggestions?

#1
The attached patch emulates the logic found earlier in _location_expand_location(), where it sets the title only if it was not set in an earlier form_alter():
if (!isset($element['#title'])) {$element['#title'] = t('Location');
}
The patch checks whether delete_location has been set before setting it. I think it would be cool to make a similar check before anything is added to the element.
With the attached patch, the following logic in my hook_form_alter allows me to hide the delete checkbox from normal users:
if (isset($form['locations']) && !user_access('administer users')) {foreach(element_children($form['locations']) as $key) {
$form['locations'][$key]['delete_location'] = array();
}
}
I post this in case it is helpful to others.
#2
Also, the delete checkbox appears on forms where parts of the location are required. In my opinion, if I've set things up to require a location, delete should not be an option.
#3
Ok, one more suggestion. Since lots of people seem to want to alter the location element, add some code like this to the end of _location_expand_location()
// Allow third party modules to alter the element. In Drupal 6, replace this\
with a call to drupal_alter()
foreach(module_implements('location_element_alter') as $module) {
$function = $module . '_location_element_alter';
$function($element);
}
...right before the $element is returned.
In Drupal 6, this would be simply a call to
drupal_alter('location_element', $element)I think this would kill many birds with one stone, and is consistant with other parts of Drupal. I'm using this code now to change the text associated with the locpick elements. And this would suffice in place of the patch I submitted earlier.
#4
Tagging with a theming tag for now.
#5
Since Cameron asked me for more details about my earlier comment...
The idea is to add the above code to the function _location_expand_location(). Then, in your own module, implement MY_MODULE_location_element_alter(&$element). In that function, make whatever changes you might have made in hook_form_alter(), if the location element did not have its own special processing.
You need some PHP chops to have this work for you, not just CSS. However in your hook_location_element_alter() you could add a #prefix and #suffix to wrap the element in a div, which could then be used in CSS.
Here's my implementation of hook_location_element_alter(), which adds some instructional text...
function sunflower_custom_location_element_alter(&$element) {//dpm(func_get_args(), "sunflower_custom_location_element_alter");
if (isset($element['locpick'])) {
$element['locpick']['user_latitude']['#description'] = ' ' . t('Use decimal notation.');
$element['locpick']['user_longitude']['#description'] = ' ' . t('See <a href=!url target=_blank>our help page</a> for more information.',
array('!url' => url('latlon_help')));
}
}
#6
Awesome, I got the code implemented in a module I made called formtheme.module which also uses hook_form_alter() to modify node forms. However, I'm trying to implement this on a case by case basis, so on one node type form the location fields are themed like x, and on another node type form the location fields are themed like y. I figure the most logical approach to this would be a 'switch' statement, but I'm not sure what to switch on. Going by hook_form_alter() I added the $form_id as a parameter at location_element_alter(), switching by $form_id, but it doesen't seem to be working. Here is my code
<?php
function formtheme_location_element_alter(&$element, $form_id) {
if (module_exists('devel')) {
dsm(func_get_args(), "formtheme_location_element_alter");
}
switch ($form_id) {
case 'uprofile_node_form':
if (isset($element['locpick'])) {
$element['locpick']['user_latitude']['#description'] = ' ' . t('Use decimal notation.');
$element['locpick']['user_longitude']['#description'] = ' ' . t('See <a href=!url target=_blank>our help page</a> for more information.', array('!url' => url('latlon_help')));
}
}
}
?>
I'd like to make it contextual by $form_id like I can with hook_form_alter(), do you know a good way to go about doing this?
I appreciate the help very much!
#7
/subscribe for the #3 addition.
Tested, works, I think it can be commited to allow to alter form element without having a hacked location module;
#8
Excellent Dave Cohen, this really worked.
#9
Hello,
@Dave Cohen, I want to remove the 'delete location' checkbox from all forms. Module version is 'Location 6.x-3.1-rc1'. I have applied the patch you provided at 1 but I don't know what to do next. I'm a beginner in both PHP and Drupal. I have no idea about how to use the code for hook_form_alter. I don't even know where hook_form_alter is located.
Any help will be very much appreciated.
Thanks.
#10
Tomasco, I don't have time to get you all the way there. But I'll share a snippet from my hook_form_alter. Look on drupal.org for how to write a module and implement hooks. And be warned this code is for Drupal 5.x. So for a 6.x site you will have to change the parameters passed into the function and more...
<?php
function sunflower_custom_form_alter($form_id, &$form) {
// here I modify user forms, this will be different for node forms.
if ($form_id == 'user_edit') {
/* you probably don't want this part
// In hook_user, we add location to personal info category.
if (isset($form['account'])) {
unset($form['locations']);
}
*/
if (isset($form['locations'])) {
//dpm(func_get_args(), "sunflower_custom_form_alter($form_id)");
foreach(element_children($form['locations']) as $key) {
$form['locations'][$key]['#title'] = t('Mailing Address');
}
if (!user_access('administer users')) {
foreach(element_children($form['locations']) as $key) {
$form['locations'][$key]['delete_location'] = array();
}
}
}
}
?>
#11
Thanks a lot, Dave.
#12
Here is a patch containing Dave's one line calling of drupal_alter for D6, worked like a charm for me. It would be great to get this in for D5 and 6
#13
The above patch for D6 doesn't work for me. I still can't access the location form fields in my hook_form_alter implementation after installing the patch.
#14
The patch creates a new hook called hook_location_element_alter
Within that hook, you can access the fields as $element['country'] etc. (edit - see comment #6)
#15
Ahhhh, that works! I skimmed through the comments too quickly and didn't piece it all together. Thanks!
#16
though the alter is nice, I believe there's already a core drupal 6 way in: after_build.
The issue with altering elements in form alter is that the element hasn't been processed.
However form calls after build functions after elements are processed(expanded) and before they're rendered.
<?phpfunction modulename_form_alter(&$form, $form_state, $form_id) {
switch($form_id) {
case 'nodetype_node_form':
$form['#after_build'][] = 'remove_location_description';
}
}
function remove_location_description(&$form) {
$form['field_location'][0]['locpick']['instructions']['#value'] = '';
$form['field_location'][0]['locpick']['map_instructions']['#value'] = '';
return $form;
}
?>
(Another example of an after_build on my 'blog' http://foxis.intheclosets.com/text/adding-attributes-changing-cck-field )
Haven't tested if can get the delete box gone, but should be able to.
#17
I agree that one of those uber-advanced triple-secret form trick likes
#after_buildis the way to go, if it can be made to work. I personally don't have time to figure it out.The module could provide the alter hook as a convenience. But its reasonable to not do so if Drupal core already provides a way.
#18
Doing a quick test it seems to work :>.
assume above has been done so after_build function is called
Assume field_location is the cck location field.
in the after_build function
<?phpfunction remove_location_description(&$form) {
if ($form['field_location'][0]['delete_location']) $form['field_location'][0]['delete_location']['#access'] = 0;
return $form;
}
?>
or for multi value:
<?phpfunction remove_location_description(&$form) {
if (!is_array($form['field_location'])) return $form;
foreach ($form['field_location'] as $key => $dontcare ) if (is_numeric($key) && $form['field_location'][$key]['delete_location']) $form['field_location'][$key]['delete_location']['#access'] = 0;
return $form;
}
?>
It's import to return $form or else the $form array will disappear (the after_build functions are called as $form = after_build_function = $form).
(Why I did access instead of unset or set to array: I prefer #access when removing an element on a forum so it's still there in the array in case a later piece of code expects it to be there it'll be there. Access will disallow access to an element; I believe it changes the element to a 'value' instead of whatever it was. For example #access = 0 on the author field, the author field will turn into 'author'=>array('#type'=>'value','#value'=>'whatever the value (default value) was?'). I believe it works the same in after_build as in form_alter.
Haven't tested to see how it'd be done with location_node or location_user, just location cck, but I bet something similar.
#19
Hi Guys,
I can't seem to get this to work for location cck - nothing in dpm($form['field_profile_location'][0]['delete_location']) at all - curious
#20
Actaully - there is no linked patch in #12 (simply goes to http://drupal.org/files/issues) so perhaps I'm missing an important piece of the puzzle. Can someone clarify? I will be happy to test, re-roll patch, pitch in, etc
#21
Scottrigby, what steps did you follow exectly?
Are you trying to do the alterations in just form_alter? If you are, then the field hasn't been built so there would be no delete_location yet.
#22
@hefox, yes - i think i was unsure about the state of this patch, or what patch was RTBC, or if wasn't a patch at all finally but a few possible solutions. Now i gather the patch in #12 was necessary :p -- was that just an expansion of #3?
#23
I think so, however I never tried that patch since as detailed above, the location element can also be reached in an after_build function, so I'm not sure if the patch will make it into module (even if figures itself out and reappears D:!)
#24
Hi - I uploaded that patch in #12, but not sure what has happened to it, I can confirm that it is just #3 in patch form.