Keysave: A Step Towards A More Intuitive Admin UX

By mandclu, Sun, 12/11/2022 - 13:33
Command key on a Mac keyboard

One of my early Drupal mentors, Khalid Baheyeldin, used to say that a big part of the value of working with open source software is the freedom to scratch your own itch. And if, as a community, we pool those improvements, we can have free software that's always evolving and getting easier to use.

I was recently setting up a headless Drupal site, which requires more than the usual amount of switching between the Drupal web UI and my IDE, for configuration yml files and templates. Occasionally when doing this kind of back-and-forth I get used to the command-s key combination for saving changes and will accidentally use it in the Drupal admin UI. On this particular occasion I had done it couple of times. As I waited in frustration for the browser's Save dialog to slide open and then slide closed, I wondered if there was a way to suppress this dialog, since it must be a rare time where it's actually useful to save a page from the backend interface. Or could Drupal be made to use this common key combination to actually work as intended, and save forms?

I had seen lots of web applications that intercept these kinds of key commands, with the particular example of command-enter as a near-ubiquitous way to submit chat and similar forms that accept multiline input.

But is this a good idea? Postel's Law (aka the Robustness Principle) suggests "be conservative in what you do, be liberal in what you accept from others." Within the context of a CMS admin UI, it's reasonable to assume the intent of a command-s or control-s key combination isn't really to save the page to local file on the user's computer, which is the browser default. Allowing the CMS to accept this as a way to submit the current form is a UX win and helps make the application more intuitive to use.

A quick proof-of-concept (POC) showed that what I wanted was indeed possible. A small JavaScript library could listen for the appropriate key combination and use it to submit the form. I decided to check for both command-s and control-s so it benefits users from different operating systems.

The POC attached the library to node forms, but I realized that if I could attach it to forms that extend the ConfigFormBase and EntityForm classes, I could add it to a wide swath of Drupal admin forms without much code. During some testing I identified some outliers where I wanted this capability, namely the module and permissions forms, and added checks to target them specifically.

I also had to decide whether to target the form's submit method directly, or use JavaScript to trigger a click on the submit button. I decided that the latter was less likely to accidentally bypass any existing submit or click handler, and targeted the button using its data-drupal-selector value of "submit". This turned out to work across most forms where I wanted this to work, but I did find a few outliers, so a couple of additional checks seem to satisfy the rest.

The last substantial gap was working within CKEditor WYSIWYG widgets. Because the user is actually working within a separate page iframed into the admin form, event handlers on the main form don't fire. I couldn't find a lot of reference on how add an event listener to a CKEditor widget without writing a plugin. Eventually I discovered that the Gin admin theme has some working code that is an excellent reference. With that code adapted (and simplified) for what I needed to do, I now had a functionally complete version of what I wanted to accomplish.

The Path Forward

I tried to test the new functionality across a wide variety of admin forms on a fairly clean Drupal site, with a few modules installed. It's entirely possible that gaps will come to light, and additional selectors will need to be added, or even a need to define exceptions (where it shouldn't be added).

On that note, if it seems as though sites need to customize where this be added, I could also add a configuration page. There could also be an option to customize what data-drupal-selector values to check when selecting the submit button to target.

Another possibility is that Keysave will need to be be updated to work better with other contrib modules. An obvious example is the Paragraphs module, which I don't personally use often, but is very popular and adds its own JavaScript to a number of entity forms.

A Small Step Forward?

The change introduced by Keysave is minor, but has successfully smoothed a point of friction in my own experience working with Drupal. The command-s key combination is one of the ones I have the most muscle memory built up to use, so navigating to edit a piece of content or a site configuration form, making a change, and then quickly saving it, now feels a little bit, but appreciably easier. I hope other sites and their users will find it helpful too.

I'd love to hear what the rest of the community thinks about this. Do you find it valuable? Did it create problems on your site? Do you have ideas on how it could be better? Reach out or open an issue on the module!



Restricted HTML

  • Allowed HTML tags: <a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • Lines and paragraphs break automatically.
  • Web page addresses and email addresses turn into links automatically.