HTML5 modal focus not working

Bringing your stacks to the web

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller, robinmiller

Post Reply
igalperry
Posts: 1
Joined: Thu Jan 17, 2008 1:28 am

HTML5 modal focus not working

Post by igalperry » Sun Jun 22, 2025 5:02 pm

Hi. I have a web standalone that uses modals. When opening a modal, the focused field looks like it is focused (there is an blinking insertion point), but it does not accept input until I click within it. Is there any way to fix this so that a click is not required before the focused field accepts input?

SWEdeAndy
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 324
Joined: Sat Aug 16, 2008 9:48 am
Contact:

Re: HTML5 modal focus not working

Post by SWEdeAndy » Mon Jun 23, 2025 9:26 pm

Hi igalperry,

Ouf, it took the better part of an evening to trouble-shoot that one, but I (and ChatGPT) FINALLY found a solution that seems to work well.

Only a physical tab key press seems able to actively shift the focus, and that can't be simulated as the browser prevents it. So it had to be a JavaScript function to force the focus onto the field.

Put this into a [hidden] field or in a custom property:

Code: Select all

(function() {
  var observer = new MutationObserver(function(mutations) {
    for (var m of mutations) {
      for (var node of m.addedNodes) {
        if (node.nodeType !== 1) continue;
        var canvas = node.querySelector && node.querySelector('canvas[data-lc-window-id]');
        if (canvas) {
          var container = canvas.parentElement;
          // Remove container tabindex
          if (container.hasAttribute('tabindex')) {
            container.setAttribute('tabindex', '-1');
          }
          // Enable & focus hidden input
          var txt = container.querySelector('input[type="text"]');
          if (txt) {
            txt.removeAttribute('disabled');
            txt.setAttribute('tabindex', '0');
            txt.style.opacity = '0';
            txt.style.width = '1px';
            txt.style.height = '1px';
          }
          // Ensure canvas focusable
          if (!canvas.hasAttribute('tabindex')) {
            canvas.setAttribute('tabindex', '0');
          }
          // Redirect container focus
          container.addEventListener('focus', function() {
            if (txt) txt.focus();
            else canvas.focus();
          }, true);
          // Directly focus the target now
          if (txt) txt.focus();
          else canvas.focus();
          // Optionally disconnect if only needed once:
          observer.disconnect();
          return;
        }
      }
    }
  });
  observer.observe(document.body, { childList: true, subtree: true });
})();
Then put this line right before the modal command like so:

Code: Select all

if the platform is "web" then do field "myJavaScriptField" as "JavaScript"
modal stack "myModalSubstack"
If the first card of the modal stack has an editable field, it should now have focus and accept key strokes without any click or tabbing.

Working example here: https://wheninspace.com/test/modal/
Andreas Bergendal
Independent app and system developer
Free LC dev tools: https://github.com/wheninspace
(WIS_WebDeployHelper, WIS_ScriptDependencies, WIS_BrowserAnimation)
WhenInSpace: https://wheninspace.com

SWEdeAndy
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 324
Joined: Sat Aug 16, 2008 9:48 am
Contact:

Re: HTML5 modal focus not working

Post by SWEdeAndy » Mon Jun 23, 2025 9:34 pm

SWEdeAndy wrote:
Mon Jun 23, 2025 9:26 pm
Working example here: https://wheninspace.com/test/modal/
Ha, well, yeah, working in Firefox and Safari on Mac, and Safari on iOS. NOT working in Chrome on Mac.
So we're not quite done with this one yet.
I'll be back! :)
Andreas Bergendal
Independent app and system developer
Free LC dev tools: https://github.com/wheninspace
(WIS_WebDeployHelper, WIS_ScriptDependencies, WIS_BrowserAnimation)
WhenInSpace: https://wheninspace.com

SWEdeAndy
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 324
Joined: Sat Aug 16, 2008 9:48 am
Contact:

Re: HTML5 modal focus not working

Post by SWEdeAndy » Tue Jun 24, 2025 9:58 pm

OK, now I have updated code that works in all tested browsers (Firefox, Safari, Chrome).
You can copy it directly from here: https://wheninspace.com/test/modal/
Implement it as in my first post.

