Problem/Motivation

I have talked to @jrockowitz a little about this.

He has added the use of the Off-Canvas tray from the Settings Tray module in core to the admin pages. We were trying to think of ways to use it on the front-end of the site.

This is would allow you to basic tasks from the front-end while you are view a webform like:

  • Reorder elements
  • Mark elements as required
  • edit elements

Proposed resolution

Add a "Quick Edit" to the contextual links for webform
Open a simplified version of the elements form in the off-canvas tray

Remaining tasks

For some reason the WebformQuickEditForm form uses ajax submit when on the front-end even though it extends \Drupal\webform_ui\WebformUiEntityForm and that form use ajax. Not sure why

The elements form work in the off-canvas tray but redirect to the webform edit page. They should stay on the current page. Maybe as simple as setting "destination" in the query string and checking for that.

Write javascript tests.

User interface changes

Basically the whole issue ;)

API changes

None

Data model changes

None

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

tedbow created an issue. See original summary.

tedbow’s picture

The patch works now to open the off-canvas tray but it will need a lot of work.

Thought @jrockowitz or someone else more familiar with the 5.x version of this module would have some idea on the ajax submit issue I mentioned in the summary. I was wondering if it a collision with some JS on that is only loaded on the front-end. I didn't look to long bug I could see on the server-side where the form is being set to use ajax.

tedbow’s picture

Re-uploading patch to get test to run (?)

jrockowitz’s picture

@tedbow I will look into the issue.

The webform modal dialog use a #ajax callback with the submit button to prevent validation errors from exiting the modal dialog.

The WebformDialogTrait::redirectForm probably just needs to account for the ?destination parameter.

tedbow’s picture

Status: Needs review » Needs work
FileSize
6.29 KB
23.24 KB

@jrockowitz thanks for pointing me to WebformDialogTrait. We were actually running into similiar problems in #2785047: In Outside In mode, form validation messages should appear in the off-canvas tray, not the main page and might be able to move some of this upstream.

I see \Drupal\webform\WebformDialogTrait::getRedirectUrl was always returning NULL but also the form classes were overriding this.

So created \Drupal\webform\WebformDialogTrait::getDestinationUrl() so the overrides could use this and then return their own values if returns NULL.

Also had to update \Drupal\webform_ui\WebformUiEntityForm::getElementRow() to add the destination option to all the operation links so that it is passed on the element forms.

So now it is working to edit Webform re-order the elements, mark as required. Also editing the elements from the links. Both of these you get redirected back to the orignal page.

But I just noticed that when click "Edit"(existing link) instead of "Quick edit" in the "destination" is also sent in the URL.
Without this patch using the existing contextual link:

  1. if you click "Edit" then just submit that form you are taken back to "destination"
  2. if you click "Edit" then click "edit" for an element you not taken back to "destination" and you have to click "Back to site" in the toolbar to get back.
  3. So basically the "destination" is not used unless you just submit the main for right away.

I think admin forms that you get to via contextual links usually route you back on submitting the form. But maybe this is not wanted on webform be you probably don't want to return back right away and may submit may forms.

Still needs work.

jrockowitz’s picture

This looks really cool.

A few tweaks

  • I merged your quick edit form tweaks into the WebformUiEntityForm and created a WebformUiEntityForm::isQuickEdit method. I am hoping this makes things easier.
  • I removing the element operations column from the quick edit form because the element's title opens each element's edit dialog.

A few thoughts..

  • We might need a helper method to pass the ?destination parameter from one quick edit form/dialog to another.
  • Save buttons maybe need to moved (or replicated) to the top of each quick edit form.

One issue.

  • Locally I have Drupal running in a subdirectory and the quick edit link is missing the base path.
  • ?destination=webform/contact should be ?destination=/BASE_PATH/webform/contact
jrockowitz’s picture

#2752637: hook_contextual_links_view_alter not getting called. just made me lose patience trying to work on this but I was able to completely fix ?destination issues using a PathProcessor. I was going to be an impossible task tracking every dialogs URL and passing the ?destination between links.

