? Feature NPM Resource Changed PR-5.0-dev Pending

User tests: Successful: Unsuccessful:

avatar Fedik
Fedik
18 Mar 2023

Summary of Changes

This is implementation of own popup/modal/dialog independend from bootstrap and other traps.
As continue of #32473 discussion.

At current point of time the PR provides only popup implementation, the script should be ready to use.
And the integration will come.

I made it for 4.x to be able easily test on "production" codebase. However main target (If I ever finish it) probably > 5.x.

The PR does not provide a separate stylesheet for popup, the styling should be done within template (example can find in _modal.scss of this PR).
(At bare it use native dialog styling)

What and why is Joomla Dialog

The script allow to create a popup/dialog programaticaly, that in oposite to current Bootstrap implementation, when modal should be prerendered in HTML. This allows more simple integration on client side without involving server side.

It basicaly a wrapper around native dialog element.

Joomla Dialog script allows to display dialog with following content:

  • inline - text or html content;
  • iframe - embed/remote content, in iframe;
  • ajax - same as inline but the content loaded through ajax request;
  • image - image lightbox;

Also it provides helper methods for alert() and confirm() dialogs.
Provides helper to bind page button/anchor to show the popup, for basic stuff, without extra js needed.

Usage examples

<?php $wa->useScript('joomla.dialog'); ?>
// Inline 
const dialog = new JoomlaDialog({
  textHeader: 'The header',
  popupContent: '<p class="p-3">Popup content text</p>',
});
dialog.show();

// IFrame
const dialog = new JoomlaDialog({
  popupType: 'iframe',
  textHeader: 'The header',
  src: 'index.php?option=com_content&view=articles&tmpl=component&layout=modal',
});
dialog.show();

// Ajax
const dialog = new JoomlaDialog({
  popupType: 'ajax',
  textHeader: 'The header',
  src: 'index.php?option=com_content&view=articles&tmpl=component&layout=modal',
});
dialog.show();

// Image
const dialog = new JoomlaDialog({
  popupType: 'image',
  src: '../images/headers/walden-pond.jpg',
});
dialog.show();

Any property can be set as instance property or in class constructor. This two is equal:

// Proprty in class constructor
const dialog = new JoomlaDialog({
  textHeader: 'The header',
  popupContent: '<p class="p-3">Popup content text</p>',
});

// Proprty in to class instance
const dialog = new JoomlaDialog();
dialog.textHeader = 'The header';
dialog.popupContent = '<p class="p-3">Popup content text</p>';

Other options:

// Optional sizing:
dialog.width = '80vw';
dialog.height = '80vh';

// Definig your own buttons:
dialog.popupButtons = [
  { label: 'Yes', onClick: () => dialog.close() },
  { label: 'No', onClick: () => dialog.close(), className: 'btn btn-outline-danger ms-2' },
];

Alert and Confirm usage:

// Alert
JoomlaDialog.alert('Chase ball of string eat plants, meow')
  .then(() => { 
    console.log('All done'); 
  });

// Confirmation
JoomlaDialog.confirm('Cheese on toast airedale the big cheese?')
  .then((result) => { 
    console.log(result ? 'Okay' : 'Not okay'); 
  });

Binding button/anchor for basic stuff

<?php $wa->useScript('joomla.dialog-autocreate'); ?>

<button class="btn btn-primary" type="button"
    data-joomla-dialog='{"popupType": "iframe", "width":"80vw", "height": "80vh", "src":"index.php?option=com_content&view=articles&tmpl=component&layout=modal"}'>Click</button>

<button class="btn btn-primary" type="button"
    data-joomla-dialog='{"popupType": "inline", "src":"#popupText", "width": "fit-content", "height": "fit-content"}'>Click</button>

<a href="index.php?option=com_content&view=articles&tmpl=component&layout=modal"
  data-joomla-dialog class="btn btn-outline-primary">Click</a>
<a href="#popupText" data-joomla-dialog class="btn btn-outline-primary">Click</a>

<template id="popupText"><p class="p-3">Popup content text</p></template>

Testing Instructions

