Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[4.0][RFC] Custom Element: Joomla! Toolbar button #19635

Closed
wants to merge 28 commits into from

Conversation

Fedik
Copy link
Member

@Fedik Fedik commented Feb 10, 2018

This is sketch of <joomla-toolbar-button/>.
It allow us to move most of inline onclick="" to separate file.

screen 2018-02-10 14 45 05 1159x125

From JavaScript side it mostly ready, but PHP require some more editing.

Any thoughts, is it need?

ping @dgt41 @C-Lodder

@joomla-cms-bot joomla-cms-bot added PR-4.0-dev RFC Request for Comment labels Feb 10, 2018
@dgrammatiko
Copy link
Contributor

dgrammatiko commented Feb 10, 2018

@Fedik one thing that would be awesome to implement is hide/show buttons depending on the selected rows of the list view. I started working on that idea so maybe something helpful there: https://github.com/joomla/joomla-cms/compare/4.0-dev...dgt41:§4.0-dev-toolbar-cleanup?expand=1

PS And yes this is needed to achieve CSP strict mode! Great stuff


if (form.boxchecked.value == 0) {
perform = false;
Joomla.renderMessages({'error': [Joomla.JText._('JLIB_HTML_PLEASE_MAKE_A_SELECTION_FROM_THE_LIST')]});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how about: this.setAttribute('hidden', true); instead of the stupid alert?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Of course you need a way to exclude buttons from the hide/show behaviour (eg new, options, etc)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for now it just keeps an old logic

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine let's do this in steps...

@brianteeman
Copy link
Contributor

One issue with the current code we are using is that the "icon" name is tied to the button id. So for example in the sysinfo there is an a11y fail as the id is the same on both buttons because the icon is the same. it would be good if that could be avoided with this new code

@Fedik
Copy link
Member Author

Fedik commented Feb 10, 2018

would be awesome to implement is hide/show buttons depending on the selected rows of the list view

that also would be cool,
but it another complex task, I think will be better to separate this to 2 task, it more easy to test, and sync in case of conflict

@dgrammatiko
Copy link
Contributor

@Fedik one more thing about accessibility:
It would be better if you create a button element and put the contents of the ce in there (button.innerHTML = this.innerHTML).
The reason is that custom elements in fact are like span elements and since we want here to have all the good browser built in accessibility for buttons is better to create a button instead of manually patch the keyboard and mouse behaviours. To make this more clear try to tab to the buttons or enter/space when selected, we're missing crucial functionality here ;)

@Fedik
Copy link
Member Author

Fedik commented Feb 10, 2018

@dgt41 good point,
hmm, I think tabindex="0" will do the work also, or?
because I not very like the idea of using these "extra wrappers" 😉

need to check

@dgrammatiko
Copy link
Contributor

dgrammatiko commented Feb 10, 2018

well it's not only tabindex you need to patch the key listeners as well. Basically because custom element extends HTMLElement just extending the base Html element there is no special functionality there. In v0 of ce you could extend other elements like class Something extends HTMLButtonElement, but I think this doesn't work anymore with v1


// If list selection are required, set button to disabled by default
if (this.listConfirmation) {
button.setAttribute('disabled', 'disabled');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

button.setAttribute('disabled', true);

Joomla.submitbutton(this.task, form, this.formValidation);
// Check whether we have selected something
if (this.formElement.boxchecked.value == 0) {
this.buttonElement.setAttribute('disabled', 'disabled');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

button.setAttribute('disabled', true);

@Fedik
Copy link
Member Author

Fedik commented Feb 11, 2018

@brianteeman the issue with non-unique ID is fixed

@dgt41 any idea why the link button use <button onlick="bla/link"> instead of a <a href="bla/link">?

* @param boolean $list True to allow lists
* @param boolean $group Does the button belong to a group?
*
* @param string $form The form CSS selector eg '#adminForm'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove extra tab

@@ -465,37 +465,44 @@ public static function trash($task = 'remove', $alt = 'JTOOLBAR_TRASH', $check =
*
* @param string $task An override for the task.
* @param string $alt An override for the alt text.
* @param boolean $group True or false
*
* @param string $form The form ID
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove extra tab

@dgrammatiko
Copy link
Contributor

@Fedik I guess the href attribute wasn't used due to the alert that had to be triggered if the link was referring to a list row element and no row element was selected...

@Fedik
Copy link
Member Author

Fedik commented Feb 11, 2018

@dgt41 hmm, no should be something diferent, because the link not require a list selection:

screen 2018-02-11 15 41 32 1067x116

I could change it to simple <a href=""> tag, and it will work in same way.
But maybe there was a reason why we have a <button> there, something with a11y?

@asika32764
Copy link
Contributor

Just reference I create a PR #19670 to handle the php side.

asika32764 added a commit to asika32764/joomla-cms that referenced this pull request Feb 16, 2018
asika32764 added a commit to asika32764/joomla-cms that referenced this pull request Feb 16, 2018
@dgrammatiko
Copy link
Contributor

dgrammatiko commented Feb 17, 2018

@Fedik one more thing here, a few months back I implemented a shortcut key handler for CTRL( or CMD)+S. That code somehow disappeared in some sync of the repos but you can check it here: joomla/40-backend-template#55. So it would be cool to have it back, probably it needs some changes as the codebase progressed a bit since

@C-Lodder
Copy link
Member

@dgt41 I swear you've added that feature like 4 times now

@Fedik
Copy link
Member Author

Fedik commented Feb 18, 2018

@dgt41 I have restored "control+s"

However if we can use one of these:
https://github.com/RobertWHurst/KeyboardJS
https://github.com/ccampbell/mousetrap
then I can integrate keyboard combos (shortcuts) to JoomlaToolbarButton (instead of hardcoding in core.js) that will allow to add own combos (one or multiple) to each toolbar button, in theory.

document.addEventListener( 'DOMContentLoaded', function() {
if (Joomla.getOptions( 'keySave' ) ) {
document.addEventListener("keydown", function(e) {
if (e.keyCode == 83 && (navigator.platform.match("Mac") ? e.metaKey : e.ctrlKey)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dgrammatiko
Copy link
Contributor

dgrammatiko commented Feb 18, 2018

@Fedik the code was in core.js because we didn't have a toolbar.js or had a clue that custom elements was going to be part of J4 back then. Now the approach should be a little different IMHO:
in the CE before the class define a const like:

	const keyboardSpecialKeys = (key, modifier, task) => {
if (modifier === 'control') { modifier = (navigator.platform.match("Mac") ? e.metaKey : e.ctrlKey); }
		document.addEventListener("keydown", function(e) {
			if (e.key === key && e.key === modifier ) {
				e.preventDefault();
				Joomla.submitbutton(task); // Pretty sure we can use submitForm here
			}
		}, false);
	}

in the class connectedCallback function:

keyboardSpecialKeys(83, 'control', 'article.save')

Or you can use this.keyboardSpecialKeys(...) if you get the function inside the class as another option.
The main point is that this functionality is tightly connected to the buttons (crtl+s is for save, but we can introduce more later) so I think the whole code should be in the custom elements.

@dneukirchen
Copy link
Contributor

dneukirchen commented Feb 24, 2018

I would not put too much stuff into this.
We can always add shortcuts and bonus stuff later.

But we should improve this a little:

  • There is no need to put the listselection logic INSIDE the custom element. This knowledge belongs in the outside world. A <joomla-toolbar-button> is - depending on those or other outside conditions - either disabled, expanded, hidden or whatever. Imagine a "merge" button which merges 2 db entries. With the current implementation the button gets enabled when at least one item in the list is checked, which makes no sense. There is also no need to show the ugly alert to the user when he clicks a button he should not be able to click at all. UI should indicate (hidden/disabled) the state.

  • Something similar is true for the confirm attribute. Its not flexible enough. Perhaps we should put this into another element like <joomla-confirm-toolbar-button>? Or implement some onBeforeSubmit callback, where we can (later) replace the ugly browser confirm with a more user-friendly, modern confirmation dialog? Still new to custom elements and i dont know whats possible. Not that i expect you to implement a modern confirm dialog in this PR, but i think putting the confirm INSIDE the custom element is not flexible enough to fulfill the requirements of modern UIs.

  • I dont like that the toolbar button is coupled to a form and especially the form validation... The formvalidation should not depend on an attribute of a toolbar button... Could be also a candidate for an onBeforeSubmit Callback / Event (see above)... ?

@Fedik
Copy link
Member Author

Fedik commented Mar 3, 2018

There is no need to put the listselection logic INSIDE the custom element

I think it is fine,
but if there a better solution, then it can be better 😄

Imagine a "merge" button which merges 2 db entries

There could be 3 db entries 😉
for it we can make <joomla-toolbar-button list-selection="3"/> or <joomla-toolbar-button list-selection="some fancy condition"/>
But it require extra work, and clear decision.

There is also no need to show the ugly alert to the user when he clicks a button he should not be able to click at all. UI should indicate (hidden/disabled) the state.

That actually what we have here disabled state 😉

Perhaps we should put this into another element like ? Or implement some onBeforeSubmit callback, where we can (later) replace the ugly browser confirm with a more user-friendly, modern confirmation dialog?

I would not do a Zoo of "toolbar-buttons" which on 90% will be copy of each other.
Technically <joomla-toolbar-button/> is a wrapper around Joomla.submitbutton which is made to be overridden by extension developer. So technically it is onBeforeSubmit callback 😉

I dont like that the toolbar button is coupled to a form and especially the form validation...

It is not very coupled.
There just a marker/flag which passed to Joomla.submitbutton that say "I would like to validate the form". But the validation is in Joomla.submitbutton, or where developer decide.
It allow to avoid hard-coding, like we have:
if ((task == 'cancel' ) || document.formvalidator.isValid( form))

$group = $displayData['group'];
$task = '';
$list = !empty($displayData['list']) ? ' list-selection' : '';
$form = !empty($displayData['form']) ? ' form=' . $displayData['form'] . '"' : '';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing " after form=?

@wilsonge
Copy link
Contributor

I've merged the PHP API Updates which of course has made this blow up with conflicts. Can we get this back in sync

@Fedik
Copy link
Member Author

Fedik commented May 14, 2018

I will check

@Fedik
Copy link
Member Author

Fedik commented Jun 2, 2018

I made new one, please check there #20650

@Fedik Fedik closed this Jun 2, 2018
@Fedik Fedik deleted the toolbar-button branch June 13, 2018 16:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
RFC Request for Comment Unit/System Tests
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants