Problem/Motivation

We use entity browser to select a single media using a view as widget plugin. By default this select plugin renders a checkbox in the views html output,
which allows it to accept multiple entries at once.

Proposed resolution

Add a setting to the views plugin to allow just a single selection.
In an ideal world this would be propagated from the original field widget down to the entity browser display plugin to the views plugin, but that seems to be out of range now. Therefore we went with an additional setting in views.

Remaining tasks

User interface changes

API changes

Data model changes

CommentFileSizeAuthor
#123 2845941--interdiff-122-123.txt14.8 KBoknate
#123 entity-browser-single-selection-2845941-123.patch38.65 KBoknate
#122 entity-browser-single-selection-2845941-122.patch42.13 KBoknate
#122 2845941--interdiff-121-122.txt970 bytesoknate
#121 2845941--interdiff-118-121.txt4.81 KBoknate
#121 entity-browser-single-selection-2845941-121.patch42.12 KBoknate
#119 entity-browser-single-selection-2845941-118.patch38.07 KBoknate
#119 2845941--interdiff-117-118.txt902 bytesoknate
#117 2845941--interdiff-115-117.txt18.94 KBoknate
#117 entity-browser-single-selection-2845941-117.patch38.07 KBoknate
#115 entity-browser-single-selection-2845941-115.patch29.45 KBoknate
#112 entity-browser-single-selection-2845941-112.patch27.68 KBoknate
#111 interdiff--108-111.txt624 bytesytsurk
#111 entity-browser-single-selection-2845941-111.patch27.68 KBytsurk
#108 entity-browser-single-selection-2845941-108.patch27.54 KBoknate
#108 2845941-interdiff--106-108.txt1.48 KBoknate
#106 entity-browser-single-selection-2845941-106.patch27.25 KBoknate
#105 entity-browser-single-selection-2845941-105.patch27.22 KBoknate
#101 2845941-interdiff--87-101.txt20.25 KBoknate
#101 2845941-interdiff--100-101.txt458 bytesoknate
#101 entity-browser-single-selection-2845941-101.patch27.88 KBoknate
#100 2845941-interdiff--87-100.txt20.7 KBoknate
#100 2845941-interdiff--97-100.txt20.83 KBoknate
#100 entity-browser-single-selection-2845941-100.patch28.33 KBoknate
#97 interdiff-2845941-92-97.txt804 bytesjohnchque
#97 entity-browser-single-selection-2845941-97.patch23.61 KBjohnchque
#94 entity-browser-single-selection-2845941-92.patch23.33 KBoknate
#94 2845941-interdiff--90-92.txt1.04 KBoknate
#90 entity-browser-single-selection-2845941-90.patch22.29 KBoknate
#90 2845941-interdiff--88-90.txt9 KBoknate
#88 2845941--interdiff-87-88.txt21.53 KBoknate
#88 entity_browser-single-selection-2845941-88.patch18.11 KBoknate
#87 entity_browser-single-selection-2845941-87.patch23.55 KBoknate
#111 entity_browser-single-selection-2845941-86--2.patch23.69 KBytsurk
#86 entity_browser-single-selection-2845941-86.patch23.55 KBoknate
#73 entity_browser-single-selection-2845941-72.patch6.96 KBPrimsi
#73 entity_browser-single-selection-2845941-68.interdiff.txt706 bytesPrimsi
#68 entity_browser-single-selection-2845941-68.patch6.97 KBPrimsi
#59 entity_browser-single-selection-2845941-59.patch5.26 KBoknate
#57 entity_browser-single-selection-2845941-58.patch2.73 KBPrimsi
#48 entity_browser-single-selection-2845941-48.patch18.36 KBoknate
#43 entity_browser-single-selection-2845941-39-10.patch18 KBPrimsi
#43 entity_browser-single-selection-2845941-39-09.patch18 KBPrimsi
#43 entity_browser-single-selection-2845941-39-08.patch18 KBPrimsi
#43 entity_browser-single-selection-2845941-39-07.patch18 KBPrimsi
#43 entity_browser-single-selection-2845941-39-06.patch18 KBPrimsi
#43 entity_browser-single-selection-2845941-39-05.patch18 KBPrimsi
#43 entity_browser-single-selection-2845941-39-04.patch18 KBPrimsi
#43 entity_browser-single-selection-2845941-39-03.patch18 KBPrimsi
#43 entity_browser-single-selection-2845941-39-02.patch18 KBPrimsi
#43 entity_browser-single-selection-2845941-39-01.patch18 KBPrimsi
#39 interdiff-35-39.txt1.04 KBoknate
#39 entity_browser-single-selection-2845941-39.patch18 KBoknate
#37 interdiff-32-37.txt3.03 KBoknate
#37 entity_browser-single-selection-2845941-37.patch17.79 KBoknate
#35 entity_browser-single-selection-2845941-35.patch39.82 KBPrimsi
#35 interdiff-entity_browser-single-selection-2845941-35.patch.txt3.48 KBPrimsi
#32 entity_browser-single-selection-2845941-32.patch18.04 KBPrimsi
#30 entity_browser-single-selection-2845941-30.patch42.82 KBPrimsi
#30 interdiff-entity_browser-single-selection-2845941-30.patch.txt11.9 KBPrimsi
#28 entity_browser-single-selection-2845941-28.patch12.67 KBPrimsi
#28 interdiff-entity_browser-single-selection-2845941-28.patch.txt1.01 KBPrimsi
#26 entity_browser-single-selection-2845941-26.patch12.73 KBPrimsi
#26 interdiff-entity_browser-single-selection-2845941-26.patch.txt4.41 KBPrimsi
#22 interdiff-2845941-20-22.txt2.81 KBjohnchque
#22 entity_browser-single-selection-2845941-22.patch7.83 KBjohnchque
#20 interdiff-2845941-17-20.txt3.38 KBjohnchque
#20 entity_browser-single-selection-2845941-20.patch7.64 KBjohnchque
#18 interdiff-2845941-9-17.txt611 bytesjohnchque
#18 entity_browser-single-selection-2845941-17.patch4.68 KBjohnchque
#13 Screenshot from 2018-11-19 17-04-16.png26.43 KBjohnchque
#9 entity_browser-single-selection-2845941-9.patch4.58 KBataimist
#8 2845941-8.patch4.15 KBfenstrat
#6 interdiff-2845941.txt582 bytesdawehner
#6 2845941-6.patch4.14 KBdawehner
#3 2845941-2--ignore.patch3.22 KBdawehner
#2 2845941-2.patch4.22 KBdawehner
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