Can test any of examples above.
Apply patch, run npm install.
Then add $wa->useScript('joomla.dialog'); in to index.php of the admin template.
And one of example js/html wherever you want. Eg. in to index.php (will show 2 popup on load):

<script type="module">
import JoomlaDialog from 'joomla.dialog';

JoomlaDialog.alert('Chase ball of string eat plants, meow')
  .then(() => { 
    console.log('All done'); 
  });

JoomlaDialog.confirm('Cheese on toast airedale the big cheese?')
  .then((result) => { 
    console.log(result ? 'Okay' : 'Not okay'); 
  });
</script>

Link to documentations

Please select:

  • Documentation link for docs.joomla.org: TBD
  • Pull Request link for manual.joomla.org: joomla/Manual#99

Issues for reference

@dgrammatiko I have stole some of your ideas from #39344, I hope you will not sue me :)

avatar Fedik Fedik - open - 18 Mar 2023
avatar Fedik Fedik - change - 18 Mar 2023
Status New Pending
avatar joomla-cms-bot joomla-cms-bot - change - 18 Mar 2023
Category Repository NPM Change JavaScript
avatar dgrammatiko
dgrammatiko - comment - 18 Mar 2023

LGTM

I left couple of comments on insertAdjacentHTML but also before this goes to production it needs the dialog polyfill, you can copy over the code from https://github.com/dgrammatiko/joomla-modal/blob/main/src/index.js and add the package in the package.json (https://github.com/GoogleChrome/dialog-polyfill)

avatar Fedik
Fedik - comment - 18 Mar 2023

also before this goes to production it needs the dialog polyfill,

At time when it will happen, we will be no need polifill ?
Well, yeah sure, can be added, but as last thing here, not really important for now.

avatar dgrammatiko
dgrammatiko - comment - 18 Mar 2023

Well, yeah sure, can be added, but as last thing here, not really important for now

Sure, so apart the innerHML part everything else are spot on on what we had discussed. Maybe the anchor shouldn't be included, for a11y reasons, ie: the dialog should be opened from a button but that's bikeshedding that someone else should do.

I will try to play a bit with it tomorrow but I think it's already in very good shape

avatar Fedik Fedik - change - 18 Mar 2023
Labels Added: ? NPM Resource Changed PR-4.3-dev
avatar dgrammatiko
dgrammatiko - comment - 18 Mar 2023

@Fedik one little change: could you rename this to JoomlaDialog and all the instances of popup to dialog? The reason is that later this year the platform will have (already on chrome) the popover so this should be easily distinguishable

avatar Fedik
Fedik - comment - 18 Mar 2023

I see, makes sense, yes I will rename

avatar Fedik Fedik - change - 19 Mar 2023
Title
[RFC] Joomla Popup script. Free, without CC and registration
[RFC] Joomla Dialog (popup) script. Free, without CC and registration
avatar Fedik Fedik - edited - 19 Mar 2023
avatar Fedik Fedik - change - 19 Mar 2023
The description was changed
avatar Fedik Fedik - edited - 19 Mar 2023
avatar dgrammatiko
dgrammatiko - comment - 20 Mar 2023

@laoneo could we have a decision for 4.4 here? This PR will unlock the fixes needed all around the broken repeatables, modal fields, etc
There's an actual implementation for the fields User and Media here: #40152

avatar laoneo
laoneo - comment - 20 Mar 2023

@dgrammatiko what for a decisions you expect? If this can go into 4.4? As @Fedik already mentioned in the pr description, this should finally be merged into 5.0 as 4.4 will not get any new features.

avatar dgrammatiko
dgrammatiko - comment - 20 Mar 2023

So 4.3 was the last minor that had new features? Well, ?

avatar laoneo
laoneo - comment - 20 Mar 2023

What is the problem to ship it with 5.0? They will be released at the same time.

avatar dgrammatiko
dgrammatiko - comment - 20 Mar 2023

What is the problem to ship it with 5.0? They will be released at the same time.

I guess some dev will be complaining, like the did with the WAM, that they need 2 different code snippets in order to support both v4 and v5...

avatar laoneo
laoneo - comment - 20 Mar 2023

