2

I've created a custom entity module, and the form for it uses field_collections. The only form field I've defined programmatically is the title, the rest of the fields and field collections for this form I've defined via the Drupal 8 interface.

I have a particular field collection with 8 dropdowns and a large textarea. I want the person using the form to be able to set the 8 dropdowns to certain values automatically based on the contents entered in the textarea, but only by clicking a button since they should also be able to manually set the dropdowns. The field_collection itself has unlimited allowed values, so there should be one button for each instance of that field collection in the form.

It was my plan to just get an inactive button into the form and add a front-end script to have it trigger a Javascript function, but I can't seem to figure out how to get a button in the form. It doesn't seem to exist as an option in field_collection field definitions. I had a prototype of this working in jQuery, but I'd rather not use jQuery to insert elements into the form if I can avoid it. So far Googling has proven fruitless. Is it possible to do this with hook_form_alter() perhaps?

  • Can you add some of your code to the question? Or perhaps a screenshot of the form? – George Aug 2 '16 at 13:56
3

I ended up asking Sacrilegious, one of the regulars in #drupal-support, and he offered this solution:

Define a new class in {module root}\Plugin\Field\FieldWidget names FieldCollectionCustomEmbedWidget.php

<?php

/**
 * @file
 * Contains \Drupal\{module}\Plugin\Field\FieldWidget\FieldCollectionCustomEmbedWidget.
 */

namespace Drupal\{module}\Plugin\Field\FieldWidget;

use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Element;
use Drupal\field_collection\Plugin\Field\FieldWidget\FieldCollectionEmbedWidget;

/**
 * Plugin implementation of the 'field_collection_custom_embed' widget.
 *
 * @FieldWidget(
 *   id = "field_collection_custom_embed",
 *   label = @Translation("Embedded custom"),
 *   field_types = {
 *     "field_collection"
 *   },
 * )
 */
class FieldCollectionCustomEmbedWidget extends FieldCollectionEmbedWidget {

  /**
   * {@inheritdoc}
   */
  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
    $element = parent::formElement($items, $delta, $element, $form, $form_state);

    $element['custom_button'] = [
      '#markup' => '<div class="guess-compatibility js-form-button field-add-more-submit button js-form-submit form-submit">button text</div>',
      '#value' => t('button text'),
      '#attributes' => [
        'class' => [
          'my-custom-button-class'
        ],
      ],
    ];

    return $element;
  }
}

Then under Structure, I went into the settings for the form containing the field that needed this button, and under "Manage Form Display", I changed the widget type of the field to the newly added "Embedded Custom." Now the button is there.

  • 1
    Brilliant solution. – Jimmy Ko Aug 3 '16 at 21:26

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.