Usually when adding ['#access'] = FALSE to form elements, it hides it from the form rendering, but it passes its value to the form validation and submit handlers. So I thought I could do the same with profile2.

I created a date field for 'last updated' on my profile and I've put in a date and saved the entity. it works, the date is displayed on the profile view page. I want to hide this field from the form because I want to handle its value with code on entity save. so here is my form_alter which hides the field from the form:

function mymodule_form_alter(&$form, &$form_state, $form_id) {
      $form['profile_profile']['field_last_updated']['#access'] = FALSE;
}

And this hides the form date element. but on saving the form, the date value is dropped from the database and not displayed on the profile. I'm not sure whether this is a bug or not. Here is the var_dump of the field element during the form_alter.

Array
(
    [#type] => container
    [#attributes] => Array
        (
            [class] => Array
                (
                    [0] => field-type-datestamp
                    [1] => field-name-field-last-updated
                    [2] => field-widget-date-text
                )

        )

    [#weight] => 26
    [#tree] => 1
    [#language] => und
    [und] => Array
        (
            [0] => Array
                (
                    [#entity_type] => profile2
                    [#bundle] => profile
                    [#field_name] => field_last_updated
                    [#language] => und
                    [#field_parents] => Array
                        (
                            [0] => profile_profile
                        )

                    [#columns] => Array
                        (
                            [0] => value
                        )

                    [#title] => Last updated
                    [#description] => 
                    [#required] => 
                    [#delta] => 0
                    [#weight] => 0
                    [#type] => date_combo
                    [#theme_wrappers] => Array
                        (
                            [0] => date_combo
                        )

                    [#default_value] => Array
                        (
                            [value] => 2011-12-09 14:53:30
                        )

                    [#date_timezone] => America/New_York
                    [#element_validate] => Array
                        (
                            [0] => date_combo_validate
                            [1] => date_widget_validate
                        )

                )

            [#theme] => field_multiple_value_form
            [#field_name] => field_last_updated
            [#cardinality] => 1
            [#title] => Last updated
            [#required] => 0
            [#description] => 
            [#prefix] => <div id="profile-profile-field-last-updated-add-more-wrapper">
            [#suffix] => </div>
            [#max_delta] => 0
            [#after_build] => Array
                (
                    [0] => field_form_element_after_build
                )

            [#language] => und
            [#field_parents] => Array
                (
                    [0] => profile_profile
                )

        )

    [#access] => 
)

Comments

southweb’s picture

Love to know how you get on with this. But I was a bit confused when I looked into a similar issue:

Firstly the formid is user_profile_form not profile_profile

Secondly, I couldn't see any of my fields to be rendered either in

hook_form_alter

or

hook_user_profile_form

bbinkovitz’s picture

I am wondering if that's related to this: #1419120: data entered in list (text) "checkbox" widget does not display on saved node

In that bug, it's reported that using some of the available submit handlers allows the checkbox values to be saved, but not others. Upon inspection, I noticed that the ones that do not save checkboxes are the ones that have #access not set to TRUE. I don't know if it's the cause, though.

It seems more likely to be a bug than a deliberate feature, since it's applied erratically depending on field type.

mokargas’s picture

Same issue here. Trying to move one profile to another page for a signup form, setting ['#access'] = FALSE for step 1 of my form and then ['#access']= TRUE for step 2 will nix the field utterly. Any ideas?

ron_s’s picture

Category: Support request » Bug report

I'm not sure this is just a support request -- I'm going to change to a bug report. It seems to be due to how Profile2 structures its data and builds the $form array. I've spent a lot of time reviewing this issue, and I do not have such problems with other modules or custom-built forms.

I have a Profile2 profile with a number of fields, and the fields need to be set as optional, required, or hidden based on a dropdown select. The select is tied to an Ajax callback, which rebuilds dependent fields based on the user selection (FYI, I'm sure someone will ask why the Conditional Fields module isn't being used to do this -- the rules are too complex and much more straightforward to handle with some custom code).

This should be fairly easy to do... all that's necessary is to toggle the values for #access and #required based on the dropdown select, and rebuild the form fields with an Ajax command. The #required field settings worked perfectly, but #access would not work no matter what method I tried. I watched the value of #access change in real time from FALSE to TRUE, and the Ajax command ran successfully, but there was no change on the screen. Even tried performing a form rebuild after processing completed, but it made no difference.

The *only* time I started to see fields when toggling #access was when I decided to do something crazy and looped through every level of the $form['profile_xxxxx']['field_xxxxxx'] arrays, and set every part to #access = TRUE. This caused the fields to be displayed in certain situations, but it was definitely not accurate and did some other strange things. I shouldn't have to jump through such hoops anyway... I should be able to toggle $form['profile_xxxxx']['field_xxxxxx']['#access'] between TRUE and FALSE and have the field displayed after Ajax callback.

In the end, I gave up trying to control the display using #access and instead set a class attribute on each field that toggles CSS display. I don't like using this approach because the fields are still present -- they are just hidden from user view.

As far as I know Form API supports toggling #access (using Ajax or just as part of normal processing) and retaining values, and not sure why there are such issues with Profile2.

ron_s’s picture

Title: Form API ['#access'] = FALSE drops form values » Form API ['#access'] = FALSE drops form values, does not update correctly, for both standard and Ajax form rendering
Issue tags: +Ajax, +form API, +#access, +profile2, +Profile 2, +form_alter, +form_state, +form

Updating the title and tags to help others who might be looking for this issue.

jamescook’s picture

For what it's worth I can report that this issue still exists in 2016
Drupal7 installation.
Setting #access on (only custom?) user fields leads to some kind of inconsistency.
The field is not shown, but, it seems, submitting the form causes the field to be set to empty or the relationship to the user to be lost.
The weird thing is that the DB seems still to contain the old contents for the field - linked to the entity.
E.g.:

mysql> select * from field_data_field_ref_2016 where entity_id=1224;
+-------------+--------+---------+-----------+-------------+----------+-------+----------------------+
| entity_type | bundle | deleted | entity_id | revision_id | language | delta | field_ref_2016_value |
+-------------+--------+---------+-----------+-------------+----------+-------+----------------------+
| user        | user   |       0 |      1224 |        1224 | und      |     0 |                  526 |
+-------------+--------+---------+-----------+-------------+----------+-------+----------------------+

But on the "surface" -(e.g. in "view" displays for this user) the value 526 is gone.
I have done drush cc all and flushed memcache so this is not a caching issue.

mickadoo’s picture

Still an issue for me:

$form[$part]['#access'] = FALSE;

Will hide the form, but submission deletes the data. It's a real pain because I'm trying to use it when overriding the user edit page to hide the role edit, so submitting the form when hiding the user roles means that the user loses all their roles.

apaderno’s picture

Issue tags: -#access
apaderno’s picture

Issue tags: -Ajax, -form API, -profile2, -Profile 2, -form_alter, -form_state, -form