As long as the old way still works, they should then use that. And yes, when they want the new dialog/popup/modal, then they need to have different code which is dependent on the Joomla version. I don't see this as a big issue.

avatar dgrammatiko
dgrammatiko - comment - 20 Mar 2023

As long as the old way still works, they should then use that.

The old way (bootstrap) works but devs SHOULD NOT use them for fields, editor buttons, etc that are already broken right now because this approach is doing SSR (Server Side Rendering) of the modals which are incompatible with repeatable fields. Same goes for the category fields for different reason. My point is that the script should be introduced in the 4.x so the transition would be easier...

avatar Fedik
Fedik - comment - 20 Mar 2023

I think 5.x+ is fine, maybe we will get some better ideas untill then.
And I would like to finish #40082 before this, and try different approaches for (cross)editor buttons.

avatar dgrammatiko
dgrammatiko - comment - 20 Mar 2023

And I would like to finish #40082 before this, and try different approaches for (cross)editor buttons.

I was thinking doing the first implementation with the buttons based on this PR and the #40082 but it needs also extending the Joomla.editors to have something like

Joomla.editors = {
  instances: {},
  buttonsCallbacks: {
    ['plg_editors-buttons_readmore']: () => { /* the code for the callback */ },
  },
}
avatar Fedik
Fedik - comment - 20 Mar 2023

I thinking about something generic, that can handle basic stuf without extra coding, and allow to be extended when needed.

avatar dgrammatiko
dgrammatiko - comment - 20 Mar 2023

I thinking about something generic, that can handle basic stuf without extra coding, and allow to be extended when needed.

My idea for the editor buttons was:

  • create a new plugin group, ie editor-buttons and for J4/5 check both, with J6 only editor-buttons would exist
  • The plugin instead of returning a php object (CMSObject) would just register the buttons in the Joomla.editors as a JS object { name, icon, etc }
  • The plugin would register the onClick function on the Joomla.editors
  • The plugin would also return true on the PHP side if the plugin is enabled on the particular instance of the editor
  • The editor should render (client side) the buttons and bind either the modal or the onClick

This way on every repeatable instance the buttons will work as expected (the editor init function has the responsibility to handle those, ie: tiny will render them inside a toolbar but others could/would render them bellow the editing area)

avatar laoneo
laoneo - comment - 20 Mar 2023

Didn't look to deep into the code, but is it possible to adapt the output of a modal with a template override as you can do now with the BS ones?

avatar Fedik
Fedik - comment - 20 Mar 2023

Didn't look to deep into the code, but is it possible to adapt the output of a modal with a template override as you can do now with the BS ones?

It does not depend from server layout anymore. Pure "client side", almost.
Here you still can customise popup template, but in 99.99% you will be no need it.

avatar dgrammatiko
dgrammatiko - comment - 20 Mar 2023

is it possible to adapt the output of a modal with a template override as you can do now with the BS ones?

You could use a <template> element with some HTML and have the modal initiator script pick the parts (Header, body, footer) and use them. The problem with all the Fields but also with other parts of the CMS is that you end up with repeated HTML fragments. There was once a PR that could solve this with a deferred renderer #37330

avatar laoneo
laoneo - comment - 20 Mar 2023

It does not depend from server layout anymore.

This does mean, it doesn't follow our current way of doing, that output is generated in a specific layout file. I'm not sure if all people will be happy with this. Just want to point that out. I'm not against the new approach, but it should then be documented somehow.

avatar dgrammatiko
dgrammatiko - comment - 20 Mar 2023

I'm not sure if all people will be happy with this. Just want to point that out.

They can still use BS Modal this PR is NOT replacing the BS Modal script, the latter is still available.
For highly interactive elements (Fields, repeatable, etc) the pre-rendered html just doesn't scale/work so it needs to be abandoned and switch to client side rendering (btw the media manager has also 0 lines of php layouts and there are other instances, so the assumption that Joomla\s current way is exclusive SSR is a lie). On the other hand the project could keep everything broken because people think that it's a heresy to have client side rendered elements...