dawehner created an issue. See original summary.

dawehner’s picture

FileSize
4.22 KB
dawehner’s picture

FileSize
3.22 KB

This is just a patch against the latest

dawehner’s picture

slashrsm’s picture

Status: Needs review » Needs work
Issue tags: +D8Media, +Needs tests
  1. +++ b/src/Element/EntityBrowserElement.php
    @@ -164,6 +164,7 @@ function (EntityInterface $item) {
    +      '#cardinality' => isset($element['##cardinality']) ? $element['##cardinality'] : NULL,
    

    This looks like an unrelated change? Element is passing the constraint validator if #cardinality is set. That value eventually ends up in the Entity browser's form state. We could access it there. See EntityBrowserForm::init().

  2. +++ b/src/Plugin/EntityBrowser/Widget/View.php
    @@ -204,7 +204,13 @@ public function validate(array &$form, FormStateInterface $form_state) {
    +    if (is_array($form_state->getUserInput()['entity_browser_select'])) {
    +      $selected_rows = array_values(array_filter($form_state->getUserInput()['entity_browser_select']));
    +    }
    +    else {
    +      $selected_rows = [$form_state->getUserInput()['entity_browser_select']];
    +    }
    

    A comment would be nice here.

  3. It would be great to add some test coverage for this feature. We're currently in the feature freeze phase, but we will start committing new features after we've released 8.x-1.0 assuming there is test coverage for them.
dawehner’s picture

FileSize
4.14 KB
582 bytes

Here is a bug fix, I really don't know anymore why this line is in there and why I spent an entire weekend debugging that.

acbramley’s picture

This doesn't seem to fix the issue of being able to select multiple entities using a view. After applying the patch I can still select multiple entities in a single cardinality field and get the "You can not select more than 1 entity." error.

However, the patch does seem to fix the issue where after the error occurred you were unable to select a single entity without reloading the page (or removing the field value and re-adding it).

fenstrat’s picture

FileSize
4.15 KB

Straight reroll of #6 as it no longer applied.

ataimist’s picture

Here's a small fix to the previous patches (#8 and #6) to get rid of the fatal error you get from list() in entity_browser\Plugin\EntityBrowser\Widget\View::prepareEntities if submitting the selection form without having selected anything.

Regarding the problem with multiple selection still being possible as described in #7, this might be a problem in the view that's used for the selection; check out https://www.drupal.org/project/media_entity_browser/issues/2924508 for a patch for Media Entity Browser that makes it correctly handle the radio buttons created by this patch.

jasonawant’s picture

miro_dietiker’s picture

Been pointed here as we have such a use case in multiple locations, also in the Paragraphs Library module (part of Paragraphs).

It took me a while to realize that the UI is basically just switching the checkbox to a radio element...
As this contains a UI proposal, a screenshot would help.

acbramley’s picture

This is breaking entity browsers after upgrading to core 8.5. I am now unable to perform pagination or filtering on an entity browser field widget. I get a notice logged:

Notice: Undefined index: #value in Drupal\Core\Render\Element\Radio::preRenderRadio()

And after spinning for a while, the ajax request will error out.

johnchque’s picture

This is how it looks now:

We also want to add logic for avoiding having more than one radio selected right, in this issue right?

Berdir’s picture

> We also want to add logic for avoiding having more than one radio selected right, in this issue right?

If that is still possible then that defeats the purpose of this issue yes.

The way to achieve this would be to making sure that the name attribute of each radio element is identical and just the value differs. That's how radio buttons are meant to be used. But from reading the code, I would kind of assume that's the case already?

Currently, this seems to be adding an explicit configuration setting.

AFAIK, the entity browser widget also forwards certain settings to the browser, so we might be able to read from that whether or not we should use radios or checkboxes. That said, just switching automatically might then also break existing integrations/customations like the file_browser module. But I know for a fact that we have cases where we use the same browser for single-cardinality and multiple-cardinality fields. Maybe a setting to opting in to radios *if* it's a single cardinality field?

miro_dietiker’s picture

That's strange.
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/radio

Multiple radio inputs with the same name property will share a common single selection.
We should not replicate this type of functionality with JS or so. We should really put the right name key to share the selection.
Maybe each radio has a different property currently?

johnchque’s picture

Yes, they should share the same name and have different value. That's not the case yet. In the previous image I posted, each radio has the a different name, with the like: entity_browser_select[paragraphs_library_item:3].

Berdir’s picture

+++ b/src/Plugin/views/field/SelectForm.php
@@ -74,6 +101,11 @@ class SelectForm extends FieldPluginBase {
+          $render[$this->options['id']][$value]['#parents'] = ['entity_browser_select'];

then I think this line isn't yet doing what it should.

Looking at \Drupal\Core\Render\Element\Radios::processRadios(), it uses the same approach of setting the parents.

However, I can see a few lines above that it explicitly sets the name attribute through #attributes. That's going to be the problem then we need to override that as well and set it to the same value then.

johnchque’s picture

Status: Needs work » Needs review
FileSize
4.68 KB
611 bytes

Hm Took me a bit more to realize that the name was set like this. Updating names, seems the functionality is not affected. Let's see how many tests it breaks.

BTW, do we want this for 8.x-2.x too?

Berdir’s picture

> BTW, do we want this for 8.x-2.x too?

Yes, we are using 8.x-2.x.

johnchque’s picture

Adding tests. Took me longer than expected. :)

Schema was missing, let see if this works.

johnchque’s picture

Discussed this with @Berdir, it makes sense to enable the radio just when the cardinality of the field is 1. We have the validation, we just need to pass its value to the plugin for the field so we can check that too.

johnchque’s picture

OK, so as stated, show radio only when the cardinality is 1. :)

Primsi’s picture

Status: Needs review » Needs work
+++ b/src/Plugin/views/field/SelectForm.php
@@ -15,6 +16,31 @@ use Drupal\views\Render\ViewsRenderPipelineMarkup;
+    $form['multiple'] = [

I am not sure about this. EB already has too much of "you need to configure it in two places". But it's true, we need to deal with existing instances. What if we change that to something like "Use field cardinality" or something along those lines?

Apart from that IMHO looks quite ok and it's a nice improvement.

Primsi’s picture

Although now that I think of it this complicates it a bit when cardinality is not 1 or unlimited.

miro_dietiker’s picture

I'd be super happy to see things just configured in one place, but rearchitecting that should be targeted in a different task... And chances are it will break many current configurations, so we either need a new branch or a fancy setting migration...

Primsi’s picture

Not sure if a major refactoring is needed. I was thinking of something like the attached patch. We set the default to "use the field cardinality" and add logic to check for that and cardinality.

That said, I only tested this briefly + needs test coverage update.

Status: Needs review » Needs work

The last submitted patch, 26: entity_browser-single-selection-2845941-26.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

Primsi’s picture

Looking int tests.

Status: Needs review » Needs work

The last submitted patch, 28: entity_browser-single-selection-2845941-28.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

Primsi’s picture

Status: Needs review » Needs work

The last submitted patch, 30: entity_browser-single-selection-2845941-30.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

Primsi’s picture

Status: Needs work » Needs review
FileSize
18.04 KB

Something went wrong there while creating the patch.

Status: Needs review » Needs work

The last submitted patch, 32: entity_browser-single-selection-2845941-32.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

oknate’s picture

Reviewing #32

1) On Entity browser bulk select form, "checboxes" is misspelled, it should be "checkboxes". Also I think the language is developer-centric and should be rewritten.

I would suggest for the label "Use radios, if applicable" and for the description "Use radios if field allows only a single selection.".

2) This text should be updated (but isn't): "Ensure to use input (checkbox) field from entity browser, column dedicated for selection checkbox."

3) This should use format plural to handle the case when cardinality is 1:

