How to hide a field from a form and add a functional test for it in Drupal 8/9

Pasan Gamage
3 min readJun 17, 2022

--

In this article, we are going to have a look at how to hide a form field from all users and how to add a functional test to verify if it is working.

To demonstrate this, I will be using the Drupal redirect module.

Task

The task at hand is to hide the language field from all the users from redirect add and edit forms.

Code

In a custom module, we can add the below code to app/modules/custom/my_module/my_module.module

/**
* Implements hook_form_alter().
*/
function my_module_form_alter(&$form, FormStateInterface $form_state, $form_id) {
// Hide language preference field as it should be left as UND by default.
// This is because to avoid confusion and 'en' being selected by the editors.
if (in_array($form_id, [
'redirect_redirect_form',
'redirect_redirect_edit_form',
], TRUE)) {
if (!empty($form["language"])) {
$form["language"]["#access"] = FALSE;
}
}
}

By setting $form[“language”][“#access”] = FALSE; all logged-in users will not see the language field in both add and edit form where redirect_redirect_form is the add form ID and redirect_redirect_edit_form is the edit form ID.

If you want to hide the field only from specific user roles, you need to add that logic in to a conditional statement rather than setting $form[“language”][“#access”] = FALSE; directly.

Writing the test

Create a .php file with below code at;

app/modules/custom/my_module/tests/src/Functional/AdminFormTest.php

There are two parts in the test. They are the add form and the edit form.

<?php

namespace Drupal\my_module\Functional;

use Drupal\Tests\BrowserTestBase;

/**
* Functional tests for the forms in cms admin.
*/
class AdminFormTest extends BrowserTestBase {

/**
* Make sure the language field is hidden from UI.
*/
public function testRedirectForm() {
// Login and navigate to add form.
$account = $this->drupalCreateUser([
'view test entity',
]);
$this->drupalLogin($account);
$this->drupalGet('/admin/config/search/redirect/add');
$page = $this->getSession()->getPage();
$this->assertNotEmpty($page->findField('Path'));
$this->assertEmpty($page->findField('Language'));

// Fill the form.
$path = $page->findField('redirect_source[0][path]');
$this->assertNotEmpty($path);

$to = $page->findField('redirect_redirect[0][uri]');
$this->assertNotEmpty($to);

$path->setValue('test-redirect');
$to->setValue('Homepage (1)');

// Save new redirect.
$page->findButton('Save')->click();
$this->drupalGet('/admin/config/search/redirect');

// Find and edit the newly created record.
$editButton = './/*[@id="views-form-redirect-page-1"]/table//tr[last()]//td[last()]//*[1][name()="a"]';
$this->assertNotEmpty($page->find('xpath', $editButton));
$page->find('xpath', $editButton)->click();
$this->assertNotEmpty($page->findField('Path'));
$this->assertEquals('test-redirect', $page->findField('Path')->getValue());
$this->assertEmpty($page->findField('Language'));

}

}

Explanation

If you are wondering how I figured out the values to use infindField() is by simply right-clicking on the form in the browser and finding the attribute name

You can use input ID, Name or label for it.

Ex.

<input data-disable-refocus=”true” data-drupal-selector=”edit-redirect-source-0-path” type=”text” id=”edit-redirect-source-0-path” name=”redirect_source[0][path]” value=”” size=”60" maxlength=”2048" class=”form-text required” required=”required” aria-required=”true” data-once=”drupal-ajax”>

Therefore,

$path = $page->findField('redirect_source[0][path]');

After saving the add form, we need to navigate back to the redirect list view and find the edit form.

In order to find the edit button, we are using XPath.

$editButton = './/*[@id="views-form-redirect-page-1"]/table//tr[last()]//td[last()]//*[1][name()="a"]';$this->assertNotEmpty($page->find('xpath', $editButton));

I’m using last() because the new records go to the bottom of the list view.

I will add the resources at the end of this article that I found useful in finding the XPath of a HTML element.

Resources

https://devhints.io/xpath — Cheat sheet

http://xpather.com/ — To test the XPath

--

--

Pasan Gamage
Pasan Gamage

Written by Pasan Gamage

Backend Developer | Motorbike enthusiast

No responses yet