Personally, I would like to remove all the entity.webform.quick_edit_form code and alter the WebformUiEntityForm based on the "?_wrapper_format' query string parameter.

The #2752637: hook_contextual_links_view_alter not getting called. issue made it really hard to begin this refactoring.

jrockowitz’s picture

I created a dedicated branch so that I can easily track changes and quickly get an MVP working before DrupalCon.

jrockowitz’s picture

Adding reference to #2773591: New contextual links are not available after a module is installed which is making it difficult to see changes to contextual links.

jrockowitz’s picture

Status: Needs work » Needs review
FileSize
28.71 KB

Attached is an MVP that I would be okay with committing to force more eyeballs to look at the Webform module's quick edit and system tray integration.

Status: Needs review » Needs work

The last submitted patch, 10: add_quick_edit_off-2866554-10.patch, failed testing.

  • jrockowitz committed 475a9c1 on 2866554-quick-edit
    Issue #2866554 by tedbow, jrockowitz: Add Quick Edit off canvas form....
jrockowitz’s picture

Status: Needs work » Needs review
FileSize
28.76 KB
tedbow’s picture

Status: Needs review » Needs work

Nice work!

Most of these are suggestions but setting to Needs work because you probably want to fix the first 1 which is probably just a copy/paste error.

  1. +++ b/modules/webform_ui/src/PathProcessor/WebformUiPathProcessor.php
    @@ -0,0 +1,42 @@
    +/**
    + * @file
    + * Contains \Drupal\msk_path\MskPathAliasPathProcessor.
    + */
    

    @file isn't needed but also points to wrong class.

  2. +++ b/src/WebformDialogTrait.php
    @@ -33,6 +33,20 @@ trait WebformDialogTrait {
    +      'drupal_dialog_offcanvas',
    

    Here but in general with off-canvas use you might want to put to-do watch #2862625: Rename offcanvas to two words in code and comments. .

    It will change "offcanvas" to "off_canvas". Sorry this break stuff but you know the whole experimental thing.

    I guess a problem will be that you will some sites that will be using different versions.

    You could maybe just do a check on the config form that lets you choose off-canvas to check for if they are using the old version and tell them they need to update if they are using the old version.

    I think the easiest way to check the version is load the service "main_content_renderer.off_canvas" from the container and see if it's format tag is "drupal_dialog_offcanvas" or "drupal_dialog_off_canvas"

  3. +++ b/src/WebformDialogTrait.php
    @@ -33,6 +33,20 @@ trait WebformDialogTrait {
    @@ -70,7 +84,7 @@ trait WebformDialogTrait {
    

    Might want to put a @todo in about using the trait from this issue #2785047: In Outside In mode, form validation messages should appear in the off-canvas tray, not the main page, OffCanvasFormDialogTrait. I am reusing a lot of the logic there.

    The problems that webform is running are probably the same as any non-trivial form interaction in the tray(or any dialog) so trying to get that into the core module.

    Any feedback on that issue appreciated.

  • jrockowitz committed 6c9ecaf on 2866554-quick-edit
    Issue #2866554 by jrockowitz, tedbow: Add Quick Edit off canvas form.
    

  • jrockowitz committed 31ae70f on 2866554-quick-edit
    Issue #2866554 by jrockowitz, tedbow: Add Quick Edit off canvas form.
    
jrockowitz’s picture

@tedbow I am not seeing how to detect if offcanvas or off_canvas should be used.

I am okay tracking the main issue and doing the renaming of offcanvas to off_canvas, when needed.

  • jrockowitz committed 940832c on 2866554-quick-edit
    Issue #2866554 by jrockowitz, tedbow: Add Quick Edit off canvas form.
    
jrockowitz’s picture

Status: Needs work » Needs review
FileSize
29.66 KB
jrockowitz’s picture

@tedbow I am thinking version detection might be enough if #2862625: Rename offcanvas to two words in code and comments. is committed to 8.4.x and I can just assume 8.3.x installations should use 'offcanvas' and anyone using 8.4.x is using the latest dev release which should use 'off_canvas'.

  • jrockowitz committed 02b8a77 on 2866554-quick-edit
    Issue #2866554 by jrockowitz, tedbow: Add Quick Edit off canvas form
    
jrockowitz’s picture

Re-rolling with latest merges

tedbow’s picture

@jrockowitz re #20 because Settings Tray is an experimental this #2862625: Rename offcanvas to two words in code and comments. will likely get committed to both 8.3.x and 8.4.x.

  • jrockowitz committed 92dd95d on 2866554-quick-edit
    Issue #2866554 by jrockowitz, tedbow: Add Quick Edit off canvas form
    

  • jrockowitz committed d303166 on 2866554-quick-edit
    Issue #2866554 by jrockowitz, tedbow: Add Quick Edit off canvas form.
    
jrockowitz’s picture

Fixing some minor UX bugs.

  • jrockowitz committed 7087a28 on 2866554-quick-edit
    Issue #2866554 by jrockowitz, tedbow: Add Quick Edit off canvas form.
    

  • jrockowitz committed 1220688 on 2866554-quick-edit
    Issue #2866554 by jrockowitz, tedbow: Add Quick Edit off canvas form.
    

  • jrockowitz committed 2bafa18 on 2866554-quick-edit
    Issue #2866554 by jrockowitz, tedbow: Add Quick Edit off canvas form
    
jrockowitz’s picture

Here is my hack to detect offcanvas vs off_canvas.

  /**
   * Off canvas trigger name.
   *
   * @var string
   */
  protected static $offCanvasTriggerName;

  /**
   * Get Off canvas trigger name.
   *
   * @return string
   *   The off canvas trigger name.
   *
   * @see Issue #2862625: Rename offcanvas to two words in code and comments.
   * @see https://www.drupal.org/node/2862625
   */
  public static function getOffCanvasTriggerName() {
    if (isset(self::$offCanvasTriggerName)) {
      return self::$offCanvasTriggerName;
    }

    if (file_exists(drupal_get_path('module', 'outside_in') .'/css/off-canvas.css')) {
      self::$offCanvasTriggerName = 'off_canvas';
    }
    else {
      self::$offCanvasTriggerName = 'offcanvas';
    }

    return self::$offCanvasTriggerName;
  }

I am very tempted to commit the patch and do a screencast before DrupalCon.

Status: Needs review » Needs work

The last submitted patch, 30: add_quick_edit_off-2866554-28.patch, failed testing.

tedbow’s picture

Status: Needs work » Needs review
FileSize
1.31 KB
43.37 KB

@jrockowitz didn't get a chance to look through the patch fully but here is a suggestion to base getOffCanvasTriggerName() off the off-canvas renderer instead of the css file, which could be removed.

There will always need to be an Off-Canvas renderer.

Also in getModalDialogAttributes() I add the dialogClass that styles the tray. This way the links from the first opening of the tray will also open in a styled tray.
This shouldn't be needed after #2826722: Add a 'fence' around settings tray with aggressive CSS reset. but it also wouldn't hurt have it there.

  • jrockowitz committed 92f48ab on 2866554-quick-edit
    Issue #2866554 by jrockowitz, tedbow: Add Quick Edit off canvas form
    

  • jrockowitz committed f86e0f8 on 2866554-quick-edit
    Issue #2866554 by jrockowitz, tedbow: Add Quick Edit off canvas form.
    
jrockowitz’s picture

Status: Needs review » Needs work

The last submitted patch, 35: add_quick_edit_off-2866554-35.patch, failed testing.

  • jrockowitz committed 4954735 on 8.x-5.x
    Issue #2866554 by jrockowitz, tedbow: Add Quick Edit off canvas form
    
jrockowitz’s picture

Status: Needs work » Fixed
CatherineOmega’s picture

This looks good, but if the Settings Tray module isn't enabled, I get a lot of notices in my logs, at least on PHP 5.6. (Enabling it suppresses this message.)

Notice: Undefined index: destination in Drupal\webform_ui\PathProcessor\WebformUiPathProcessor->processOutbound() (line 28 of /var/www/connect.mitacs.ca/modules/contrib/webform/modules/webform_ui/src/PathProcessor/WebformUiPathProcessor.php) #0 /var/www/connect.mitacs.ca/core/includes/bootstrap.inc(552): _drupal_error_handler_real(8, 'Undefined index...', '/var/www/connec...', 28, Array) #1 /var/www/connect.mitacs.ca/modules/contrib/webform/modules/webform_ui/src/PathProcessor/WebformUiPathProcessor.php(28): _drupal_error_handler(8, 'Undefined index...', '/var/www/connec...', 28, Array) #2 /var/www/connect.mitacs.ca/core/lib/Drupal/Core/PathProcessor/PathProcessorManager.php(109): Drupal\webform_ui\PathProcessor\WebformUiPathProcessor->processOutbound('/admin/structur...', Array, Object(Symfony\Component\HttpFoundation\Request), Object(Drupal\Core\GeneratedUrl)) #3 /var/www/connect.mitacs.ca/core/lib/Drupal/Core/Routing/UrlGenerator.php(382): Drupal\Core\PathProcessor\PathProcessorManager->processOutbound('/admin/structur...', Array, Object(Symfony\Component\HttpFoundation\Request), Object(Drupal\Core\GeneratedUrl)) #4 /var/www/connect.mitacs.ca/core/lib/Drupal/Core/Routing/UrlGenerator.php(296): Drupal\Core\Routing\UrlGenerator->processPath('/admin/structur...', Array, Object(Drupal\Core\GeneratedUrl)) #5 /var/www/connect.mitacs.ca/core/lib/Drupal/Core/Render/MetadataBubblingUrlGenerator.php(105): Drupal\Core\Routing\UrlGenerator->generateFromRoute('<current>', Array, Array, true) #6 /var/www/connect.mitacs.ca/core/lib/Drupal/Core/Url.php(753): Drupal\Core\Render\MetadataBubblingUrlGenerator->generateFromRoute('<current>', Array, Array, true) #7 /var/www/connect.mitacs.ca/core/lib/Drupal/Core/Render/Element/RenderElement.php(359): Drupal\Core\Url->toString(true) #8 /var/www/connect.mitacs.ca/core/lib/Drupal/Core/Render/Element/RenderElement.php(229): Drupal\Core\Render\Element\RenderElement::preRenderAjaxForm(Array) #9 [internal function]: Drupal\Core\Render\Element\RenderElement::processAjaxForm(Array, Object(Drupal\Core\Form\FormState), Array) #10 /var/www/connect.mitacs.ca/core/lib/Drupal/Core/Form/FormBuilder.php(982): call_user_func_array(Array, Array) #11 /var/www/connect.mitacs.ca/core/lib/Drupal/Core/Form/FormBuilder.php(1045): Drupal\Core\Form\FormBuilder->doBuildForm('webform_ui_elem...', Array, Object(Drupal\Core\Form\FormState)) #12 /var/www/connect.mitacs.ca/core/lib/Drupal/Core/Form/FormBuilder.php(1045): Drupal\Core\Form\FormBuilder->doBuildForm('webform_ui_elem...', Array, Object(Drupal\Core\Form\FormState)) #13 /var/www/connect.mitacs.ca/core/lib/Drupal/Core/Form/FormBuilder.php(1045): Drupal\Core\Form\FormBuilder->doBuildForm('webform_ui_elem...', Array, Object(Drupal\Core\Form\FormState)) #14 /var/www/connect.mitacs.ca/core/lib/Drupal/Core/Form/FormBuilder.php(1045): Drupal\Core\Form\FormBuilder->doBuildForm('webform_ui_elem...', Array, Object(Drupal\Core\Form\FormState)) #15 /var/www/connect.mitacs.ca/core/lib/Drupal/Core/Form/FormBuilder.php(1045): Drupal\Core\Form\FormBuilder->doBuildForm('webform_ui_elem...', Array, Object(Drupal\Core\Form\FormState)) #16 /var/www/connect.mitacs.ca/core/lib/Drupal/Core/Form/FormBuilder.php(1045): Drupal\Core\Form\FormBuilder->doBuildForm('webform_ui_elem...', Array, Object(Drupal\Core\Form\FormState)) #17 /var/www/connect.mitacs.ca/core/lib/Drupal/Core/Form/FormBuilder.php(1045): Drupal\Core\Form\FormBuilder->doBuildForm('webform_ui_elem...', Array, Object(Drupal\Core\Form\FormState)) #18 /var/www/connect.mitacs.ca/core/lib/Drupal/Core/Form/FormBuilder.php(557): Drupal\Core\Form\FormBuilder->doBuildForm('webform_ui_elem...', Array, Object(Drupal\Core\Form\FormState)) #19 /var/www/connect.mitacs.ca/core/lib/Drupal/Core/Form/FormBuilder.php(314): Drupal\Core\Form\FormBuilder->processForm('webform_ui_elem...', Array, Object(Drupal\Core\Form\FormState)) #20 /var/www/connect.mitacs.ca/core/lib/Drupal/Core/Controller/FormController.php(74): Drupal\Core\Form\FormBuilder->buildForm(Object(Drupal\webform_ui\Form\WebformUiElementEditForm), Object(Drupal\Core\Form\FormState)) #21 [internal function]: Drupal\Core\Controller\FormController->getContentResult(Object(Symfony\Component\HttpFoundation\Request), Object(Drupal\Core\Routing\RouteMatch)) #22 /var/www/connect.mitacs.ca/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(123): call_user_func_array(Array, Array) #23 /var/www/connect.mitacs.ca/core/lib/Drupal/Core/Render/Renderer.php(574): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() #24 /var/www/connect.mitacs.ca/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(124): Drupal\Core\Render\Renderer->executeInRenderContext(Object(Drupal\Core\Render\RenderContext), Object(Closure)) #25 /var/www/connect.mitacs.ca/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(97): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array) #26 [internal function]: Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() #27 /var/www/connect.mitacs.ca/vendor/symfony/http-kernel/HttpKernel.php(144): call_user_func_array(Object(Closure), Array) #28 /var/www/connect.mitacs.ca/vendor/symfony/http-kernel/HttpKernel.php(64): Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object(Symfony\Component\HttpFoundation\Request), 1) #29 /var/www/connect.mitacs.ca/core/lib/Drupal/Core/StackMiddleware/Session.php(57): Symfony\Component\HttpKernel\HttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #30 /var/www/connect.mitacs.ca/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(47): Drupal\Core\StackMiddleware\Session->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #31 /var/www/connect.mitacs.ca/core/modules/page_cache/src/StackMiddleware/PageCache.php(99): Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #32 /var/www/connect.mitacs.ca/core/modules/page_cache/src/StackMiddleware/PageCache.php(78): Drupal\page_cache\StackMiddleware\PageCache->pass(Object(Symfony\Component\HttpFoundation\Request), 1, true) #33 /var/www/connect.mitacs.ca/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(47): Drupal\page_cache\StackMiddleware\PageCache->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #34 /var/www/connect.mitacs.ca/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(50): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #35 /var/www/connect.mitacs.ca/vendor/stack/builder/src/Stack/StackedHttpKernel.php(23): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #36 /var/www/connect.mitacs.ca/core/lib/Drupal/Core/DrupalKernel.php(656): Stack\StackedHttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #37 /var/www/connect.mitacs.ca/index.php(19): Drupal\Core\DrupalKernel->handle(Object(Symfony\Component\HttpFoundation\Request)) #38 {main}.

jrockowitz’s picture

Status: Fixed » Needs review
FileSize
608 bytes

Arg.. I really wish that error was displayed onscreen.

Here is the patch. I will probably do a hotfix release after DrupalCon.

  • jrockowitz committed f7fd775 on 8.x-5.x
    Issue #2866554 by jrockowitz, tedbow: Add Quick Edit off canvas form
    
jrockowitz’s picture

Status: Needs review » Fixed

Status: Fixed » Closed (fixed)

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