example_field:
'#type': custom_composite
'#title': 'Label'
'#multiple__header': false
'#multiple__item_label': 'Tankkaart'
'#multiple__min_items': 1
'#multiple__empty_items': 0
'#multiple__sorting': false
'#multiple__add': false
'#multiple__remove': false
'#multiple__add_more_input': false
'#multiple__add_more_button_label': 'Voeg nog een itemtoe'
'#wrapper_type': container
'#element':
products:
'#type': checkboxes
'#options':
diesel+adblue: 'Diesel en AdBlue'
benzine+95+e10: 'Benzine 95 E10'
benzine+98+e5: 'Benzine 98 E5'
lpg: LPG
gasolie+diesel: 'Gasolie diesel (rode mazout)'
kero+type+c: 'Kero Type C'
'#title': Productensubmission in database is "Array" and also in the mail is "Array"
| Comment | File | Size | Author |
|---|---|---|---|
| #69 | 3216923--6.2.x--69.patch | 15.68 KB | alorenc |
| #63 | 3216923--6.2.x--62.patch | 14.64 KB | jrglasgow |
| #48 | 3216923--6.1.3--48.patch | 14.64 KB | rossb89 |
| #47 | 3216923--6.1.2--47.patch | 15.13 KB | jonmcl |
| #41 | 3216923-41.patch | 14.47 KB | jrockowitz |
Issue fork webform-3216923
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
michiellucas commentedI created a patch for saving and loading these values
Comment #3
michiellucas commentedComment #4
jrockowitz commentedI am very hesitant to start supporting this feature because of the risk of regressions. But, at the same time, I understand why having support for multi-select and checkboxes within a composite is important.
Instead of pipe-delimited values, my initial thought is that we need to serialize the values using JSON, YAML, or PHP. I am partial to using YAML, but I open to suggestions.
Also, this improvement is going to require a decent amount of test coverage.
Thank you for creating the first patch.
Comment #5
michiellucas commentedIt works for my setup and is already in production, i think that with some easy changes you can support it.
Love the composite work, amazing webforms you can build without custom code.
Comment #6
marcusvsouza commentedThe patch in comment #2 applies without problems and work good, it remains to assess the feasibility of the implementation.
Comment #8
jrockowitz commentedThe attached patch uses serialization and tweaks \Drupal\webform\Plugin\WebformElement\WebformCompositeBase::formatComposite to support multiple values.
This is a major improvement that is changing how some data is stored, My thoughts are we should implement it using the least amount of code with a lot of test coverage.
Also, I would like to implement this feature in 8.x-5.x and then merge into 6.x
Comment #12
jrockowitz commentedComment #13
jrockowitz commentedComment #14
paulocsI'll write some tests for it.
Comment #15
jrockowitz commented@paulocs Please hold off writing the automated tests. We need to create more test webform examples.
For example, we need to manually test adding checkboxes to a composite in code,
Comment #16
paulocsOkay. I already wrote some test to the webform created in #13. Nothing big
Do you mean for example via hook?
Comment #17
jrockowitz commentedMaybe add checkboxes to the webform_example_composite.module
Comment #18
paulocsPlease review...
I added a checkboxes field via hook to the composite element.
Comment #19
jrockowitz commentedPlease let me moving this ticket forward and I will ping you as it needs review.
Comment #21
jrockowitz commentedSo I added checkboxes to example composite and fixed a few related bugs.
I think for an MVP we should just support checkboxes and multi-select. Support for other multiple value elements (manually table selects) can be added later (or never)
Comment #24
jrockowitz commentedComment #25
jrockowitz commentedFixing minor typo. This patch needs to be reviewed by someone else.
Comment #26
marcusvsouza commentedThe patch in the comment #25 save the checkboxes correctly, not affecting others functionalities.
Comment #27
jrockowitz commented@marcusvsouza Thank you for reviewing the patch. This is a major change and probably requires more review and consideration.
Comment #28
michiellucas commentedThanks for the improvement but i am missing
public static function getOptionText($value, array $options, $options_description = FALSE) {
So the values are represented in the mails or did you fix this a different way?
Comment #29
jrockowitz commentedI tried to fix the display of the values at a higher level. Can you create an example webform that can be used to reproduce what you are seeing via email.
Comment #30
jrockowitz commentedChanging the priority to Major since the feature request is going to require a lot of review and testing.
Comment #31
jonmcl commentedThis is working very well for us. Composite element with a custom checkboxes element.
I created a second issue to handle re-rolls for 6.x: #3240605: Radios or Checkboxes inside Composite not saved (6.x-dev clone)
Comment #32
jedihe commentedI suggest you consider using JSON format for serialization, as DB engines are capable of handling JSON; doing this should get submissions better prepared to perform query/manipulation directly with DB primitives/plug-ins, which should be way more performant than grep'ping + PHP-land unserialization. For reference, see:
Comment #33
jrockowitz commented@jedihe That was exactly the type of suggestion I was looking for via #4. Thanks.
JSON it is.
Comment #34
jrockowitz commentedComment #36
jrockowitz commentedComment #37
maijs commentedThanks, @michiellucas and @jrockowitz for great work!
Couple of things I'd like to suggest:
1. Hardcoding webform element types which are supported in composite element in
Plugin\WebformElement\WebformCompositeBase::isSupportedElementType()and inElement\WebformElementComposite::validateWebformElementComposite()methods make it really hard to make it work with custom webform element types which directly extend the allowed hardcoded type classes, e.g.,CheckboxesorRadios.In a project I'm working on I have several custom webform element types which extend said classes (e.g.,
class DecoupledCheckboxes extend Checkboxes). They are not going to work with current implementation, even if they are technically completely compatible.2. The logic behind checking if a particular element type is supported by a composite element type is scattered across many related classes like
Plugin\WebformElement\WebformCompositeBaseandElement\WebformElementComposite. It becomes very hard to override methods likePlugin\WebformElement\WebformCompositeBase::isSupportedElementType()because it requires at least two class overrides which is cumbersome and hardly maintainable.Given that
Plugin\WebformElement\WebformCompositeBase::isSupportedElementType()andElement\WebformElementComposite::validateWebformElementComposite()methods are designed to work within thewebform_custom_compositewebform element plugin (or the extended classes of this class), I think it's best if is-this-type-allowed checks are performed by the composite webform element plugin itself. This will allow for easier customizations in the extended classes of the custom webform types, and will also keep the logic contained in one place.3. Currently
Plugin\WebformElement\WebformCompositeBase::isSupportedElementType()method returns FALSE for element plugins which are instance ofWebformElementEntityReferenceInterface.After doing some testing, I can report that term reference option webform element works fine within the composite element and multiple reference term IDs are nicely saved as multiple values in the database.
It's fine to disable term reference elements by default, if maintainers have concerns that this may cause regressions. But, going back to first two points I raised, currently it's a huge headache to override the logic in
isSupportedElementType()method in cases where there's no such concern.Also, I really hope that patches in this issue will end up in 6.x branch as well.
Comment #38
jrockowitz commentedYes, I am very concerned about unexpected issues with composite sub-elements which is why WebformCompositeBase::isSupportedElementType acts as a whitelist. In a separate ticket, we could rework the code to allow a webform element to determine if it can or can't be used as a composite sub-element.
Comment #39
maijs commentedRe-rolling
3216923-36.patchfor 6.x branch.Comment #41
jrockowitz commentedI will probably not commit this feature until 6.2.x
Comment #42
jonmcl commentedPatch at #41 does not currently work with 6.1.1, 6.1.2 or current 6.x-dev. It does work with 6.1.0
Comment #43
jrockowitz commentedComment #44
jrockowitz commentedComment #46
jrockowitz commentedI updated the patch to work with Webform 6.2.x. I am very hesitant to merge this because I think it may create more issues that it is worth.
Comment #47
jonmcl commentedPlease don't drop this :)
We are successfully using it in production (with 6.1.2). Our composite elements have textfield, textarea, and checkboxes. What sort of issues to you foresee happening by merging this into a release? Anything specific that I could test for?
Very minor re-rolll for 6.1.2 (currently recommended version).
Comment #48
rossb89 commentedDid a minor re-roll for 6.1.3 in case anyone needs it for the latest 6.1.x version :)
Comment #49
KristineC commentedTested @JonMcL's patch file on Drupal 9 and 6.1.2. Seems to be working fine with fields saving.
Comment #50
elneto commentedOk, I am shooting in the dark here. I added #36 patch trying to fix the error below. It happens only when I click on one of the composite checkboxes and submit the webform. Just wanted to see if anyone had run into this. Trying to figure what is causing it.
I am using Drupal 9.3.12 on php 8.1.5 and Maria db 10.6.7-MariaDB-2ubuntu1.
Thanks!
Comment #51
plessas commentedI am also facing the TypeError: Illegal offset type in Drupal\Core\Render\Element\Checkboxes::valueCallback() error that @elneto reports, with version 6.1.3 of the module and patch #48. The details of the environment are: Drupal 9.3.12 and php 8.1.5. This was previously working (tested with a previous version of php - not sure which 8.1.x- and with Drupal 9.3.7 - I haven't used it with newer Drupal core versions until today), however I an not sure what broke it (Drupal core update or possibly the PHP update).
Comment #52
danthorne#48 working for me, apart from when I add the field in a view (webform_views installed). Array is outputted rather then the actual submitted data.
Comment #53
plessas commented@danthorne which Drupal core version are you using?
I am currently using Drupal 9.4.4, Webform 6.1.3 and the error still appears with patch #48.
For anyone interested for a quick workaround (unfortunately I didn't have the time to search for an appropriate solution), the problem occurs since in line 136 of core/lib/Drupal/Core/Render/Element/Checkboxes.php:
$key is actually an array.
Replacing (using a local patch) that line with the one below seems to solve the problem (at least for my use case):
Comment #54
danthorneCurrently using Drupal 9.4.3 and Webform 6.1.3
Comment #55
bbombachiniI'm on D9.5 and php 8.1
Tried the patch #48 with webforms 6.1.4 and tried the patch from the MR (https://git.drupalcode.org/project/webform/-/merge_requests/123.patch) with version 6.2.0-beta5 (latest release) and the dev version, but all the 3 gave me the same error as #50 on form submission:
TypeError: Illegal offset type in Drupal\Core\Render\Element\Checkboxes::valueCallback() (line 136 of core/lib/Drupal/Core/Render/Element/Checkboxes.php).So I'm moving this to needs work.
Comment #56
phonkala commentedFor me the parth #48 works fine right after applying it, using Drupal 10.0.8, Webforms 6.2.0-beta5 and PHP 8.1. This feature was very much needed and as it's just saving the data as JSON string, I don't think adding this to the actual module would be much of an issue. However if that is not desired, maybe this could be moved to a separate module while it's not considered stable?
And for @bbombachini, I had no issue using checkboxes and submitting form, no errors there.
Comment #57
bbombachiniInteresting @phonkala, I'm still testing this on D9.5.3, webform 6.2.0-beta5, PHP 8.1, and the patch from #48. And I still have the same error:
TypeError: Illegal offset type in Drupal\Core\Render\Element\Checkboxes::valueCallback() (line 136 of core/lib/Drupal/Core/Render/Element/Checkboxes.php).So I created a simple webform for testing, can you try using this form and tell me what it gives you for
$element[$key]on line 36 of core/lib/Drupal/Core/Render/Element/Checkboxes.php?I have the same issue as outlined on comment #53 where $key is an array.
Comment #59
elberHi I just rebased.
Comment #60
phonkala commented@bbombachini I was getting no output of that yaml (well, there was submit button) so checked into it a bit and seems the element types are named differently than mine. Modified the source "elements" section a bit, with this I got composite with checkboxes:
And submitting gives no error.
Basically I just checked the element types from my other forms and replaced the ones you had with them. And also removed the "|-" part from the "elements" row.
Comment #61
phonkala commented@bbombachini Ah now I see it, using "webform_checkboxes_other" as the element type sure does give the array key error! Weirdly, basic checkboxes work nicely and for example even "webform_select_other" works just fine.
EDIT: Tested submitting the form with "radios or other", "checkboxes or other" and "select with other" input types and only the "checkboxes with other" has the issue. Even "Select with other" with multiple enabled works great and does save submissions correctly.
Comment #63
jrglasgow commentedThe patch in #48 was no longer applying to 6.2.x (Drupal 10 compatible) so I fixed the merge conflict in the fork
Comment #66
alorencFixed "webform_checkboxes_other" issue and the failing tests.
Comment #67
alorencComment #69
alorencRolled patch with the latest updates from merge request
Comment #70
liam morlandPlease rebase the merge request and get tests to pass. Which merge request is preferred?
I note that in addition to the two merge requests, there is also branch
3216923-composite-multiple.Comment #71
apparatchik commentedHow would one go about rebasing this for 6.3? besides the rebase, what else is needed to get this ready for beta?
Comment #72
liam morlandYou could either cherry-pick all the needed commits or use
git rebase --onto. Then force-push the branch and update the merge request to target 6.3.x.Comment #73
jrockowitz commentedI don't want to implement this feature because it would require too much work to support it.
For example, the webform views module would most likely need to be updated and tokens will probably need to fixed.