On a node edit form, I want to make certain fields be non-editable by all users but the values stored in them to be visible on the form. My thought was to just print them out as text instead of in an HTML form element. What is the best way to accomplish this?

To provide some context, these values are populated via a migration and should not be edited on the site.

2 Answers 2


Changing a form field to a markup element creates problems if the form field is checked by a form validation handler or a form submission handler: #markup elements are not passed in the $form_state['values'] array, which contains the current values associated with the form fields (and which is the array used by the form handlers—both the validation and the submission handers). This method works for form fields that use #element_validate, as #element_validate is also used from the #markup form fields.
If you are sure there aren't form validation handlers that check the value of the form fields you want only to show, then you can adopt this method. As third-party modules could add form validation handlers for those fields, I would not suggest to adopt it, if not in the case the form fields are created by a custom module you created, and no other developers will alter the form fields added by your code (or alter the form created by your code).

Using #attributes to make a field read-only is not a secure method (as Berdir pointed out); to be sure the form field values are not altered, you should compare them with the value contained in the form before it shows (which means to check the values contained in the $form array). This method has still problems with the form validation handlers (and form submission handlers) because other modules will act as those values are not read-only; only your code will act like as those values are read-only. The other reason to not adopt this method is that is "easier" to add the #disable attribute to a form field.

Another method is to change the form field type to #hidden. If you choose this method, then you need also to render the form field value using #prefix, and #suffix.

$form['field']['#type'] = 'hidden';
$form['field']['#prefix'] = '<strong>' . t("Field title: ") . '</strong>' . 

As side note, if those form fields don't need to be visible to users, but they must be present in the $form_state array because other modules (including the one that created the form) implement form handlers, then you can change the form field type to #value.


You can use the yourmodule_form_alter to change fields #type from textfield to markup.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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