Note though, that modal generally does not work as expected in web deployment. The modal mode is supposed to block any interaction with any other stack until the modal stack is closed, but it does not behave that way on web. You can still click controls in the parent stack. Also, if the parent stack has an editable field, the JavaScript hack to focus on the field in the modal stack does not work.

For future reference, here is the updated JavaScript code:

Code: Select all

(function(){
  // Only run this once per page load
  var observer = new MutationObserver(function(mutations, obs){
    for (var m of mutations) {
      for (var node of m.addedNodes) {
        if (node.nodeType !== 1) continue;
        // Look for LiveCode’s modal canvas
        var canvas = node.querySelector && node.querySelector('canvas[data-lc-window-id]');
        if (!canvas) continue;

        // Stop observing further mutations
        obs.disconnect();

        var container = canvas.parentElement;
        // 1) Remove the container from the Tab order
        if (container.hasAttribute('tabindex')) {
          container.setAttribute('tabindex', '-1');
        }

        // 2) Find and prep the hidden text input
        var txt = container.querySelector('input[type="text"]');
        if (txt) {
          txt.removeAttribute('disabled');
          // Visually hide it off-screen but keep it focusable
          txt.style.position = 'absolute';
          txt.style.left     = '-9999px';
          txt.style.top      = '-9999px';
          txt.style.width    = '1px';
          txt.style.height   = '1px';
          txt.style.overflow = 'hidden';
          txt.setAttribute('tabindex','0');
        }

        // 3) In Chrome, focus the hidden input asynchronously
        if (isChrome() && txt) {
          try {
            txt.focus();
            console.log('Chrome path: focused hidden input →', document.activeElement);
          } catch(e) {
            console.warn('Chrome input.focus() failed:', e);
          }
          return;
        }

        // 4) In Firefox/Safari, focusing an input works too
        if (txt) {
          txt.focus();
          console.log('FF/Safari path: focused hidden input →', document.activeElement);
        }
        return;
      }
    }
  });

  observer.observe(document.body, { childList: true, subtree: true });

  function isChrome(){
    return /Chrome/.test(navigator.userAgent) &&
           /Google Inc/.test(navigator.vendor);
  }
})();
Andreas Bergendal
Independent app and system developer
Free LC dev tools: https://github.com/wheninspace
(WIS_WebDeployHelper, WIS_ScriptDependencies, WIS_BrowserAnimation)
WhenInSpace: https://wheninspace.com

Kangaroo SW
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 40
Joined: Sat Jan 15, 2011 10:57 am

Re: HTML5 modal focus not working

Post by Kangaroo SW » Thu Jun 26, 2025 11:44 am

Hi everyone 8)

Some time ago, I did also a bit of research to figure out how to focus a field after a page loads. I'm using a combination of JavaScript and LC Script for this.

Code: Select all

on openCard
   do "document.getElementById('canvas').focus();" as javascript
   focus on fld 1
end openCard
I’m not entirely sure if my approach works in all situations, and I haven’t tested it in every browser yet - but I thought I’d share my method here in case it’s useful to someone else :D !

Best regards
Rolf
Attachments
Focus_Field_On_Web.livecode.zip
(2.06 KiB) Downloaded 29 times

SWEdeAndy
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 324
Joined: Sat Aug 16, 2008 9:48 am
Contact:

Re: HTML5 modal focus not working

Post by SWEdeAndy » Thu Jun 26, 2025 8:09 pm

Kangaroo SW wrote:
Thu Jun 26, 2025 11:44 am
I’m not entirely sure if my approach works in all situations
Unfortunately, your approach does not work for modal stacks. The field is focused and the insertion beam is blinking, but when you start typing nothing enters the field. You still have to click it to make it receive key strokes. This is the problem the OP described, and which I managed to find a working solution to, after many failed attempts.

I'm still impressed that igalperry created an account here in 2008 and then waited 17 years before making their first (very valid) posting! :D
Andreas Bergendal
Independent app and system developer
Free LC dev tools: https://github.com/wheninspace
(WIS_WebDeployHelper, WIS_ScriptDependencies, WIS_BrowserAnimation)
WhenInSpace: https://wheninspace.com

Post Reply