4

I added some search block in my theme, and I placed each of them in a custom place.
I want to edit each of theme by using function hook_form_FORM_ID_alter for this purpose.

Provide a form-specific alteration instead of the global hook_form_alter().

Modules can implement hook_form_FORM_ID_alter() to modify a specific form, rather than implementing hook_form_alter() and checking the form ID, or using long switch statements to alter multiple forms.

How can I find each search block form ID? How can I edit them in ThemeName_form_search_block_form_alter() to add special classes to each of them?

I used the Devel module for this purpose, but It seems that for the Devel module, all those forms have the same ID (search_block_form).

This is the code I used.

function ThemeName_form_search_block_form_alter(&$form, &$form_state, $form_id) {
  drupal_set_message(kint($form));
  $form['keys']['#attributes']['placeholder'][] = t('Search');
  $form['actions']['submit']['#attributes']['class'][] = 'my-class';
}
3
  • What version of Drupal?
    – Jaypan
    Mar 6, 2017 at 12:57
  • The answer is different depending on the version. Which version are you using?
    – Jaypan
    Mar 6, 2017 at 13:43
  • I'm using Drupal 8 version. Mar 6, 2017 at 13:44

1 Answer 1

4

The first thing to do is extend SearchBlockForm so you can give it a custom ID. Put code in mymodule/src/Form/MymoduleSearchBlockForm.php

namespace Drupal\mymodule\Form;

use Drupal\search\Form\SearchBlockForm;

class MymoduleSearchBlockForm extends SearchBlockForm
{
  protected $formIdentifier;

  public function setFormIdentifier($formIdentifier)
  {
      $this->formIdentifier = $formIdentifier;
  }

  public function getFormId()
  {
    $form_id = 'search_block_form';
    if($this->formIdentifier)
    {
        $form_id .= '-' . $this->formIdentifier;
    }
    return $form_id;
  }
}

Then you can call your form like this:

$form = \Drupal::service('class_resolver')->getInstanceFromDefinition('Drupal\mymodule\Form\Mymodule\SearchBlockForm');
$form->setFormIdentifier('some_custom_value');

return \Drupal::formBuilder()->getForm($form);

The key line of code here is this one:

$form->setFormIdentifier('some_custom_value');

If you pass a different value each time you generate the form, each form will get a different form ID. The form ID will be:

search_block_form-some_custom_value

Which will then be available in hook_form_alter with a $form_id of search_block_form-some_custom_value

6
  • 1
    Thanks for your help and attention, I appreciate you a lot, but in this special case i don't think that we should use module, because it's a theme level problem and it's not good and logical to use module for very simple and handy ability like this. Mar 6, 2017 at 14:57
  • 1
    You want to override the form in your theme, but creating a form that is overrideable is a module-level issue. If you change themes, and still want multiple versions of the search form on the page, and you put your solution in the theme, you would then need to copy the code from one theme to another. Any time that's the case, it's a module-level issue, not a theme level issue. Module alterations are for alterations that should persist between themes. Anyways, that's a solution to the problem you asked about. You don't have to use it. But it's there for someone else in the future.
    – Jaypan
    Mar 6, 2017 at 14:59
  • 1
    Thanks again, but the problem also arise here, because I don't want to override default theme system functionality, For example you imagine that I want to create a search block with two different look and style one for large screen sizes like desktops and another for small screen like phone device set or you imagine that I want to have one search block for header and another for footer as It's common in most sites. Mar 6, 2017 at 15:13
  • 2
    And that's what the code I gave you allows you to do. Functionality isn't overridden, it's extended. That's one of the core benefits of OOP - being able to extend code.
    – Jaypan
    Mar 6, 2017 at 15:16
  • Sounds good thank you so much and I appreciate you hearty and a lot! I was hoping for more simple way, but as this is the most user friendly and fool proof method, I happily accept it. Thanks again for every thing ;) Mar 7, 2017 at 19:34

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.