avatar Fedik Fedik - change - 26 Mar 2023
Labels Added: PR-4.4-dev
Removed: PR-4.3-dev
avatar Fedik Fedik - change - 26 Mar 2023
The description was changed
avatar Fedik Fedik - edited - 26 Mar 2023
avatar laoneo
laoneo - comment - 30 Mar 2023

I guess it is better to rebase this pr to the 5.0-dev branch, as it will get more attention for new features. Thanks for understanding.

avatar Fedik Fedik - change - 30 Mar 2023
The description was changed
avatar Fedik Fedik - edited - 30 Mar 2023
avatar Fedik Fedik - change - 2 Apr 2023
The description was changed
avatar Fedik Fedik - edited - 2 Apr 2023
avatar Fedik Fedik - change - 2 Apr 2023
The description was changed
avatar Fedik Fedik - edited - 2 Apr 2023
avatar HLeithner
HLeithner - comment - 7 Apr 2023

@Fedik can you rewrite/change a joomla action (maybe com_content modal select field) so I can have a better feeling how this works with the joomla code base?

I expect you only have to change the layout of the field right?

avatar dgrammatiko
dgrammatiko - comment - 7 Apr 2023

@HLeithner try this #40152

avatar HLeithner
HLeithner - comment - 7 Apr 2023

@HLeithner try this #40152

this looks really complex for using a simple popup/modal?!

avatar dgrammatiko
dgrammatiko - comment - 7 Apr 2023

this looks really complex for using a simple popup/modal?!

@HLeithner not really, these 2 fields have a dependency on the BS Modal as of 4.3.0. The changes to convert them to the new one are not complex but maybe this is not the easiest example. The easiest example would be some toolbar popup button, where the code would be significantly less or some of the move/copy buttons (eg banners, articles, etc). I'm quite busy atm to code such an example, but for what is worth, this approach of the modals has my support (it's an iteration/improvement of my exploratory PR and according to the specs that were set in the discussion). In sort it's a step forward, it eliminates a number of existing XSS and it's a better fit for the project as it's tailored to the actual needs...

avatar Fedik
Fedik - comment - 7 Apr 2023

If you remamber SqueezeBox from < joomla 2.5, that will be similar.

I expect you only have to change the layout of the field right?

For basic stuff yes.
But, for make it "good" there also will be need some JS changes.

That one #40202 based on current pr, it uses new popup for all XTD buttons (except media).

// Display modal dialog
JoomlaEditorButton.registerAction('modal', (editor, options) => {
if (options.src) {
// Replace editor parameter to actual editor ID
const url = options.src.indexOf('http') === 0 ? new URL(options.src) : new URL(options.src, window.location.origin);
url.searchParams.set('editor', editor.getId());
if (url.searchParams.has('e_name')) {
url.searchParams.set('e_name', editor.getId());
}
options.src = url.toString();
}
const popup = new JoomlaDialog(options);
popup.addEventListener('joomla-dialog:close', () => {
Joomla.Modal.setCurrent(null);
popup.destroy();
});
Joomla.Modal.setCurrent(popup);
popup.show();
});

This is shared "modal" action, for XTD buttons, that replaces layouts/joomla/editors/buttons/modal.php which rendered for every modal button.

avatar Fedik
Fedik - comment - 7 Apr 2023

rewrite/change a joomla action (maybe com_content modal select field)

com_content "modal select" field is pretty complex field,
that is heavily coupled with horror inside media/system/js/fields/modal-fields.js
Would be a bad example ?

This will probably require multiple steps for updated that.

avatar dgrammatiko
dgrammatiko - comment - 7 Apr 2023

This will probably require multiple steps for updated that.

It can be in one step but the PHP side of the code introduces B/C breaks: #39351

But, yeah, that's the worst example for showcasing the modals ?

avatar Fedik Fedik - change - 7 Apr 2023
The description was changed
avatar Fedik Fedik - edited - 7 Apr 2023
avatar Fedik Fedik - change - 7 Apr 2023
Labels Added: ? PR-5.0-dev
Removed: PR-4.4-dev
avatar Fedik Fedik - change - 7 Apr 2023
The description was changed
avatar Fedik Fedik - edited - 7 Apr 2023
avatar Fedik
Fedik - comment - 7 Apr 2023