+      if ($use_field_cardinality && $cardinality > 0) {
+        if (count($selected_rows) > $cardinality) {
+          $form_state->setError($form['widget']['view']['entity_browser_select'], $this->t('You can only select up to @number items.', ['@number' => $cardinality]));
+        }
+      }

If cardinality is 1, the error should read "You can only select 1 item.".

Other than that, it seems to work well.

Primsi’s picture

Addressed feedback.

Status: Needs review » Needs work

The last submitted patch, 35: entity_browser-single-selection-2845941-35.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

oknate’s picture

Thanks for the update @Prismi. It looks like #35 had some extraneous changes (moving from 8.x-1.x branch to 8.x-2.x branch), so it wouldn't apply on the 8.x-2.x branch. Rerolling.

oknate’s picture

Testing #37 (reroll of #35) on 8.x-2.x branch.

I'm testing with an entity embed button. If I select an entity, then go back and re-open the browser I get this:

Warning: array_filter() expects parameter 1 to be array, string given in Drupal\entity_browser\Plugin\EntityBrowser\Widget\View->validate() (line 184 of modules/contrib/entity_browser/src/Plugin/EntityBrowser/Widget/View.php).
Drupal\entity_browser\Plugin\EntityBrowser\Widget\View->validate(Array, Object) (Line: 207)
oknate’s picture

