0

I have a jquery function so whenever a <input type="text"> element comes into focus, all text within it is selected.

$('input[type=text]').focusin(function(e) {
    // Selects all text on text field focus
    $(this).select();

});

So far, so good. Elsewhere in the page is a checkbox disguised as toggle switches via some fancy CSS, using the topcoat css library. Here is what the toggle switch looks like:

http://topcoat.io/switch/

When I click or tab into a textbox, all the text is selected, as expected. However, if I then click onto the toggle switch, it won't fire. I have to double click to make it work. It should only require a single click. If I click out of the textbox, onto the background of the page, the toggle switch reverts to only needing a single click. If I reload the page, and don't click into any text boxes, the toggle switch works properly, only requiring a single click. Weirdly enough, if I remove the $(this).select(); line from the jQuery function, the toggle switch then functions correctly again.

This is the structure of the HTML:

<div class="section-wrapper">

    <div class="section">
        <div class="trough">
            <label class="topcoat-switch">
                <input type="checkbox" class="topcoat-switch__input">
                <div class="topcoat-switch__toggle"></div>
            </label>
        </div>
    </div>

    <div class="section-contents">
        <!-- Input text fields are in here, buried in some more divs -->
    </div>

</div>

To dig deeper, I wrote a small function to keep track of which elements were registering a click.

$('div, input').on('click', function(e) {
    console.dir(e.currentTarget);
})

When working as expected, before focusing in on any text boxes, this is what the mouse click propagation looks like when clicking the toggle switch:

input.topcoat-switch__input
div.trough
div.section
div.section-wrapper
div.container-inner
div.container

The crucial element that needs to register a click is the input element: input.topcoat-switch__input

As expected, the mouse click registers in the deepest element, and propagates outward. However, after I click into a text box and then click the toggle switch, the mouse propagation stack looks like this:

div.topcoat-switch__toggle
div.trough
div.section
div.section-wrapper
div.container-inner
div.container

The input element is nowhere to be seen, and requires a double click to register. Instead of the input registering, it seems as though the div.topcoat-switch__toggle element (the input's sibling element) is registering instead.

What can I do to make it so I can keep the functionality of selecting all text when focusing on a text input, and fix the weird mouse click registration behavior?

boguslavsky
  • 155
  • 1
  • 7
  • What is your `focusin` function? – Anthony McGrath Apr 23 '20 at 01:05
  • It's the same as in the post. It was more complicated but I commented everything else out and the but was still present. It's the single line of $(this).select(); that's causing this whole problem somehow. – boguslavsky Apr 23 '20 at 01:07
  • 1
    Can you unselect the text input when you hover over the topcoat switch (before you click it)? It seems like the selected text interferes with the topcoat CSS such as the `input:focus`, `input:active`, `input:checked` styles – Anthony McGrath Apr 23 '20 at 01:19
  • another idea is when the `div.topcoat-switch__toggle` click registers, manually initiate a click of the input instead. – Anthony McGrath Apr 23 '20 at 01:21
  • I think this was indeed the problem. I added in a function to deselect everything on the focusout event of a text box using this user's function: https://stackoverflow.com/a/14788286/2450280 That did the trick. Thanks for the insight. – boguslavsky Apr 23 '20 at 01:22

1 Answers1

0

As pointed out by Anthony McGrath, the problem was that the text selection input was interfering with the CSS style that was used to make the toggle switch work. The topcoat.io toggle switch style relies on input: focus, input:active, and input:checked selectors to properly function, and the selection of the text interfered with those selectors.

I've solved this by adding a clearSelection() function to the focusOut event of each text box. The clear selection function I used was provided courtesy of Tim Down:

https://stackoverflow.com/a/14788286/2450280

boguslavsky
  • 155
  • 1
  • 7