“ How you look at it is pretty much how you'll see it ! "
Recently, in a project, I came across a problem statement where I was supposed to display a Node Form to an authenticated user with access to edit only limited set of fields, in a way similar to maintaining a Linkedin profile.
The ideal solution is to create a separate form mode with the ability to access only a limited number of fields and keeping all other fields disabled from displaying in the form itself .
In my mind, this looked pretty easy to implement; but I was stuck at a point where I had to use this “Custom Form Mode”. This is when I realised, Drupal 8 core does not provide any interface or help to make use of the “Custom Form Mode”. We have to programmatically call the custom form mode and display it to the type of user intended.
Also I came across this module Form Mode Control which does provide help in terms of managing permissions and form modes through an admin interface, but if you want to avoid installing another contributed module for a small implementation(similar to our case) which does not involve managing multiple roles / users and also does not require providing a manageable admin interface then this simple solution is a way to go !
Through this post, we’ll look into the following :
- Creation of a Custom form Mode
- Use of the form mode to display Node form as a block to an authenticated user.
Before we move ahead with actual implementation, first let’s understand the basics
What is a Form Mode and how is it different from View Mode ?
According to the Drupal documentation here
- Form modes are a way to create different field configurations with the same content entity bundle.
- Form modes allow for multiple sets of field widget orderings and customizations, just as view modes allow for different orderings and customization of field formatters.
- In addition to form modes, form operations allow for defining which classes should be used for forms like a node delete form.
Whereas,
- View modes exist to allow Drupal site building tools like Entity Reference fields to request a given entity be rendered in a certain way.
With this background, let’s learn how to do this !
Create a Form Mode :
- First step is to create a separate Form mode at : /admin/structure/display-modes, This page will provide 2 options , Form Mode and View Mode. Since here we are going to create a form mode, we will select “Form Mode” .
- In the next step, we will get an option to select which form should be created.. Ex. Content, Taxonomy Term, Contact Form. In our case let’s select Content. And provide the name of the Form mode as required. [Refer the Screenshot Attached]
- After creating a form mode , let’s use it for our content type. In my case , I have created a custom content type by the name “Agency” and added a few fields to it. To use the custom form mode created, head towards /admin/structure/types/manage/agency/form-display and at the bottom of the page you should be able to see the “Custom Display Settings” tab, here you should be able to see the your custom form mode in the list. Simply check and enable this Form Display [Refer the Screenshot Attached]
- In this form mode, you can order or enable/disable the fields that you want to display.
Create a Module and Set Form Class :
- The next step is to create a custom Module and set Form Class as follows: [Refer the code snipped below]
/**
* Implements hook_entity_type_build().
*/
function display_custom_form_mode_entity_type_build(array &$entity_types) {
$entity_types['node']->setFormClass('company_form_mode', 'Drupal\node\NodeForm');
}
Create a Block and Call the Node Form :
- Now let’s create a custom Block and Call the Node Form as follows : [Refer the code snipped below].
/**
* Implements \Drupal\block\BlockBase::build().
*/
public function build() {
$build = array();
$nids = $this->getNodeFromCurrentUserProfile();
//Display Node Form.
if (!empty($nids)) {
$node_form = Node::load($nids);
$build['form'] = $this->entityFormBuilder->getForm($node_form, 'company_form_mode');
}
return $build;
}
public static function getNodeFromCurrentUserProfile() {
$nids = '';
// Fetch Email ID
$current = \Drupal::currentUser();
if ($current->id()) {
$account = \Drupal\user\Entity\User::load($current->id());
if (!empty($account)) {
$email = $account->getEmail();
}
}
//Fetch Company Id.
if (!empty($email)) {
$query = \Drupal::database()->select('node__field_mail', 'nce');
$query = $query->fields('nce', array('entity_id'));
$query = $query->condition('nce.bundle
', 'agency');
$query = $query->condition('nce.field_mail_value
', $email);
$nids = $query->execute()->fetchField();
}
return $nids;
}
- In the code snipped above, I have created a link between Current Drupal User account and Company Content by the field “Mail”. Further, the Company Node is fetched for a specific User, in order to display different Content Forms to different users.
Create a Page and Place the Block :
- Next ,place the block on a page and now you should be able to see the Custom Node Form as follows: [Refer the Screenshot Attached].
With this, we have now successfully created the Custom Form Mode and used it to display it as a Block to an authenticated user.We have come a long way in Drupal 8 and now it’s high time to get some implementations up and running as a part of Drupal Core as things like these are an essential component of site Building. If it was difficult to understand in terms of steps, please refer the Youtube video Link below to get some more clarity on the steps :
Also you can follow this github link to get the code and get the Custom Form Mode implementation up and running : https://github.com/panshulK/CustomFormMode
Thank You.
Our Services
Customer Experience Management
- Content Management
- Marketing Automation
- Mobile Application Development
- Drupal Support and Maintanence
Enterprise Modernization, Platforms & Cloud
- Modernization Strategy
- API Management & Developer Portals
- Hybrid Cloud & Cloud Native Platforms
- Site Reliability Engineering