adding fix for comment #38, and rerolling as my last reroll was missing /config/schema/entity_browser.views.schema.yml.

Two of the fails on this patch on Drupal 8.7 can be explained by
- #3020449: ImageFieldTest::testImageFieldSettings fails on Drupal 8.7
- #3020353: Test needs update due to change in Drupal 8.7

oknate’s picture

Status: Needs work » Needs review
Issue tags: -Needs tests

The last submitted patch, 6: 2845941-6.patch, failed testing. View results

Primsi’s picture

Version: 8.x-1.x-dev » 8.x-2.x-dev

This are some strange fails. Following @Berdir suggestion to test if this is are random fails: upload the patch multiple times. Also changing the version.

The last submitted patch, 43: entity_browser-single-selection-2845941-39-03.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

The last submitted patch, 43: entity_browser-single-selection-2845941-39-04.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

The last submitted patch, 43: entity_browser-single-selection-2845941-39-02.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

oknate’s picture

I'm testing out and patch 39 is missing the interdiff changes, so I'm still getting the error:

Warning: array_filter() expects parameter 1 to be array, string given in Drupal\entity_browser\Plugin\EntityBrowser\Widget\View->validate() (line 184 of modules/contrib/entity_browser/src/Plugin/EntityBrowser/Widget/View.php).
Drupal\entity_browser\Plugin\EntityBrowser\Widget\View->validate(Array, Object) (Line: 207)

Needs a reroll.

oknate’s picture

Reroll to restore changes in interdiff-35-39.txt.

oknate’s picture

Status: Needs review » Reviewed & tested by the community

Marking #48 RTBC. Patch #48 was largely #35 with one change. I'm testing locally and I don't see any issues so far. Since I'm marking my reroll as RTBC, it would be good to get some other people to review as well.

johnchque’s picture

Status: Reviewed & tested by the community » Needs work

If the code added in #48 is needed to avoid that error, we need test coverage. In #43 we had passing tests which means that that error is not being covered.

oknate’s picture

The error mentioned in #38 wasn't happening in head (before the patch is applied) and isn't happening with patch #48. I don't think we need test coverage for a bug in patch #37 when it's been corrected in a later patch.

Primsi’s picture

IMHO it's not strictly needed, but it would be nice to have the error covered now that we know it might happen.

  • Primsi committed d65396b on 8.x-2.x
    Issue #2845941 by Primsi, yongt9412, oknate, dawehner, ataimist,...
Primsi’s picture

Status: Needs work » Fixed

Or we can add it later when/if something breaks. Thanks for the work :)

oknate’s picture

This should be added to the 8.x-1.x branch too. It applies there too, and it would be nice to keep them in sync.

  • Primsi committed c7c8808 on 8.x-1.x
    Issue #2845941 by Primsi, yongt9412, oknate, dawehner, ataimist,...
Primsi’s picture

Status: Fixed » Needs review
FileSize
2.73 KB

$view->cardinality doesn't persist of course :) Which results in radios being checkboxes again if you run a filter on the view for example.

Setting cardinality as a view argument is the only idea I have currently on how to fix that (and I am not quite sure if there are cases when we would i.e. set the wrong arguments by doing that). Any other options?

oknate’s picture

#57 fixes the issue, nice work there, Primsi, but I think we should look for a different solution without touching the views arguments, if possible. What if someone has a hook that changes the views arguments and they remove that last argument?

oknate’s picture

We could use private.tempstore, this works and leaves the views arguments untouched.

Primsi’s picture

Assigned: Unassigned » Primsi

Had a quick discussion with @Berdir about that. While using private.tempstore is a better way to solve that, we would still have a problem in the case of a user accessing the same browser via multiple tabs for example. We discussed an alternative solution though. Will be working on that.

