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

Dave Cohen - February 23, 2009 - 21:16
Category:support request» feature request
Status:active» needs review

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.

AttachmentSize
location_delete_alter.diff 463 bytes

#2

Dave Cohen - February 24, 2009 - 20:26

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

Dave Cohen - February 24, 2009 - 20:47

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

YesCT - April 13, 2009 - 19:41

Tagging with a theming tag for now.

#5

Dave Cohen - June 29, 2009 - 19:36

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'] = '&nbsp;' . t('See <a href=!url target=_blank>our help page</a> for more information.',
                                                                         array('!url' => url('latlon_help')));
  }
}

#6

corona ronin - July 24, 2009 - 18:37

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'] = '&nbsp;' . t('Use decimal notation.');
   
$element['locpick']['user_longitude']['#description'] = '&nbsp;' . 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

zmove - August 6, 2009 - 07:14
Status:needs review» reviewed & tested by the community

/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

yasir farooqui - August 14, 2009 - 11:17

Excellent Dave Cohen, this really worked.

#9

tamasco - September 3, 2009 - 19:46
Version:5.x-3.x-dev» 6.x-3.1-rc1

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

Dave Cohen - September 4, 2009 - 09:50

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

tamasco - September 5, 2009 - 05:12

Thanks a lot, Dave.

#12

nirbhasa - October 8, 2009 - 13:59

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

AttachmentSize
locationd6_element_alter.patch 297 bytes

#13

jsenich - October 8, 2009 - 15:25

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

nirbhasa - October 8, 2009 - 16:07

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

jsenich - October 8, 2009 - 16:41

Ahhhh, that works! I skimmed through the comments too quickly and didn't piece it all together. Thanks!

#16

hefox - October 22, 2009 - 14:23

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.

<?php
function 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

Dave Cohen - October 23, 2009 - 00:07

I agree that one of those uber-advanced triple-secret form trick likes #after_build is 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

hefox - October 23, 2009 - 01:00

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

<?php
function 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:

<?php
function 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

scottrigby - November 23, 2009 - 21:36
Version:6.x-3.1-rc1» 6.x-3.x-dev

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

scottrigby - November 23, 2009 - 21:42
Status:reviewed & tested by the community» active

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

hefox - November 24, 2009 - 00:58

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

scottrigby - November 24, 2009 - 01:20

@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

hefox - November 24, 2009 - 12:51

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

nirbhasa - November 24, 2009 - 23:15

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.

 
 

Drupal is a registered trademark of Dries Buytaert.