13

I am trying to make some of the Drupal profile form fields as read-only in edit mode. I am using the following code in hook_alter

$form[field_organisation_company_name][und][0]['#after_build'][]='_build_element_readonly';

function _build_element_readonly($element, &$form_state) {  
    $element['value']['#attributes']['readonly'] = 'readonly';
    return $element;
}

In the UI filed is showing as read-only, but still, I can change the value using firebug and save. Is there any way to prevent this behavior?

6

It sounds like you could accomplish what you need to with Field Permissions. On a field-by-field basis you can set permissions to:

  • Create own value for the field
  • Edit own value for the field
  • Edit anyone's value for the field
  • View own value for the field
  • View anyone's value for the field

So you would easily be able to allow your users to create the value for the field initially, but as soon as they have it only becomes editable by an admin.

  • +1. As OP wants to allow admins to edit the value, field_permissions would be easier than doing the work in dirty way. – AyeshK Apr 9 '13 at 10:11
  • Yes, this is a much better answer than mine :) – Alfred Armstrong Apr 9 '13 at 11:13
6

When you set a field as readonly, browser locks the field and sends data back to the server upon submission. Other attribute is disabled that locks the field and does not sends data back to the server.

For both of cases, you can forcefully set the value to be the same after submission. So, even when the field is set to readonly or disabled, and the user modified the HTML and sent different data, $form_state['values'] will remain unchanged.

function _build_element_readonly($element, &$form_state) {  
    $element['value']['#attributes']['readonly'] = 'readonly';
    $element['value']['#value'] = isset($element['value']['#default_value']) 
       ?  $element['value']['#default_value']
       :  ''; 
    return $element;
}

Note that we set #value from #default_value. #default_value is the usual way to set the default value that loads up when the form is built, and $form_state['values'] will contain the default_value or user-input. When you set #value explicitly, user-input is ignored and #value will be used.

Anyways, I'd recommend to use '#access' => FALSE, when hiding form elements. It will remove the element completely, while allowing you to use its values.

1

You cannot prevent Firebug from changing readonly fields. But if the textfield is readonly, it's only purpose is to display data. So why not change the input-element against a text-element?

You could use the "disabled" attribute instead, because disabled input-fields are not beeing sent to the server.

You can remove the "disabled" attribute with firebug as well, but the drupal core does not react on changes of disabled input fields!

  • Thanks larrydahooster for the help. My requirement is something like to lock some of the fields filled by user at the time of registration . While on the profile edit mode want to display this information to the user , but want to prevent the user to update these field . Only super user can edit these fields – Jayesh Jose Apr 9 '13 at 8:59
1

The safest way to do this is to change the type of the field to be an 'item'. http://api.drupal.org/api/drupal/developer!topics!forms_api_reference.html/7#item

  • Using #disabled attribute I solve the problem . In my case only some users can edit the field , where as others only can view the field . I written a logic based upon the user role and solve the problem . Thank You all – Jayesh Jose May 9 '13 at 10:06
1

You may use Field Permissions + Field Readonly.

Field Permissions will allow you to make some of your fields non-accessible to certain users.

Field Readonly will allow you to display the non-accessible fields as read-only items on edit forms (instead of hiding them).

1

I think using #disabled = true; is the easiest way to achieve this instead of adding some heavy module to your core, as an example I disable edit of the custom image field in user_profile_form when it's filled by the user before.

function MY_CUSTOM_MODULE_form_alter(&$form, $form_state, $form_id){

        if($form_id == 'user_profile_form'){
            if($form['field_national_front']['und'][0]['#default_value']['fid']){
                $form['field_national_front']['und']['#disabled'] = true;
             }
          //ym($form);
        }
}

Also, you can check the role of user and just disable (readonly field) for not admin users.

    function MY_CUSTOM_MODULE_form_alter(&$form, $form_state, $form_id){
       global $user;
       if($form_id == 'user_profile_form'){
           if($form['field_national_front']['und'][0]['#default_value']['fid'] && !in_array('webadmin', $user->roles)){
              $form['field_national_front']['und']['#disabled'] = true;
         }
//ym($form);
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.