Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Problem/Motivation
When YAML forms are attached to a page via an entity reference or a block it would help user experience to allow the form to be submitted using AJAX.
Proposed resolution
Allow YAML forms to be submitted using AJAX
Remaining tasks
TBD
User interface changes
TBB
Development Notes
- Branch Name: 2757491-submit-via-ajax
- Commit message: Issue #2757491: Allow YAML forms to be submitted using AJAX
References
Comment | File | Size | Author |
---|---|---|---|
#57 | interdiff-2757491-55-57.txt | 389 bytes | jrockowitz |
#57 | allow_webforms_to_be-2757491-57.patch | 169.06 KB | jrockowitz |
| |||
#55 | allow_webforms_to_be-2757491-55.patch | 169 KB | jrockowitz |
| |||
#50 | allow_webforms_to_be-2757491-50.patch | 161.91 KB | jrockowitz |
| |||
#42 | interdiff-2757491-32-42.txt | 914 bytes | jrockowitz |
Comments
Comment #2
jrockowitz CreditAttribution: jrockowitz as a volunteer commentedComment #3
jrockowitz CreditAttribution: jrockowitz as a volunteer commentedDrupal AJAX integration is not fully documented and there are some more immediate issues that need to be addressed. So I am going to hold off implementing this feature.
Comment #4
jrockowitz CreditAttribution: jrockowitz as a volunteer commentedComment #5
fenstratMoving to Webform queue, see #2827845: [roadmap] YAML Form 8.x-1.x to Webform 8.x-5.x.
Comment #6
jrockowitz CreditAttribution: jrockowitz as a volunteer commentedThis feature could be handled by the port of the Webform AJAX module to D8
Comment #7
jrockowitz CreditAttribution: jrockowitz as a volunteer commentedComment #8
AndyF CreditAttribution: AndyF commentedHey @jrockowitz, I'm starting the ball rolling on this. AFAICT there hasn't been a start on webform_ajax 8. Would you prefer me to submit a patch here or there? (:
Comment #9
jrockowitz CreditAttribution: jrockowitz as a volunteer commented@AndyF Similar to the Webform View Integration module, I think it is perfectly okay to start with submitting a patch. First off, you will most likely get more followers and reviewer within the Webform issue queue.
Personally, I think AJAX integration should be part of Webform core, similar to how Views includes AJAX integration... all you need to do is check the 'Use AJAX' box to ajaxify a View.
Still, I must emphasize that this feature requires test coverage, which is now possible using Drupal's JavaScript testing framework.
I recommended looking at the WebformDialogTrait, which handles how admin and element setting forms are ajaxified within modal dialogs. In theory, you might be able to write a trait that enables Ajax support for ANY entity form. At the very least, the trait could support AJAX validation.
Finally, you should see if any of your work could be applicable to the Examples module.
Lastly... thanks.
Comment #10
AndyF CreditAttribution: AndyF commentedSo I feel a bit silly - having asked what you'd prefer, I found it easier to develop a standalone module while I'm still trying to get an idea of Webform's overall architecture (and because I shamelessly stole from contact_ajax which is also standalone). I've created a sandbox for it but am very happy for you to fold it into webform.
Hopefully I can trigger testbot by attaching as a patch...
Comment #11
jrockowitz CreditAttribution: jrockowitz as a volunteer commented@AndyF I am getting a little swamped with issues and requests. I think a dedicated Webform Ajax sandbox module is the way to go.
I will do some initial review of your sandbox module and then add it the Webform Add-Ons list.
Comment #13
AndyF CreditAttribution: AndyF commented@jrockowitz thanks, I appreciate any time you can spare, I'm still far from feeling confident with Drupal 8!
Glad to see testbot worked (there's one known bug - Drupal messages stack up on multiple submissions - which is what's causing the failure).
Comment #14
jrockowitz CreditAttribution: jrockowitz as a volunteer and at Memorial Sloan Kettering Cancer Center commented@AndyF I just tested your sandbox, your code works, and make complete sense to me. Could you experiment with getting AJAX callbacks to work within multiple step forms with preview and save draft enabled.
If you can get the ajax callbacks working and it is really just few lines of extra code. I can find the time to get the UX right.
Comment #15
jrockowitz CreditAttribution: jrockowitz as a volunteer and at Memorial Sloan Kettering Cancer Center commentedAlso, checkout code in the D7 Webform Ajax module, I think the trick with multiple step AJAX forms is storing the unique but persistent 'webform_ajax_wrapper_id' in a hidden field or $form_state (which I would prefer).
Comment #16
jrockowitz CreditAttribution: jrockowitz as a volunteer and at Memorial Sloan Kettering Cancer Center commentedAlso checkout #2872021: Webform Ajax Drupal 8 port.
Comment #17
AndyF CreditAttribution: AndyF commentedah my bad, I did check both webform and webform_ajax but somehow missed that :/
I'll take a look now...
Comment #18
jrockowitz CreditAttribution: jrockowitz as a volunteer and at Memorial Sloan Kettering Cancer Center commentedI think the Webform Ajax integration is definitely going to be a collaborative effort, which would be great since we should be able to resolve any outstanding issues/challenges and then add this to the Webform core module.
Comment #19
AndyF CreditAttribution: AndyF commentedK a quick look at the existing port and I think our efforts could complement each other's. It looks like @vanvlaanderen has multipage and working back links but no tests, so hopefully not too much duplicated effort!
Comment #20
AndyF CreditAttribution: AndyF commentedI got a chance to work on this yesterday:
Comment #21
AndyF CreditAttribution: AndyF commentedComment #23
AndyF CreditAttribution: AndyF commentedSilly me, forgot the 'Back to form' callback route...
Comment #24
dawehnerI'm wondering whether we could minimize the tests a bit by merging them together a bit aka. always add the required text field, but then in one test method:
1. Forget to enter this required text field
2. Posting it, ensure the message is shown
3. Do another post to ensure that a new message is shown
On the other hand having explicit named bits on the ajax webform is really nice for itself.
Is it possible to pass in an URL object here, so just use
This one feels a bit redundant with the other tests
Oh that is tricky. There is indeed no new element popping up, right?
Can't you put it into
Drupal\Tests\webformweb / webform/tests/src
That indeed looks quite ugly :)
At least for me there seems to be nothing in those helper classes which requires them to be classes. Couldn't you just use methods which call each other, like on a trait?
Its a bit sad ... views already provides an ajax command which does exactly that:
\Drupal\views\Ajax\ScrollTopCommand
. I think you should be able to copy exactly from it.For
in_array
we should pass TRUE ($strict) as third parameter, otherwise you might run into the problem shown inhttps://3v4l.org/jX5Ze
I assume there aren't many usecases to make that configurable?
Note:
\Drupal\Core\Render\MainContent\AjaxRenderer::renderResponse
does a slightly simpler approach aka. just use['#type' => 'status_messages']
There is no variable $message_manager hanging around :)
Let's use
===
Is that really needed? Do the tests in subdirectories don't run automatically?
Comment #25
AndyF CreditAttribution: AndyF at TES Global commentedThanks for the review @dawehner!
1. I've been trying to make the setup explicit and at the start of the test, rather than hidden in either setUp() or createWebform(). I realise it does lead to slightly top-heavy test cases and repetition. Happy to go with whatever people prefer (:
2. Yes! Thank you!
3. It's a specific regression test, so perhaps would be good to keep it separate. It detected the problem with implementing point 11.
4. Yeah :/ Will investigate using the throbber.
5. Apparently not, the autoloader isn't happy with that (or it's me being silly).
6. :p Not at the top of the priority list just yet
7. At the moment they don't need to be classes because they have no state, but I thought they might have some at some point. I realise the more normal thing to do would just be to add methods on a base class, but I've seen the object creator pattern before and found it quite neat personally.
8. Thanks! Will use that
9. Thanks, added.
10. I wanted to focus on core behaviour first, and add things like animation customisation second. (I'm sure someone _will_ want to configure it at some point!)
11. Hmmn, looks like my #prefix and #suffix will get overridden if I go that approach.
12. How'd that crafy little beggar get there?! Thanks!
13. Done
14. Dunno, will give it a go and find out...
Comment #26
dawehnerSome additional feedback ...
This description is super pointless ... Let's just drop it, the label of the checkbox explains enough already.
It'd be nice to have an explicit dependency on
- core/jquery.once
.Nitpick: Missing @return statement.
Ideally you could set a data- attribute on the element and then use it here. By this we don't have classes/ids while still making it possible to access it, see
core/modules/big_pipe/js/big_pipe.js:68
as random exampleNote: You can use
::getEntityManager()
.Do you mind using short array syntax here?
Note: I would have ordered the test methods in a different order. For example I would start with
testAjaxSubmissionStorage
then continue withtestRequiredTextField
or something like that. I know this is super nitpicky, but I like a nice readable test. This also makes it easier for reviewers, to be honest.Let's please use the convention used in Drupal usually, aka. move the constructor/setup method to the top as well as any property we use ...
In an ideal world you would render the confirmation inline, right?
It doesn't sound like any of these
@todos
needs to be addressed now.Comment #27
jrockowitz CreditAttribution: jrockowitz as a volunteer and at Memorial Sloan Kettering Cancer Center commentedI am about to commit #2875841: Hide third party tab (at least optionally). You will need to change 'webform_ajax_form_webform_third_party_settings_form_alter' to 'webform_ajax_webform_third_party_settings_form_alter'
Comment #28
basil_snowman CreditAttribution: basil_snowman as a volunteer and for Skilld commentedComment #29
ziomizar CreditAttribution: ziomizar as a volunteer and at East Atlantic Engineering commentedHi basil_snowman,
Thanks for your patch.
When you write a patch its good practice upload also an interdiff (https://www.drupal.org/documentation/git/interdiff) in this way its easier see what differ between patches.
Comment #30
AndyF CreditAttribution: AndyF at TES Global commented@jrockowitz Thanks for the update, that would've had me scratching my head a bit! I've updated the code in the sandbox, but haven't posted a patch (that's the only change). (I still intend to look at @dawehner's feedback.)
Comment #31
jrockowitz CreditAttribution: jrockowitz as a volunteer and at Memorial Sloan Kettering Cancer Center commented@AndyF I have just committed #2878193: Allow actions (aka submit buttons) to be placed anywhere on a webform which should not have any impact on your code because your #ajax callbacks should still be attached to the $form['actions'].
Comment #32
AndyF CreditAttribution: AndyF at TES Global commentedI've responded to some more of @dawehner's comments:
1. Done
2. Added.
3. On the todo list (:
4. I'm using
\Drupal\Core\Controller\ControllerBase::entityTypeManager()
, I couldn't find an appropriate::getEntityManager()
.5. Done.
6. I've reordered the tests, not 100% sure if the order's perfect...
7. Sorry, wasn't done intentionally! I've moved them up top.
8. No, because the confirmation is a redirect. However before the redirect can happen the form must validate - and it's nice to do that with AJAX, so there is a good reason to have AJAX redirects I think!
Here's the latest patch which includes clean-up based on the feedback above, and also supports page and URL confirmation types.
Comment #33
AndyF CreditAttribution: AndyF at TES Global commented@jrockowitz I think it's getting to the point where we should decide if webform_ajax should remain as a standalone module, or if it gets folded into webform proper (there are some ugly bits in the code where I suspect the ideal solution will change based on this).
Comment #35
AndyF CreditAttribution: AndyF at TES Global commentedIt looks like I can't assume
<front>
maps to/
with testbot. (The tests pass for me locally.)Comment #36
dawehnerRight, Drupal is installed in a directory on the testbot.
$this->getAbsoluteUrl()
might help you.Comment #37
jrockowitz CreditAttribution: jrockowitz as a volunteer and at Memorial Sloan Kettering Cancer Center commented@AndyF I would like to include Ajax support in the core Webform module as an out-of-the-box feature.
Comment #38
ABaier CreditAttribution: ABaier commentedNice to hear, @jrockowitz! Especially for the Multistep Forms Ajax would be a great plus, which would allow them to be used inside blocks or paragraphs easily. Would love to see that coming!
Comment #39
hanoiiFor what it's worth, I am starting to try this patch. On a simple form it seems to be working fine, one thing I noticed is that on forms that the submissions are disabled the thank you message is not displayed.
I think this belongs more to webform than this patch. Reported it on #2883894: A webform's state is always STATE_UNSAVED if submissions are disabled.
Also, there's a lot of work put into this patch. What can it be done to be included in webform. Is there anything I can do to help?
Comment #40
hanoiiComment #41
AndyF CreditAttribution: AndyF at TES Global commentedThanks @hanoii, off the top of my head
Comment #42
jrockowitz CreditAttribution: jrockowitz as a volunteer and at Memorial Sloan Kettering Cancer Center commentedAttached patch fixes broken tests.
Comment #50
jrockowitz CreditAttribution: jrockowitz as a volunteer and at Memorial Sloan Kettering Cancer Center commented@AndyF Your patch was so unbelievably helpful. It immediately highlighted my mistakes with how inline confirmations and confirmation messages were being handled. Your code also provided the needed helper functions and perfect work-arounds. I had thought it would take a few days to get this integrated and it only took a few hours.
Notes
Comment #52
jrockowitz CreditAttribution: jrockowitz as a volunteer and at Memorial Sloan Kettering Cancer Center commentedSomething is up with the testbot.
All the tests are passing locally, so feel free to download and review the patch.
Comment #53
hanoiiI'll review, but do you think this one could still be necessary: #2883894: A webform's state is always STATE_UNSAVED if submissions are disabled?
Comment #55
jrockowitz CreditAttribution: jrockowitz as a volunteer and at Memorial Sloan Kettering Cancer Center commentedAttached patch, refactors the WebformDialogFormTrait to use the WebformAjaxFormTrait and removes most of the duplicate code.
Comment #56
dotist CreditAttribution: dotist commentedThis is great! #55 is working for me.
A note to those using a custom template for your webform: you must ensure that you've got the right #id on your form for the ajax response to work. I passed it to my template in hook_preprocess_webform() with
$variables['element']['#form_id']
Comment #57
jrockowitz CreditAttribution: jrockowitz as a volunteer and at Memorial Sloan Kettering Cancer Center commentedI think adding adding a $form['#form_wrapper_id'] property should help with customized form templates.
Comment #59
mikeoharaIs this in the -dev branch now?
Comment #61
jrockowitz CreditAttribution: jrockowitz as a volunteer and at Memorial Sloan Kettering Cancer Center commentedI committed the committed the patch. Please download the latest dev release to review.
Comment #62
AndyF CreditAttribution: AndyF at TES Global commented@jrockowitz that's awesome, thanks!
Comment #63
5n00py CreditAttribution: 5n00py commentedWow! Great job. Works well for me.
I used
And message was shown on top of form.
Thanks!
Comment #64
Lennard WesterveldOops my bad :) the fault was in a other patch i applied.
Comment #66
nickBumgarner CreditAttribution: nickBumgarner at Inclind Inc commentedUpdate -- made a comment here and then found the bug (which was not related to this module) almost immediately afterward.
Comment #67
nickvanboven CreditAttribution: nickvanboven as a volunteer commentedIs there any way to alter te position of the message to the bottom of the form and add an extra class to it? or wrap it?