I am trying to put a simple message at the top of a node edit form when a user is creating a new node.
I added a \Drupal::messenger()->addMessage() inside a my form_alter hook but this prints when I open the edit form (good!) but also on the view of the node after the node is saved (bad!).

Looking in debugger I can see that the hook is run twice (load and submit); but I don't see any way of determining which version is being run.

The only thing apparent to me is that $form_state->requestMethod is different in both cases; but this is a protected property; so no access to it.

code shouldn't be required for this question, but:

function mymodule_form_alter(&$form, $form_state, $form_id) {
  \Drupal::messenger()->addMessage(t('some msg'), 'warning');
  • Usually when after save a node it takes you to the new page. I take it you made go bk to the node add page. – No Sssweat Nov 29 '19 at 2:45

You can get the request method from \Drupal::requestStack(), like this:

function mymodule_form_alter(&$form, $form_state, $form_id) {
  $request_method = \Drupal::requestStack()->getCurrentRequest()->getMethod();
  if ($request_method == 'GET') {
    // Add/Edit form.
  elseif ($request_method == 'POST') {
    // Form is being saved.
| improve this answer | |
  • I would have thought $form_state would have some sort of state property to show this; but your requestStack answer does do the trick. Thank-you. – liquidcms Nov 29 '19 at 9:03
  • You can't tell by the request method alone, it could be the other way. A form can be delivered in a POST request, for example through AJAX or a form can be submitted in a GET request. And you can't catch a submit action like this, because the form object could have been cached and then the alter hook is not invoked. – 4k4 Dec 1 '19 at 10:20

When there is no user input the form is loading for the first time and it is not submitting.

Additionally you can check the entity whether it is new, if you don't want this condition to be true when the form is loading for an existing node:

if (!$form_state->getUserInput() && $form_state->getFormObject()->getEntity()->isNew()) {
  // first load of the form
| improve this answer | |
  • Hmm, yes, that would mostly work; but not if editing the form. Is there not a way to distinguish between form load and form submit? – liquidcms Nov 28 '19 at 19:51
  • OK, this is the answer on Form API level and it doesn't distinguish whether the form is loaded for a new or an existing node. You can check this on the entity. see the edited answer. – 4k4 Nov 28 '19 at 20:03

You can check using @4k4's answer. I think that's probably the best way if you want to trigger against any new node.

However, if you're trying to do this for just one type, node forms have two different form ids whether they're being created or edited. The form ids match a pattern like:

  • New node: node_TYPE_form
  • Existing node (editing): node_TYPE_edit_form

For example, you can act on the initial load of the Basic Page create form like:

 * Add message to node:page create form.
 * Implements hook_form_FORM_ID_alter().
function mymodule_form_node_page_form_alter(&$form, $formState) {
  // Check if this is the initial load of the form.
  if (empty($formState->getUserInput()) {
    // Do stuff on node create form initial load.
    \Drupal::messenger()->addMessage(t('You're creating a Basic Page node.'), 'info');
| improve this answer | |

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.