@HLeithner Here is simpliest example that I found :)
5.0-dev...Fedik:joomla-cms:popup-guidedtour-viewall

Replacing modal for "Show all tours".

avatar Fedik Fedik - change - 8 Apr 2023
The description was changed
avatar Fedik Fedik - edited - 8 Apr 2023
avatar Fedik
Fedik - comment - 10 Apr 2023

@HLeithner there I tried more simple example #40359 :)

avatar HLeithner
HLeithner - comment - 10 Apr 2023

thanks, I tried this pr and on the second click it was broken (guidedtour branch) ;-) you can't open a popup again.
Also in the guided tour plugin you removed the code that handles the tab-path out of modal

avatar Fedik
Fedik - comment - 10 Apr 2023

you can't open a popup again

Yes there was a bug in Dialog script, I have fixed that, in one of last commits here. You probably have to re-run 'npm' on new changes.

Also in the guided tour plugin you removed the code that handles the tab-path out of modal

We do not need it anymore with Dialog, just try, the "tab" should work as usual.

avatar Fedik Fedik - change - 10 Apr 2023
The description was changed
avatar Fedik Fedik - edited - 10 Apr 2023
avatar Fedik Fedik - change - 10 Apr 2023
The description was changed
avatar Fedik Fedik - edited - 10 Apr 2023
avatar Fedik Fedik - change - 12 Apr 2023
The description was changed
avatar Fedik Fedik - edited - 12 Apr 2023
avatar Fedik
Fedik - comment - 23 Apr 2023

@HLeithner there #40462 a prototype of what I have in mind for Modal_Article field (similar will be for Category, Menu and other Modal_x)

avatar Fedik Fedik - change - 23 Apr 2023
Title
[RFC] Joomla Dialog (popup) script. Free, without CC and registration
[5.0][RFC] Joomla Dialog (popup) script. Free, without CC and registration
avatar Fedik Fedik - edited - 23 Apr 2023
avatar Fedik Fedik - change - 6 May 2023
Labels Added: Feature
Removed: ?
avatar brianteeman
brianteeman - comment - 6 May 2023

every time I see this pr I wonder why we have an RFC about Credit Cards

avatar HLeithner
HLeithner - comment - 6 May 2023

every time I see this pr I wonder why we have an RFC about Credit Cards

pretty sure we need credit card support

avatar Flowman
Flowman - comment - 11 May 2023

Sorry to be late to the party. Is there a reason why we don't use the new dialog html element? https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog

avatar brianteeman
brianteeman - comment - 19 Jun 2023

From what I can tell this works as per the instructions

avatar Fedik
Fedik - comment - 2 Jul 2023

Is there a reason why we don't use the new dialog html element?

What do you suggest?

avatar HLeithner
HLeithner - comment - 11 Aug 2023

One question, shouldn't this be part of our Joomla Super Global Object/Namespace instead of the JoomlaDialog -> joomla.dialog?

avatar dgrammatiko
dgrammatiko - comment - 11 Aug 2023

One question, shouldn't this be part of our Joomla Super Global Object/Namespace instead of the JoomlaDialog -> joomla.dialog?

Actually the custom element should be exported (without being registered in the registry) and then whatever script needs the modal should import the script (using the importmaps) and have some code (pseudo) like:

import JoomlaDialog from 'Joomla-dialog';

if (!customElements.get('joomla-dialog')) {
  customElements.define('joomla-dialog', JoomlaDialog);
}

// code specific to the script...
avatar Fedik
Fedik - comment - 11 Aug 2023

JoomlaDialog -> joomla.dialog

JoomlaDialog is a class that represent a custom element in DOM, there no point to place it under Joomla.
It may live without Joomla very well (under some conditions).

It kind of <img>:

const img = new Image;
img.src = 'blabla.png';

But for <joomla-dialog>

Actually the custom element should be exported

I thought about it, but would keep it as 1 file, for now.
We can split it at any time, if there will be a real demand.

avatar dgrammatiko
dgrammatiko - comment - 11 Aug 2023

@Fedik re checking the code what I meant was:

  • keep it as one file
  • replace window.JoomlaDialog = JoomlaDialog; with export default JoomlaDialog;
  • add the script also as an importmap

