Problem/Motivation

There was a discussion to add a JS based collape, or always display the individual edit / preview / close buttons.
#2650306: Always offer Collapse/Preview/Edit
#2721941: Add a JS based collapse / expand

On our paragraphs sprint, we realised that the close button is currently simply too much limited and we should further iterate on the 3 states before adding new complexity.

Proposed resolution

Instead of per-item control, we need a way to bulk close / open / preview all paragraphs.

On each paragraphs widget, a new button is added that will offer the actions. A drop down button seems to fit best.

Initially, the close all can ignore nesting. Later we might still want to display the children, also to allow easy drag and drop.
#2658694: Move a nested Paragraph across fields and nesting

To complete the experience and make the user aware of what's inside a collapsed paragraph, the closed type should receive some one line summary.

Remaining tasks

User interface changes

An added button "close / open / preview all" per widget.

Comments

miro_dietiker created an issue. See original summary.

miro_dietiker’s picture

Priority: Normal » Major

Promoting for better visibility, because we think this is a severe UI improvement.

Unsure how we are going to handle configurability, combined with the "always show close / edit / preview buttons" issue.
We might decide that the setting only defined the initial state of the widget.
Except we see that the buttons totally clutter the UI.
But again, we want to find a way that the UI is always nice and it should not be needed to disable UX functions because you need better UX. ;-)

johnchque’s picture

Assigned: Unassigned » johnchque
Issue tags: +DevDaysMilan

I think this is a good step to start with.

miro_dietiker’s picture

Yeah, great to move forward here!

Would be great to discuss styling on a visual basis with @tassilogroeper and others.
The button will add weight to the UI and we need to find a way to keep it light. I fear the right side will be button cluttered. We should not just add the button and try to optimise UX later. :-)

johnchque’s picture

Status: Active » Needs review
StatusFileSize
new2.67 KB

Created an early patch, just for "Collapse all" It also work inside nested Paragraphs. Still needs test and I'm not sure how to continue with adding support for "Open all".

miro_dietiker’s picture

Status: Needs review » Needs work

Since this is a visual element, please provide a screenshot.

The last submitted patch, 6: add_a_close_edit-2738645-6.patch, failed testing.

The last submitted patch, 6: add_a_close_edit-2738645-6.patch, failed testing.

The last submitted patch, 6: add_a_close_edit-2738645-6.patch, failed testing.

johnchque’s picture

Status: Needs work » Needs review
StatusFileSize
new2.96 KB
new1.03 KB

Added small changes, now it also collapse/open all.

Status: Needs review » Needs work

The last submitted patch, 11: add_a_close_edit-2738645-11.patch, failed testing.

The last submitted patch, 11: add_a_close_edit-2738645-11.patch, failed testing.

The last submitted patch, 11: add_a_close_edit-2738645-11.patch, failed testing.

johnchque’s picture

StatusFileSize
new54.43 KB

Actually the button is not well placed. Still need to work on it.

miro_dietiker’s picture

