Page 1 of 1

HTML5 modal focus not working

Posted: Sun Jun 22, 2025 5:02 pm
by igalperry
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?

Re: HTML5 modal focus not working

Posted: Mon Jun 23, 2025 9:26 pm
by SWEdeAndy
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/

Re: HTML5 modal focus not working

Posted: Mon Jun 23, 2025 9:34 pm
by SWEdeAndy
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! :)

Re: HTML5 modal focus not working

Posted: Tue Jun 24, 2025 9:58 pm
by SWEdeAndy
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);
  }
})();

Re: HTML5 modal focus not working

Posted: Thu Jun 26, 2025 11:44 am
by Kangaroo SW
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

Re: HTML5 modal focus not working

Posted: Thu Jun 26, 2025 8:09 pm
by SWEdeAndy
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