So any other script that needs to construct a dialog will do:

import JoomlaDialog from 'Joomla-dialog';

const myDialog = new JoomlaDialog(someConfig);

// the rest...
avatar Fedik
Fedik - comment - 11 Aug 2023

hmhm, yeah that can work.
I just not sure if doing a registration of anything in DOM while doing import is a good idea.

avatar Fedik
Fedik - comment - 11 Aug 2023

I will do some tests, and probably will update the PR

avatar Fedik Fedik - change - 14 Aug 2023
The description was changed
avatar Fedik Fedik - edited - 14 Aug 2023
avatar Fedik
Fedik - comment - 14 Aug 2023

Okay, I made it as a module:

import JoomlaDialog from 'joomla.dialog';

const dialog = new JoomlaDialog();
dialog.textHeader = 'The header';
dialog.popupContent = '<strong>blabla very strong text</strong>';
dialog.show();

Any other sugestions/wishes before I update Manual PR?

avatar Fedik Fedik - change - 14 Aug 2023
The description was changed
avatar Fedik Fedik - edited - 14 Aug 2023
avatar Fedik Fedik - change - 14 Aug 2023
The description was changed
avatar Fedik Fedik - edited - 14 Aug 2023
avatar HLeithner
HLeithner - comment - 14 Aug 2023

2 things would be great.

  1. A css for frontend independen from the template because it's use less now in frontend
  2. footerText adding text or html to the left side of the footer (like the legend for codemirror)
  3. Maybe a backdrop?

I tested it and it works as expected.

avatar HLeithner
HLeithner - comment - 15 Aug 2023

hmm, I thought more on a css file I can use in my own frontend template as base and not only cassiopia, what do you thing?

avatar Fedik
Fedik - comment - 15 Aug 2023

By default it use a browser default styling for dialog.
I have fixed iframe sizing, now it pretty usable without extra css.

Backdrop also there, it is browser default.

About footerText. I not very want to overload with features, and keep it simple.
However it still possible to customize:

const dialog = new JoomlaDialog();
dialog.textHeader = 'The header';
dialog.popupContent = '<strong>blabla very strong text</strong>';
// Customise footer
dialog.getFooter().insertAdjacentElement('afterbegin', (() => {
  const el = document.createElement('div');
  el.innerText = 'Footer text';
  return el;
})());
dialog.getFooter().classList.remove('empty');
dialog.show();
avatar HLeithner HLeithner - change - 21 Aug 2023
Status Pending Fixed in Code Base
Closed_Date 0000-00-00 00:00:00 2023-08-21 07:43:32
Closed_By HLeithner
avatar HLeithner HLeithner - close - 21 Aug 2023
avatar HLeithner HLeithner - merge - 21 Aug 2023
avatar HLeithner
HLeithner - comment - 21 Aug 2023

thanks, I think it's a starting point, even if I would add a css which is (or could be) part of the webasset with a nicer styling

avatar coolcat-creations
coolcat-creations - comment - 4 Nov 2023

Does this issue have something to do with this topic here?

#42291


This comment was created with the J!Tracker Application at issues.joomla.org/tracker/joomla-cms/40150.

avatar Frank-MandarinFish
Frank-MandarinFish - comment - 19 Sep 2024

Hey, since JoomlaDialog is now a module script I think it would be useful to have a little section in the manual that shows how this class can be used in "classic" non-module scripts, as the import function can only be called from another module script. The current manual gives the impression you can use the JoomlaDialog class in any script.

For example static:

<script type="module">
    import JoomlaDialog from "joomla.dialog";
    window.JoomlaDialog = JoomlaDialog;    
</script>

Or dynamic:

async function run() {
  const JoomlaDialog = await import("joomla.dialog");
  dialog = new JoomlaDialog();
}

This comment was created with the J!Tracker Application at issues.joomla.org/tracker/joomla-cms/40150.
avatar fgsw
fgsw - comment - 21 Sep 2024

I think it would be useful to have a little section in the manual

@Frank-MandarinFish As far as i know everybody can contribute to the manual

Add a Comment

Login with GitHub to post a comment