netw3rker’s picture

I'm pretty sure the whitespace change in the first block of the patch in #57 doesn't conform to drupal coding standards. I'm not being pedantic though, the only reason I caught this is that it causes an unnecessary conflict with another issue I'm following: #2832240: Configure path arguments for View widget via UI

oknate’s picture

Good catch @netw3rker. I would recommend using 59 for now, as it also fixes the paging issue.

nmitev’s picture

When using the entity browser view display on a field with single value the green checkmark is displayed on all selected items https://prnt.sc/m41gv8 (no as expected), but only saves the last selected value (works as expected). Is there a possibility to look into this one?

From what i found in #48 was added the option to select the radio button, but no additional logic was added for handling the radio button checked class add/remove in order the green checkmark to be removed.

Primsi’s picture

@nmitev This is with Media entity browser I would assume? The markup changed, so I guess the js/css part there would have to be updated.

oknate’s picture

Thanks for pointing this issue out, @nmitev.

Here's an issue on the media_entity_browser queue for the incompatibility:

#3024311: Fix incompatibility with single selection views in entity_browser

netw3rker’s picture

@oknate, My impression from the comment in #60 is that #59 is not going to be the ultimate route for this, and it sounds like 57 is more in-line with what the final approach will look like. Am I reading that right?

oknate’s picture

I don't think the final approach has been determined, Primsi is working on it. #57 adjusts the views arguments, which I don't like, which is why I created #59. If #57 works for you, you can use that. Primsi is working on a new approach. I don't know if that would be close to #57 or not.

Primsi’s picture

This will fail now. To make it work we need #2823541: Table clicksort is lost when using views exposed filter.

Using that patch, we then can pass the cardinality information to the view that is executed in the ViewAjaxController. Given that our display is always assumed to use ajax, this should be fine.

Primsi’s picture

Assigned: Primsi » Unassigned
Primsi’s picture

Oh, it needs tests to test that :)

oknate’s picture

Thanks for the update, Primsi. Can you point me to where I can read about "instance_overrides_key"

I don't understand this part:

+        $element['#pager']['#parameters']['instance_overrides_key'] = $cardinality;

I don't see that anywhere in the current codebase (8.6.4).

Oh, I see it's a patch for #2823541: Table clicksort is lost when using views exposed filter.

Was this the patch you're using? https://www.drupal.org/files/issues/2018-05-31/2605218-19-this-fix-only-...

Berdir’s picture

That should probably be cardinality there as well, not instance_overrides_key.

Primsi’s picture

That part was from an internal display we have and it's not relevant here. Thx for catching that.