+++ b/src/Plugin/Field/FieldWidget/InlineParagraphsWidget.php
@@ -746,6 +746,19 @@ class InlineParagraphsWidget extends WidgetBase {
+        '#value' => t('Collapse all'),
...
+        '#submit' => [[get_class($this), 'paragraphsMultipleSubmit']],

@@ -960,6 +973,34 @@ class InlineParagraphsWidget extends WidgetBase {
+  public static function paragraphsMultipleSubmit(array $form, FormStateInterface $form_state) {

Unfortunate naming... It's paragraphs anyway, and multipleSubmit is meaningless.
It's a toggle now, right? Button label is also always Collapse.

Also tests... ;-)

ada hernandez’s picture

Issue summary: View changes

Hi everyone, I tested the #11 patch and when I add a new paragraph content, it is not saved.

cleverhoods’s picture

Started working on this

johnchque’s picture

Assigned: johnchque » Unassigned
Issue tags: -DevDaysMilan

Not sure when I will find time for working on this.

miro_dietiker’s picture

Promoting this issue. With our deep nested content and issues of paragraphs that sometimes mixes behavior plugin settings, ... we would love to be able to collapse all children with a single click.

toncic’s picture

Assigned: Unassigned » toncic
Status: Needs work » Needs review
StatusFileSize
new11.75 KB
new9.7 KB

Made some progress, Collapse all button works fine for nested paragraph and when we have more than one filed, but still there is a problem from #17.
Also added tests.

miro_dietiker’s picture

Any ui screenshot update?
Please also for a nested situation.

What is remaining here?

miro_dietiker’s picture

Title: Add a close / edit / preview all button » Add a close / edit all button
Status: Needs review » Needs work

Oh it still looks the same. :-)
The button should be right aligned as all other such buttons.
And it should play well with the Content / Behavior tabs if present. They should be on the same line.

I think we should only display the button if we have multiple children. Otherwise it's a full duplicate.

Also the button is still only collapse all. The issue title is proposing a drop down with both expand=edit and collapse all actions.
We should not care about "preview" though as we likely define that closed==previe (with a setting to define if closed shows the summary or preview).

berdir’s picture

> And it should play well with the Content / Behavior tabs if present. They
should be on the same line.

That's easier said than those because those are just put in #prefix and are plain HTML.

That approach is not possible here as we have actual form elements.

I have the same problem in the reorder issue, where I started to add stuff to the template/preprocess to handle that. The problem is that field API assumes that all children are field item deltas except the add more button and that stuff is all pretty hardcoded.

So, not sure if we want to fix that here, but I know it looks very bad right now if we don't.

I think we need to create a design of how the header should look like with all the switches and buttons and thingies combined. And likely completely replace the default field ui template and introduce regions where we can put stuff and so on, including all our ugly prefix/suffix html markup.

miro_dietiker’s picture

  1. +++ b/css/paragraphs.widget.css
    @@ -122,3 +122,7 @@
    +  float: right;
    

    I think we should avoid floats wherever possible.

  2. +++ b/src/Plugin/Field/FieldWidget/ParagraphsWidget.php
    @@ -1246,6 +1261,30 @@ class ParagraphsWidget extends WidgetBase {
    +        $widget_state['paragraphs'][$delta]['show_warning'] = $button['#paragraphs_show_warning'];
    

    Not sure about this. Why pass down the show warning thing? However i realize i don't fully understand what the purpose of this is and it's undocumented. We should at least create a follow-up to document all these magic properties.

  3. +++ b/src/Plugin/Field/FieldWidget/ParagraphsWidget.php
    @@ -1246,6 +1261,30 @@ class ParagraphsWidget extends WidgetBase {
    +        $widget_state['paragraphs'][$delta]['_original_delta'] = 1;
    

    I doubt that you should overwrite the original delta ever.

toncic’s picture

Status: Needs work » Needs review
StatusFileSize
new52.37 KB
new0 bytes
new0 bytes

Fixed problem with saving, moved collapse all button into header.
Also fixed:

I think we should only display the button if we have multiple children. Otherwise it's a full duplicate.

Collapse all works fine with nested and also with multi fields.
Need to fix tests for Collapse all and add Expand all button.

toncic’s picture

Oops, something went wrong with previous patch and diff. :)

berdir’s picture

Status: Needs review » Needs work
  1. +++ b/src/Plugin/Field/FieldWidget/InlineParagraphsWidget.php
    @@ -853,6 +853,7 @@ class InlineParagraphsWidget extends WidgetBase {
           );
    +
         }
    

    unrelated.

  2. +++ b/src/Plugin/Field/FieldWidget/ParagraphsWidget.php
    @@ -1247,6 +1252,37 @@ class ParagraphsWidget extends WidgetBase {
       /**
    +   * Went through all paragraphs and change mode for each paragraph instance.
    +   *
    

    went.. is strange, describe what you *do*, not what you *did*.

  3. +++ b/src/Plugin/Field/FieldWidget/ParagraphsWidget.php
    @@ -1247,6 +1252,37 @@ class ParagraphsWidget extends WidgetBase {
    +    foreach ($widget_state['paragraphs'] as $delta => $value) {
    +      if (!empty($button['#paragraphs_show_warning']) &&
    +        $widget_state['paragraphs'][$delta]['mode'] != $button['#paragraphs_mode']) {
    +        $widget_state['paragraphs'][$delta]['mode'] = $button['#paragraphs_mode'];
    +        $widget_state['paragraphs'][$delta]['show_warning'] = $button['#paragraphs_show_warning'];
    +      }
    

    i'm not sure what the show warning has to do with this and the code is quite hard to read. it oesn't really hurt if we set the value again if it was the same.

  4. +++ b/src/Plugin/Field/FieldWidget/ParagraphsWidget.php
    @@ -1386,6 +1422,22 @@ class ParagraphsWidget extends WidgetBase {
    +
    +    if ($key_exists) {
    +      if (!$this->handlesMultipleValues()) {
    +        $values = array_filter($values, function ($value) {
    +          return is_array($value);
    +        });
    +        NestedArray::setValue($form_state_variables, $path, $values);
    

    I know the place you copied this from also didn't have comments but lets add some here.

  5. +++ b/src/Plugin/Field/FieldWidget/ParagraphsWidget.php
    @@ -1537,4 +1589,42 @@ class ParagraphsWidget extends WidgetBase {
    +  /**
    +   * Build collapse all button.
    +   *
    

    Builds

  6. +++ b/src/Plugin/Field/FieldWidget/ParagraphsWidget.php
    @@ -1537,4 +1589,42 @@ class ParagraphsWidget extends WidgetBase {
    +   *   Field widget state.
    +   * @param int $delta
    +   *   The order of this item in the array of sub-elements (0, 1, 2, etc.).
    

    why is the delta relevant here, this button only exists once and is not delta specific?

toncic’s picture

Issue summary: View changes
Status: Needs work » Needs review
StatusFileSize
new38.06 KB
new20.24 KB
new15.68 KB

Addressed #28.
Added "Edit all" button.
Fixed test for "Collapse all" and added for "Edit all".
Here is the new screenshot:

One more stuff here, do we want to show only one button "Collapse all/ Edit all" depend of current state of paragraphs on page or we want to make dropdown menu like we have for Collapse,Remove ... actions? If we want dropdown menu what will be default action?

miro_dietiker’s picture

It should be a dropbutton, not two buttons.

We could do it as simple as this:
If the first paragraph is open, make collapse the default action. It the first is closed, make edit the default.

Is this a temporary solution and you plan to move the button later? The new button should be on the line where the tabs are.

I try to search some nockup previously done. The goal should be that the tabs are next to the button, because the left area on that line will be extended with contextual / parent hierarchy information.. and then the line gets sticky while scrolling.

primsi’s picture

Status: Needs review » Needs work
  1. +++ b/css/paragraphs.widget.scss
    @@ -134,3 +134,7 @@
    +.paragraphs_header_action {
    

    Not sure, but it from what I see in the rest of the file, this should be - not _.

  2. +++ b/paragraphs.module
    @@ -243,3 +243,24 @@ function template_preprocess_paragraph(&$variables) {
    +  // Remove the reorder mode switcher from the form in the header.
    

    Is this comment a leftover?

  3. +++ b/src/Plugin/Field/FieldWidget/ParagraphsWidget.php
    @@ -845,6 +846,17 @@ class ParagraphsWidget extends WidgetBase {
    +        $elements['header_actions'] = [
    +          '#type' => 'container',
    +          '#prefix' => '<div class="paragraphs_header_action">',
    +          '#suffix' => '</div>',
    

    Doesn't the container already produce a div element? Maybe I am missing something, but do we still need another level via the prefix/suffix? Or you could just apply the class to the container? If it's because of the if check above, can we use something else for that check?

  4. +++ b/src/Plugin/Field/FieldWidget/ParagraphsWidget.php
    @@ -1247,6 +1259,33 @@ class ParagraphsWidget extends WidgetBase {
    +   * Goes through all paragraphs and change mode for each paragraph instance.
    

    I would suggest "Loops through all paragraphs and changes"...

  5. +++ b/src/Plugin/Field/FieldWidget/ParagraphsWidget.php
    @@ -1247,6 +1259,33 @@ class ParagraphsWidget extends WidgetBase {
    +  public static function paragraphsMultipleSubmit(array $form, FormStateInterface $form_state) {
    

    Should we change the name of this submit method to something related to the logic it does?

  6. +++ b/src/Plugin/Field/FieldWidget/ParagraphsWidget.php
    @@ -1537,4 +1578,100 @@ class ParagraphsWidget extends WidgetBase {
    +  /**
    +   * Builds collapse all button.
    ...
    +   * @return array
    +   *   The form element array.
    

    We introduce two new properties in this array, which are not required by the type submit. Maybe it should be a good idea just to mention a bit why we need them and where we use them.

  7. +++ b/src/Plugin/Field/FieldWidget/ParagraphsWidget.php
    @@ -1537,4 +1578,100 @@ class ParagraphsWidget extends WidgetBase {
    +      '#paragraphs_mode' => 'edit',
    

    Same as above, document a bit?

toncic’s picture

Issue summary: View changes
Status: Needs work » Needs review
StatusFileSize
new76.6 KB
new20.25 KB
new13.32 KB

Implemented #31.

It should be a dropbutton, not two buttons.

Fixed.

If the first paragraph is open, make collapse the default action. It the first is closed, make edit the default.

Fixed.

New version:

Need to fix test failing.

berdir’s picture

Status: Needs review » Needs work
  1. +++ b/src/Plugin/Field/FieldWidget/ParagraphsWidget.php
    @@ -845,6 +846,19 @@ class ParagraphsWidget extends WidgetBase {
    +        $elements['header_actions']['collapse_all'] = $this->buildCollapseAllButton($field_state);
    +        $elements['header_actions']['edit_all'] = $this->buildEditAllButton($field_state);
    +
    +        // Set default action.
    +        if ($field_state['paragraphs'][0]['mode'] === 'closed') {
    +          $elements['header_actions']['edit_all']['#weight'] = -10;
    +        }
    

    can't we combine those two methods into one, including the logic to define the default. We have a huge amount of methods already on this class and very long main form methods.

    We could even move all of it, including the dropbutton building into that method and call it buildHeaderActions(). Once this is committed, I will refactor my reorder patch to add another button here.

  2. +++ b/src/Plugin/Field/FieldWidget/ParagraphsWidget.php
    @@ -1266,6 +1280,34 @@ class ParagraphsWidget extends WidgetBase {
    +  public static function changeParagraphsMode(array $form, FormStateInterface $form_state) {
    

    lets include submit in the method name so it is clear that it is a submit callback. And we call it edit mode usually, not paragraphs mode. changeAllEditModeSubmit() ?

  3. +++ b/src/Plugin/Field/FieldWidget/ParagraphsWidget.php
    @@ -1406,6 +1448,8 @@ class ParagraphsWidget extends WidgetBase {
    +    $this->removeNonRelatedButtons($form, $form_state);
    

    I was thinking about method name and so on for this, but I would actually prefer to keep this inline. This is a small method, we will never need that logic anywhere else. keep it inlined.

  4. +++ b/src/Plugin/Field/FieldWidget/ParagraphsWidget.php
    @@ -1557,4 +1601,88 @@ class ParagraphsWidget extends WidgetBase {
    +      if (!$this->handlesMultipleValues()) {
    +        if (in_array('header_actions', array_keys($values))) {
    +          unset($values['header_actions']);
    +        }
    +
    +        NestedArray::setValue($form_state_variables, $path, $values);
    +        $form_state->setValues($form_state_variables);
    +      }
    +    }
    

    this is our widget, so we know it is always multiple and can skip that if.

    either we just unconditinally call unset() ( it doesn't care if the key doens't exist) or we move the set calls below also inside the if, as we don't need them unless we actually remove it.

steniya’s picture

Issue summary: View changes
toncic’s picture

Status: Needs work » Needs review
StatusFileSize
new19.05 KB
new15.19 KB

Implemented #33, refactoring, fixing test failing.

berdir’s picture

Status: Needs review » Needs work
+++ b/src/Plugin/Field/FieldWidget/ParagraphsWidget.php
@@ -847,18 +847,10 @@ class ParagraphsWidget extends WidgetBase {
+      if (!empty($this->buildHeaderActions($field_state))) {
+        $elements['header_actions'] = $this->buildHeaderActions($field_state);
       }

Now you're doing the logic here twice. try $header_actions = $this->buildHeaderActions(); if ($header_actions) { ... set it }

lets merge the two test together into one class.

miro_dietiker’s picture

Title: Add a close / edit all button » Add a collapse / edit all button
toncic’s picture

Status: Needs work » Needs review
StatusFileSize
new14.74 KB
new9.59 KB

Addressed #36.

miro_dietiker’s picture

Status: Needs review » Needs work

This needs a re-roll now.

didebru’s picture

StatusFileSize
new14.05 KB

I have rerolled the patch but it does not seem to work properly.

toncic’s picture

StatusFileSize
new14.75 KB
new805 bytes

Fixing test failing from #38.

@Insasse, just tested this and for me works pretty fine, can you give as more information about what is not working properly in your case?

toncic’s picture

Status: Needs work » Needs review
didebru’s picture

StatusFileSize
new101.78 KB

@tonic works pretty well thanks :) had tested it on an old ~8.0 setup my fault sry.

miro_dietiker’s picture

Status: Needs review » Needs work

@Insasse it seems you are not using the experimental widget.

Works pretty well for me.
But if i "collapse all" children, they do not indicate anymore if they have been changed.

That said, i realize that if we collapse a parent container that contains changed children, we should bubble up the changed annotation - but only for collapsed ones. Otherwise it looks like nothing changed. I guess should be a follow-up, more related to the other changed issue..
#2886686: Collapsable paragraphs always show "You have unsaved changes on this Paragraph item." message on collapsing..

toncic’s picture

Status: Needs work » Needs review
Related issues: +#2895565: Add warning message on collapsed container if changed child

Created follow-up.

miro_dietiker’s picture

Status: Needs review » Needs work

Renamed the follow-up. IMHO the original issue should make sure that the regular changed messages display after a collapse-all. No regressions.

toncic’s picture

Status: Needs work » Needs review
StatusFileSize
new14.95 KB
new1.04 KB

Added warning message on collapse all button.

As @miro_dietiker mentioned in #44

"collapse all" children, they do not indicate anymore if they have been changed.

.

So it's working fine if you change top level container, but not when you change the children.

After discussion with @Berdir:
That part we will do in follow-up.

miro_dietiker’s picture

Status: Needs review » Needs work

Warnings now work for me.

Nitpick: The button labels are centered now. The other drop buttons are left aligned. Plz check style.

+++ b/paragraphs.module
@@ -271,3 +271,24 @@ function template_preprocess_paragraphs_add_dialog(&$variables) {
+function paragraphs_preprocess_field_multiple_value_form(&$variables) {
...
+            'title' => $variables['table']['#header'][0]['data'],
+            'button' => $variables['table']['#rows'][$i]['data'][1],
...
+          unset($variables['table']['#rows'][$i]);

I'm confused, we remove the whole row here. Where do we put that helper row?
There is no more simple way to bring in those buttons than via a pseudo row?

Other than that, it looks ready to commit. Also tested no-js behavior.

miro_dietiker’s picture

Committed.

Plz create a follow-up about using a field template and care about the alignment as proposed in #48 and close.

  • miro_dietiker committed 660a663 on 8.x-1.x authored by toncic
    Issue #2738645 by toncic, yongt9412, Insasse, miro_dietiker, Berdir: Add...
toncic’s picture

Added follow-up.

Status: Fixed » Closed (fixed)

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