Summary
We are using a single webform to be displayed multiple times on the same page and the issue we are facing is that no matter when you fill the information in the submission information (such as source entity, source title, etc) is taken from the first webform rendered on the page and also the success message is placed in the first webform's container.
Steps to reproduce
- Create a webform named Event Registration
- Create a new content type named Event
- Add a new field that references an webform for Event content type
- Create multiple Event pages and for each event choose the Event Registration webform
- Created a new view that list Event rendered content (not Fields)
- Now you should be presented with a list of content and your webforms listed, too
Problem/Motivation
The form_id value is the same for all webforms, thus success messages are printed in the first webform's container and the information of the submission such as source entity is taken from the first content listed.
Proposed solution
Our solution was to append the source entity id to the actual form id by overriden the parent's getFormId() in src/WebformSubmissionForm.php as such:
/**
* {@inheritdoc}
*/
public function getFormId() {
$form_id = parent::getFormId();
$source_entity = $this->entity->getSourceEntity();
// When displaying the same webform on a single page, the form_id value must
// be unique based on the parent entity.
if ($source_entity) {
$form_id .= '_' . $source_entity->id();
}
return $form_id;
}
Remaining tasks
After applying the patch, custom code that alters the webform through hook_form_alter() or hook_form_FORM_ID_alter() needs to be checked because $form_id has changed now.
| Comment | File | Size | Author |
|---|---|---|---|
| #12 | Webforms Webform Demo Site.png | 103.01 KB | jrockowitz |
| #12 | 2957002-12.patch | 7.68 KB | jrockowitz |
| #11 | 2957002-11.patch | 6.03 KB | jrockowitz |
| #5 | 2957002-5.patch | 982 bytes | jrockowitz |
| #2 | 2957002-webform-same-webform-multiple-times.patch | 673 bytes | chrlvclaudiu |
Comments
Comment #2
chrlvclaudiu commentedComment #3
jrockowitz commentedThis patch reverts Webform submission form id no longer includes the source entity type and id.
The issue with including the source id is hook_form_FORM_ID_alter hooks have been written for each webform/source entity instance.
Comment #4
chrlvclaudiu commentedIf I understood correctly, the issue with having the source entity id in the form id is when trying to target a webform with hook_form_FORM_ID_alter, right ?
IMHO I'd rather prefer having same webform multiple times displayed and functional than introducing a couple of lines of code for targeting specific webforms in hook_form_alter() (not hook_form_FORM_ID_alter).
Any other ideas on achieving the same result as described in this ticket ?
Thanks in advance.
Comment #5
jrockowitz commented@chrlvclaudiu I think it is very clear now that every form instance must have unique form id which means all webforms must include the source entity type and id.
One compromise is to add the webform id to base form id.
BASE_FORM_ID = webform_submission_{WEBFORM_ID}_form
FORM_ID = webform_submission_{WEBFORM_ID}_{SOURCE_ENTITY_TYPE}_{SOURCE_ENTITY_ID}_{OPERATION}_form
The only form that I found which alters the base form id and form id is the \Drupal\views\Form\ViewsForm.
ViewsForm::getBaseFormId
ViewsForm::getFormId
@chrlvclaudiu Does the attached patch work for you? Can you also help fix the broken tests and write up the change record?
Comment #6
chrlvclaudiu commented@jrockowitz your patch works fine :)
Comment #9
chrlvclaudiu commentedI'll be able to handle the tests and the change record sometime mid next week.
Comment #10
jrockowitz commented@chrlvclaudiu I am going to assign this to myself. I would like to get this in before DrupalCon.
Comment #11
jrockowitz commentedComment #12
jrockowitz commentedThe attached patch now includes the below notification.
Comment #14
jrockowitz commentedComment #16
dpolant commentedUnfortunately this patch doesn't solve the following use case:
I think the problem is that the sourceEntity concept uses a route match which will catch the active node and not things like if a block has referenced a webform. I have a bad feeling there isn't an easy solution to this, but I will be giving it some thought.
Comment #17
finex commentedI've the same problem with the same webform loaded multiple times on the same page from a custom module.
Comment #18
ivnishI have the same problem
Comment #19
stefanos.petrakisReplying to the last 3 comments:
There is a - most probably - related issue and a possible solution to try out over at #3316194: [Webform block] Block redirect setting with node present collision.
If you manage to test it on your side, please post some feedback over there, cheers.
Comment #20
ivnishPatch from #3316194: Block redirect setting with node present collision works