Problem/Motivation
Currently core dialog links can set the attribute data-dialog-type to specify where the dialog will be either a generic dialog or a modal dialog.
The experimental Settings Module provides a new Off-canvas dialog that is not modal but is vastly different from the regular "dialog" that is provided by core(but not used anywhere in core).
In core there is currently not a way to specify which renderer class a dialog link should use so it can be handled by 1 of 2 classes \Drupal\Core\Render\MainContent\DialogRenderer or \Drupal\Core\Render\MainContent\ModalRenderer
The Setting Tray module currently get around this by looping through Drupal.ajax.instances and looking for the attribute data-dialog-renderer with the value 'off_canvas' and then manually updating the wrapper string sent in the query string of the instance's url.
Proposed resolution
'
Provide an new attribute for dialog links to use data-dialog-renderer.
Update ajax.js to handle this new attribute and concatenate it if provided to the _wrapper_format provided in the query string.
This would mean the new off-canvas tray provided in Settings Tray would use "drupal_dialog.offcanvas". The current links would continue to use "drupal_dialog" and "drupal_modal".
The current Drupal\outside_in\Render\MainContent\OffCanvasRender class uses this service by simply being tagged with the "format: drupal_dialog.offcanvas"
Note: this slight changed for the current implementation "format: drupal_dialog_offcanvas" to have "." show a clear split from is coming from the data-dialog-renderer attribute.
Remaining tasks
Review patch
User interface changes
None
API changes
New option to links attribute data-dialog-renderer
Used like:
$mylink['attributes'] = [
'class' => ['use-ajax'],
'data-dialog-type' => 'dialog',
'data-dialog-renderer' => 'off-canvas',
];
For new services that are tagged with render.main_content_renderer that wanted to be used with the dialog library they would need to use the "format" tag, "drupal_dialog.SOME_RENDER" or "drupal_modal.SOME_RENDER"
Data model changes
None
Comment | File | Size | Author |
---|---|---|---|
#45 | 2844261-45.patch | 17.26 KB | tedbow |
#45 | interdiff-38-45.txt | 2.19 KB | tedbow |
#38 | 2844261-38.patch | 17.3 KB | tedbow |
#38 | interdiff-32-38.txt | 520 bytes | tedbow |
#32 | 2844261-32.patch | 17.57 KB | tedbow |
Comments
Comment #2
tedbowHere is the first patch with needed changes to:
Comment #3
tedbowComment #4
tedbowAdded Javascript test to prove that dialog links with use a different renderer based on the 'data-dialog-renderer' attribute.
Comment #5
tedbowComment #6
tedbowHere are couple points from #2786459: "Offcanvas" tray should be using the existing dialog system
because I thought they might be brought up here
Comment #9
tedbowOK forgot that OffCanvasDialogTest uses the format of the renderer service. Updated
Comment #10
tedbowI have submitted a patch to #2784443: Move off-canvas functionality from Settings tray module into drupal.dialog.ajax library so that other modules can use it that includes because it is not longer waiting of other issues.
Going to close as a duplicate unless others determine it should be its own issue.
Comment #11
tedbowOk I am reopening this issue because #2784443: Move off-canvas functionality from Settings tray module into drupal.dialog.ajax library so that other modules can use it is blocked on other issues.
If this gets in there will be no there will no other changes needed to ajax.js in #2784443 and hopefully it will be easier to review
Rerolled the patch from #9 now that we are using es6.js files.
I also improve the tests a little bit. Now the test modal provides to 2 different render services and the test make sure the correct 1 is used for each test dialog link.
Comment #13
tedbowUpdating version
Comment #14
GrandmaGlassesRopeManCan we put this conditional value where the property is declared?
This is slightly confusing syntax.
@tedbow
Some minor nits, but it looks like the tests don't pass.
Comment #15
tedbowOk the test failed because the dialog was still on the page after clicking close. It is probably a timing issue where locally it passes because things are running faster and there is no need to wait.
I am changing the test to make a drupalGet call to reload the page before clicking the different modal link.
There should probably be a waitForElementRemoved() like there is \Drupal\FunctionalJavascriptTests\JSWebAssert::waitForElement()
I will make the issue.
Comment #16
tedbow@drpal thanks for the review. I didn't see when I posted #15
#14.1
No we shouldn't assign 'ajax' to
element_settings.dialogType
because the only values are 'modal' or 'dialog'.Update the comment to reflect what is happening here
// If this element has a dialog type use if for the wrapper if not use 'ajax'
#14.2
I reworked that block and added commented. It was more complex because it was also doing the logic that has now move to ajax.es6.js. The block simpler now and hopefully less confusing.
Comment #17
tedbowComment #18
GrandmaGlassesRopeManShould probably be documentation about the
filter
expressionComment #19
tedbowOK updated the comments there to reflect that we are first finding the instances and then looping through them.
Comment #20
tim.plunkettOnly the smallest of nitpicks:
"Constructs a new WideModalRenderer." and needs a blank line.
The rest looks great.
Comment #21
tedbow@tim.plunkett thanks for review!
Fixed
Comment #22
GrandmaGlassesRopeManI don't think we need this file.
Or this file.
Comment #23
tedbow@drpal thanks. yes let over from the patch command.
Comment #25
tedbowI messed up reroll in #23. Needed manual reroll because of #2880007: Auto-fix ESLint errors and warnings
Comment #26
Wim LeersNit: Missing trailing period.
Nit: 80 cols.
This must be named
OffCanvasRenderer
.s/render/main content renderer/
Looks good.
For consistency with the existing ones:
Why is this not extending
ModalRenderer
?Nit: Needs blank line in between.
Interesting way of testing this, seems sound.
Comment #27
GrandmaGlassesRopeMan- #26.1,2,3,4,5,6,8,9 👍
- #26.7 🤷♀️
- Fixed an issue with two missing variables that were accidently removed in #21/#23,
search
&replace
- Simplified
Drupal.ajax.instances
filter.Comment #28
tim.plunkettThis is still wrong, needs to be something like "Constructs a new WideModalRenderer." and also there is now a trailing whitespace on the blank line
Comment #29
tedbow#26.3 The class file still needed to be renamed.
#26.7 fixed
#26.8 and #28 fixed.
Comment #32
tedbowFixed failure.
Actually the variables were removed on purpose but the line referencing them should have also been removed.
Comment #33
Wim LeersOne nit, one question.
Nit: Must fit on single line.
Why is this still called "off canvas renderer"? Isn't that a remnant from when this module was called
off_canvas.module
?Is the plan to move this into core itself, outside this module, once this module becomes stable?
Comment #34
GrandmaGlassesRopeMan@Wim Leers
#33.1 - Really?
Comment #35
Wim Leers"Nit".
It's a coding standard rule we have. Maybe that changed with the shift to ES6? Not clear to me. Anyway, just a nit — should not hold up commit.
Comment #36
tedbow#33.2
This will be moved into core dialog library in #2784443: Move off-canvas functionality from Settings tray module into drupal.dialog.ajax library so that other modules can use it
So it could be changed to OffCanvasDialogRenderer but I think that this is out of scope for this issue.
Also it follows the pattern of ModalRenderer though technically this is could also be called ModalDialogRenderer.
Modal and OffCanvas are both special kinds of dialogs.
Comment #37
droplet CreditAttribution: droplet commentedNo changes to ES6 as I known. It's same as PHP I think..
Comment #38
tedbowI just noticed that #33.1 referenced a comment that was actually an out of scope change introduced in #27
Reverting that change. I think shortening that comment could be complicated because I don't think it is actually a correct description and should be separate issue.
Comment #39
Wim Leers#36 Ok.
#38 Yay, that ends that yak shaving exercise immediately!
Comment #40
effulgentsia CreditAttribution: effulgentsia at Acquia commentedThis patch looks great. My only question is:
Why are we prefixing this with "drupal"? Why not just
element_settings.dialogRenderer
?Comment #41
effulgentsia CreditAttribution: effulgentsia at Acquia commentedAlso, I'm not entirely thrilled with the word "renderer" in the attribute name, because when I think of "what's rendering the dialog?", I think of
Drupal.dialog()
or jQuery UI'sdialog()
function, and the value of'data-dialog-renderer'
isn't changing that (it could in theory, depending on the implementation of the PHP service that binds to this, but the off_canvas "renderer" is using the same jQuery UI dialog() function for client-side rendering that the base dialog type does). It's a "renderer" on the PHP side, but HTML attribute names and JS code are in the client-side world, and in that world, I don't see "off_canvas" as a separate renderer. Looks to me like it's more like a dialog "style", but we shouldn't use that word either, since that would lead people to think of CSS, rather than "style" in the more abstract sense.I can't think of a better word, so won't hold this up on that.
Comment #42
effulgentsia CreditAttribution: effulgentsia at Acquia commentedActually, for #41, what do you all think of "preset"? I.e.,
"data-dialog-preset" => "off_canvas"
? I don't know if that helps to clarify or not, so feel free to shoot it down.Comment #43
tim.plunkettThat machine name corresponds to a class that implements \Drupal\Core\Render\MainContent\MainContentRendererInterface, which says
Example classes, and their corresponding machine name
drupal_ajax => \Drupal\Core\Render\MainContent\AjaxRenderer
drupal_modal => \Drupal\Core\Render\MainContent\ModalRenderer
drupal_dialog => \Drupal\Core\Render\MainContent\DialogRenderer
drupal_dialog_off_canvas => \Drupal\outside_in\Render\MainContent\OffCanvasRender
Comment #44
effulgentsia CreditAttribution: effulgentsia at Acquia commentedRight, per #41, that's PHP-centric. But we're talking about a name for an HTML attribute and JS variable. How that's connected back to PHP is an implementation detail.
Comment #45
tedbowFixes #40
I think we I added this was thinking of things like `dialogOptions.drupalAutoButtons` but dialogOptions is different because it is options passed to Jquery Ui dialog and so prefix drupal specific things.
That is not need here.
Comment #46
tim.plunkettThanks @tedbow!
Comment #47
tedbowRe #41 while I do think preset might be better word for what this being used for in the off-canvas example. This feature will potentially allow a module provide dialog system alongside core's that uses a totally different JS library so renderer I think portrays more the potential of what it could be used for.
Comment #48
effulgentsia CreditAttribution: effulgentsia at Acquia commentedThanks for #45, and I see your point in #47, so I'm about to commit this. Ticking credit boxes for reviewers.
Comment #50
effulgentsia CreditAttribution: effulgentsia at Acquia commentedPushed to 8.4.x.
Comment #51
tedbow@effulgentsia thanks for review and committing!
@tim.plunkett, @drpal, @Wim Leers @droplet thanks for reviews!
Comment #52
effulgentsia CreditAttribution: effulgentsia at Acquia commentedThere might be a side effect to having committed this. ExceptionJsonSubscriber::getHandledFormats() has a hard-coded list of formats.
drupal_dialog.off_canvas
isn't one of them, so errors within such a request might not get handled/formatted correctly. This could use a follow-up issue for solving.Comment #53
Wim Leers#52 Wow, great catch!