Refactor form for adding classes to Styles entities

Created on 20 March 2023, over 1 year ago
Updated 8 August 2023, over 1 year ago

Problem/Motivation

The "classes" field on Styles entities uses a multivalued textfield with some ajax functionality

It's quite clumsy to remove classes, despite what the help text might make you think.

Also, the use of ajax makes functional testing more difficult. It also makes functional testing more important since it's custom ajax functionality rather than standard form API stuff.

Proposed resolution

It would make use and maintenance of this project easier if the ajax stuff were removed in favor of using a single form element to hold the multiple classes.

The single form element could be a textfield with space-delimited classes or a textarea with line-break delimited classes.

User interface changes

Simpler form

API changes

None

Data model changes

None

📌 Task
Status

Fixed

Version

2.0

Component

Code

Created by

🇺🇸United States danflanagan8 St. Louis, US

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @danflanagan8
  • Issue was unassigned.
  • Status changed to Needs review over 1 year ago
  • 🇮🇳India akshay_d Bangalore

    Hi team,
    I have updated the entity style classes field to have simpler form by updating the ajax enabled fieldset field to textfield.

    Please review the PR

    Thanks

  • Status changed to Needs work over 1 year ago
  • 🇺🇸United States danflanagan8 St. Louis, US

    Nice work, @akshay_d

    This worked well in m y manual testing, but there are still a few changes I'd like to see.

    First, I have a couple nitpicky things from the form build:

    +++ b/src/Form/StylesForm.php
    @@ -16,12 +16,7 @@ class StylesForm extends EntityForm {
    +    $classes = !empty($styles->get('classes')) ? $styles->get('classes') : NULL;
    

    I think I'd rather see this:

    $classes = $styles->get('classes') ?? [];

    And then later we can implode without any additional logic:

    +++ b/src/Form/StylesForm.php
    @@ -42,38 +37,14 @@ class StylesForm extends EntityForm {
    +      '#default_value' => $classes ? implode(' ', $classes) : '',
    

    That could be changed to:

    '#default_value' => implode($classes)

    And then I'd like to see the save method approached in a different way. We should override the parent's copyFormValuesToEntity method and deal with setting values in there. I think it would look like this:

      /**
       * {@inheritdoc}
       */
      protected function copyFormValuesToEntity(EntityInterface $entity, array $form, FormStateInterface $form_state) {
        $values = $form_state->getValues();
        foreach ($values as $key => $value) {
          if ($key === 'classes') {
            $entity->set('classes', explode(' ', $value));
          }
          else {
            $entity->set($key, $value);
          }
        }
      }
    

    Then the save method would look like this:

      /**
       * {@inheritdoc}
       */
      public function save(array $form, FormStateInterface $form_state) {
        $styles = $this->entity;
        $status = $styles->save();
    
        switch ($status) {
          case SAVED_NEW:
            $this->messenger()->addStatus($this->t('Created the %label Styles.', [
              '%label' => $styles->label(),
            ]));
            break;
    
          default:
            $this->messenger()->addStatus($this->t('Saved the %label Styles.', [
              '%label' => $styles->label(),
            ]));
        }
        $form_state->setRedirectUrl($styles->toUrl('collection'));
        return $status;
      }
    

    Note we're returning the status at the end which is something we are forgetting to do at the moment.

    This is a much better logical division of labor. Now the save method is only handling saving, messaging, and redirecting, which is what the docbloc says it should do.

    And now the copyFormValuesToEntity will do what it says it does, and do it correctly the first time.

  • Status changed to Needs review over 1 year ago
  • Open in Jenkins → Open on Drupal.org →
    Core: 9.5.x + Environment: PHP 8.1 & MySQL 5.7
    last update over 1 year ago
    6 pass
  • 🇮🇳India akshay_d Bangalore

    Thanks @danflanagan8 for reviewing the patch.

    Also, I made the requested change please re-review.

  • Status changed to Needs work over 1 year ago
  • 🇺🇸United States danflanagan8 St. Louis, US

    Looks good, @akshay_d. Thanks for the updates!

    I just have one nit. It looks like the word "or" is missing from this sentence:

    +++ b/src/Form/StylesForm.php
    @@ -42,38 +38,14 @@ class StylesForm extends EntityForm {
    +      '#description' => $this->t('Add one more classes by delimiting with space.'),
    

    Can you change this to read, "Add one or more space-delimited classes."

  • Status changed to Needs review over 1 year ago
  • Open in Jenkins → Open on Drupal.org →
    Core: 9.5.x + Environment: PHP 8.1 & MySQL 5.7
    last update over 1 year ago
    6 pass
  • 🇮🇳India akshay_d Bangalore

    @danflanagan8 Thanks for the detailed review.

    Also, Updated the patch please review.

  • Open in Jenkins → Open on Drupal.org →
    Core: 9.5.x + Environment: PHP 8.1 & MySQL 5.7
    last update over 1 year ago
    7 pass
  • Open in Jenkins → Open on Drupal.org →
    Core: 9.5.x + Environment: PHP 8.1 & MySQL 5.7
    last update over 1 year ago
    6 pass, 1 fail
  • 🇺🇸United States danflanagan8 St. Louis, US

    Thanks, @akshay_d!

    Here's an updated patch with tests. Ease of test coverage, after all, was part of the motivation here.

  • Status changed to Fixed over 1 year ago
  • 🇺🇸United States danflanagan8 St. Louis, US

    Ha! The interdiff mostly passed. :)

  • Automatically closed - issue fixed for 2 weeks with no activity.

Production build 0.71.5 2024