Probably the test in the patch you posted comes from the same use case. But the the one that is needed to make this work is the one I mentioned already ([#2823541).

oknate’s picture

Is this the one you're using from that issue? https://www.drupal.org/files/issues/2018-10-03/2823541-38.patch

Primsi’s picture

nmitev’s picture

There are some notices in latest version #73 - https://prnt.sc/m4yxc8 , when open media browser for first time without any filters applied.
Not relevant.

oknate’s picture

Issue tags: +Needs tests

I manually tested #73 (with core patch https://www.drupal.org/files/issues/2018-05-21/2823541-34.patch) manually within a modal entity browser and it fixed the persistence of the radios when paging.

So far so good.

We should have a functional test to prove that paging within the entity browser doesn't switch back to checkboxes when cardinality is set to 1.

nmitev’s picture

It works fine on first load it displays radio button on all items of the page, but when you go on other page the radio button is switched to checkbox again and on every page switch it is displayed with check boxes instead of radio buttons.

Berdir’s picture

Yes, that's what we are trying to fix and if you combine the latest patch with the referenced core issue then that should fix that problem.

johnchque’s picture

I tested this manually, it seems to keep the radios fine now.

@nmitev could you describe your problem more? I didn't find problems so far with the last patch.

We still need tests.

Primsi’s picture

Seems like this is causing some problems in #3026890: Update to Entity Browser 8.x-2.x in tests. An idea was to revert this until that core patch is in. Any objections to that?

oknate’s picture

I don't mind. If you revert it, it would be nice to have a single patch here that will add back what was reverted as well as the update in #73?

  • Primsi committed 658b604 on 8.x-2.x
    Revert Issue #2845941
    
    This reverts commit...

  • Primsi committed f68edc6 on 8.x-1.x
    Revert Issue #2845941.
    
    This reverts commit...
Primsi’s picture

Status: Needs review » Needs work

So we need a combined patch now.

oknate’s picture

Here's a patch that combines the commit reverted with #73. Please note it, it requires the core patch mentioned in #75.

oknate’s picture

Reroll of 86 against HEAD of dev branch.

oknate’s picture

Status: Needs work » Needs review
FileSize
18.11 KB
21.53 KB

Here's a patch that takes advantage of the persistent data (#widget_context) to store the cardinality.

As the original post wished for no config option to trigger this, I drop the use_field_cardinality option. (Update, see below, I add this to new config entity_browser.settings.)

"In an ideal world this would be propagated from the original field widget down to the entity browser display plugin to the views plugin . . . "

I tested manually with the field widget, entity embed and and inline entity form and it seems to work fine, and be persistent despite exposed filters. It reduces the amount of code changes needed.

Also, this isn't dependent on a core patch to work, if I haven't missed any bugs.

Still to do:

  • Review
  • Update the automated testing of the feature.
oknate’s picture

Hmm, I see in #23, the reason to add a config is to not break BC. Which is sad to me, because it's kind of a bug that you can select more than one if the cardinality is one on a field. Do really have to have an option to turn on this feature? I guess so, if it would break tests on the Paragraph module, for example.

I think going forward if we need to suppress things for BC purposes, a settings form for entity browser would work. There could be a checkbox "Enable radios in view widget when cardinality is 1". The use_field_cardinality could be moved there globally. Since this works with widget context and should work with entity embed, I think we should remove "field" part of parameter name.

oknate’s picture

Adding entity_browser.settings config form and adding parameter so this feature is disabled by default, to prevent breaking BC with other modules tests', such as paragraphs, see (#3026890: Update to Entity Browser 8.x-2.x in tests).

Status: Needs review » Needs work

The last submitted patch, 90: entity-browser-single-selection-2845941-90.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

oknate’s picture

Status: Needs work » Needs review

Re-queuing test on #90. The test in question passed. Other failures were random, I believe.

Status: Needs review » Needs work

The last submitted patch, 90: entity-browser-single-selection-2845941-90.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

oknate’s picture

Adding more wait time to try to fix this intermittently failing test. Has been an issue a lot of the last month.

oknate’s picture

Status: Needs work » Needs review
Berdir’s picture

In regards to BC, I think it is necessary for this to be per view.

For example, many entity browser customizations use hidden checkboxes, grids and so on to to improve the UI. I'm pretty sure many of these would break if we would automatically switch the type to a radio instead of a checkbox.

It's also a problem for automated tests. Paragraphs tests for example were broken after when we had this committed for a while

This is only partially addressed I think as new views default to having that enabled, so not sure about that.

johnchque’s picture

Thanks for the patches. Not sure either which path to take. BUT I saw that this might be a problem as I saw that webform had a similar problem.
Not sure how to reproduce but if the value is NULL it fails when rendering as it tries to convert NULL to string.

Status: Needs review » Needs work

The last submitted patch, 97: entity-browser-single-selection-2845941-97.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

oknate’s picture

In #97, I'm no sure where a NULL value would come from, the $value is the entity type and the entity id, 'media:6866' etc. I don't think this is necessary:

+          $render[$this->options['id']][$value]['#value'] = ($value === NULL) ? FALSE : (string) $value;

It would never be NULL. In what condition were you seeing this NULL? Do you have steps to recreate so I can test?

oknate’s picture

Per Berdir's comment in #97, restoring the per view config use_field_cardinality.

I'm adding two interdiff's so you can compare with the last patch as well as before my latest refactor to use widget_context. I think comparing with 87 is more helpful, perhaps.

Also I tested with /paragraphs/modules/paragraphs_library/tests/src/FunctionalJavascript/ParagraphsContentModerationTest.php

It works now due to this change:

diff --git a/src/Plugin/views/field/SelectForm.php b/src/Plugin/views/field/SelectForm.php

@@ -61,7 +74,7 @@ class SelectForm extends FieldPluginBase {
   protected function defineOptions() {
     $options = parent::defineOptions();
     $options['use_field_cardinality'] = [
-      'default' => TRUE,
+      'default' => FALSE,
     ];

Setting the default to use cardinality was breaking that test in paragraphs.

I'm also breaking out one method into a trait, EntityBrowserWidgetContextTrait, because I found myself using it a lot in another issue.

oknate’s picture

I see I have one thing left over in #100 from #94, updating.

The last submitted patch, 100: entity-browser-single-selection-2845941-100.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

Status: Needs review » Needs work

The last submitted patch, 101: entity-browser-single-selection-2845941-101.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

oknate’s picture

Status: Needs work » Needs review

Setting back to needs review, more random failures.

oknate’s picture

Reroll, also fixing whitespace in two places

oknate’s picture

Reroll against latest dev (commit hash ba3e64c4487df07d272677ebb7eab1a886e567f4)

Status: Needs review » Needs work

The last submitted patch, 106: entity-browser-single-selection-2845941-106.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

oknate’s picture

Status: Needs work » Needs review
Issue tags: -Needs tests
FileSize
1.48 KB
27.54 KB

Fixing test, node title needed to change due to adding in test coverage of edit button that changed node title.

m-si’s picture

Checked last patch of #108 against 8.2.x-dev, Drupal 8.6.14 and can confirm it worked for me. Best regards.

kellyimagined’s picture

Status: Needs review » Reviewed & tested by the community

This has been RTBC great solution added in #108

ytsurk’s picture

We still get the php notice

Notice: Undefined index: #value in Drupal\Core\Render\Element\Radio::preRenderRadio() (line 68 of /.../web/core/lib/Drupal/Core/Render/Element/Radio.php)

when filtering a SelectForm using views exposed filters.

Giving the radio form element an initial value makes this notice disappear.

So here the updated 108 patch and an older patch (86--2) applying to 8.x.-2.1.

oknate’s picture

hctom’s picture

Just for the record: After revert of changes made for #2851580: Re-order + remove broken with the Entity Reference (and File) widget due to its buggy behavior, the last applying patch against the current dev state is the one from #105. Therefore I make it visible again in the head of the issue.

oknate’s picture

Status: Reviewed & tested by the community » Needs work

Needs reroll.

oknate’s picture

Status: Needs work » Needs review
FileSize
29.45 KB

Here's a reroll, plus moving the cardinality test to a separate file for now, to prevent merge conflicts. It can be moved back into /tests/src/FunctionalJavascript/EntityReferenceWidgetTest.php later.

I added some helper functions to make the test easier to read:

+
+  /**
+   * Checks that a specific radio input element exists on the current page.
+   *
+   * @param string $value
+   *   The string value of the radio element.
+   *
+   * @return \Behat\Mink\Element\NodeElement
+   *   The radio input form element.
+   *
+   * @throws \Behat\Mink\Exception\ElementNotFoundException
+   */
+  protected function assertRadioExistsByValue($value) {
+    $value = (string) $value;
+    return $this->assertSession()
+      ->elementExists('xpath', "//input[contains(@type, 'radio') and contains(@value, '" . $value . "')]");
+  }
+
+  /**
+   * Checks that a specific checkbox input element exists on the current page.
+   *
+   * @param string $value
+   *   The string value of the radio element.
+   *
+   * @return \Behat\Mink\Element\NodeElement
+   *   The radio input form element.
+   *
+   * @throws \Behat\Mink\Exception\ElementNotFoundException
+   */
+  protected function assertCheckboxExistsByValue($value) {
+    $value = (string) $value;
+    return $this->assertSession()
+      ->elementExists('xpath', "//input[contains(@type, 'checkbox') and contains(@value, '" . $value . "')]");
+  }
+
+}

I didn't add an interdiff, because of the merge conflict, it's hard to get a clean interdiff.

Berdir’s picture

Status: Needs review » Needs work
  1. +++ b/config/schema/entity_browser.schema.yml
    +++ b/config/schema/entity_browser.schema.yml
    @@ -1,4 +1,4 @@
    
    @@ -1,4 +1,4 @@
    -# Schema for configuration files of the Entity browser module.
    +# Schema for configuration of the Entity browser module.
    

    Unrelated change, no big deal, but cleanup like that tends to result in more frequent patch conflicts.

  2. +++ b/entity_browser.module
    @@ -176,13 +176,17 @@ function entity_browser_form_entity_embed_dialog_alter(&$form, FormStateInterfac
       // Add contextual information to entity browser's widget context array.
       if (!empty($form['entity_browser']['#entity_browser'])) {
    -    $embed_button = $form_state->get('embed_button');
    -    $form['entity_browser']['#widget_context']['embed_button_id'] = $embed_button->id();
     
         if (empty($form['entity_browser']['#widget_context'])) {
           $form['entity_browser']['#widget_context'] = [];
         }
     
    +    // Cardinality is always 1 with entity embed.
    ...
    +
    +    $embed_button = $form_state->get('embed_button');
    +    $form['entity_browser']['#widget_context']['embed_button_id'] = $embed_button->id();
    +
    

    What about just removing the empty-array initialization instead of moving the code down and then always setting a value afterwards anyway?

  3. +++ b/src/EntityBrowserWidgetContextTrait.php
    @@ -0,0 +1,42 @@
    +   */
    +  protected function getWidgetContext() {
    +    if ($this->currentRequest->query->has('uuid')) {
    ...
    +      if ($storage = $this->selectionStorage->get($uuid)) {
    

    The trait now has a dependency on selectionStorage and currentRequest, both don't exist by default in WidgetBase. That's always a bit weird, IDE's complain and so on.

    One option is to add abstract getCurrentRequest() and so on methods, but that's also almost more boilerplate code than what you're actually saving by having the trait.

  4. I wasn't aware of how ajax_view.js passed existing query arguments through to ajax requests, that's pretty neat and makes this indeed quite easy to resolve so that ajax requests work too. It would be nice to explicitly test this, though. If we have a view that has an exposed filter that should be fairly easy, we just need to submit that filter form once and make sure we still see a radio.
oknate’s picture

Update based on Berdir's feedback:

  1. I removed unrelated change. It wasn't even wrong, but it was unidiomatic. It can be dealt with in a separate issue, if needed.
  2. I updated the code in entity_browser_form_entity_embed_dialog_alter so that it doesn't check if array is empty so many times.
  3. I dropped the trait. In fact, the View widget wasn't even using the trait. I think during a refactor it stopped using it, and I missed dropping the code changes in the constructor.
  4. I added test coverage for the persistence of the radios when using exposed filters.
  5. I noticed that the cardinality error message was different in /src/Plugin/EntityBrowser/WidgetValidation/Cardinality.php, so I updated it to match:
    diff --git a/src/Plugin/EntityBrowser/WidgetValidation/Cardinality.php b/src/Plugin/EntityBrowser/WidgetValidation/Cardinality.php
    index a52dc4e..e26d3f6 100644
    --- a/src/Plugin/EntityBrowser/WidgetValidation/Cardinality.php
    +++ b/src/Plugin/EntityBrowser/WidgetValidation/Cardinality.php
    @@ -28,7 +28,7 @@ class Cardinality extends WidgetValidationBase {
         $count = count($entities);
         $max = $options['cardinality'];
         if ($max !== EntityBrowserElement::CARDINALITY_UNLIMITED && $count > $max) {
    -      $message = $this->formatPlural($max, 'You can not select more than 1 entity.', 'You can not select more than @count entities.');
    +      $message = $this->formatPlural($max, 'You can only select one item.', 'You can only select up to @number items.', ['@number' => $max]);
           $violation = new ConstraintViolation($message, $message, [], $count, '', $count);
           $violations->add($violation);
         }
    

    This might mean I need to update a test.

oknate’s picture

Status: Needs work » Needs review
oknate’s picture

Fixing EntityBrowserViewsWidgetTest.php after changing the validation message.

The last submitted patch, 117: entity-browser-single-selection-2845941-117.patch, failed testing. View results

oknate’s picture

Adding test coverage for the cardinality functionality within the entity embed integration.

oknate’s picture

I saw one cut and paste error where I needed to change the word in a comment from "without" to "with".

oknate’s picture

  1. Adding test coverage for the cardinality functionality within the inline entity form widget integration. With the addition of this test, the patch covers the three major use cases within the module: the field widget, the entity embed dialog and the inline entity form widget.
  2. Moving the helper methods for finding checkboxes vs radios to EntityBrowserWebDriverTestBase. I would like to use these in other tests.
  3. Changing calls to \Drupal::configFactory()->getEditable() to $this->config()
  4. I found a more efficient way of setting views to use the cardinality feature:
    -    $view = \Drupal::configFactory()->getEditable('views.view.bundle_filter_exposed');
    -    $field = $view->get('display.default.display_options.fields.entity_browser_select', TRUE);
    -    $field['use_field_cardinality'] = FALSE;
    -    $view->set('display.default.display_options.fields.entity_browser_select', $field);
    -    $view->save();
    +    // Set view to use field cardinality.
    +    $this->config('views.view.bundle_filter_exposed')
    +      ->set('display.default.display_options.fields.entity_browser_select.use_field_cardinality', FALSE)
    +      ->save();
    
ainoidoi89’s picture

Hi @oknate
I had error when tried to apply your patch #123 on drupal 8.7.1
I checked log and it has something like this:
can't find file to patch at input line 866:
I checked in your patch add see this file is not in my source code. Please help to check.
tests/src/FunctionalJavascript/EntityBrowserWebDriverTestBase.php

antiorario’s picture

Status: Needs review » Reviewed & tested by the community

The patch at #123 gets the job done with the latest dev version.

oknate’s picture

Thanks, @antiorario! I think this is about ready to go into the dev branch. Anyone else using this patch successfully who wants to concur?

Berdir’s picture

+1, we've been using previous patches for a long time and I just updated to the latest one here, automated and manual testing looks good.

oknate’s picture

Adding credit to anyone who added a useful comment.

  • oknate committed 0de5e61 on 8.x-2.x
    Issue #2845941 by oknate, Primsi, yongt9412, dawehner, ytsurk, ataimist...

  • oknate committed 3c1142b on 8.x-1.x
    Issue #2845941 by oknate, Primsi, yongt9412, dawehner, ytsurk, ataimist...
oknate’s picture

Status: Reviewed & tested by the community » Fixed

Committed to dev! Thanks to everyone who helped out on this issue.

  • oknate committed 80cc894 on 8.x-1.x
    Issue #3068426 by oknate, kellyimagined: 8.x-1.x branch tests are...
oknate’s picture

When I backported this to 8.x-1.x, I forgot to update a drupal:media reference, so tests have been failing. I just committed a patch to fix that, so the tests for the 8.x-1.x branch should go back to green soon.

Status: Fixed » Closed (fixed)

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

oknate’s picture