How to detect clear/close from set in jQueryMobile DateBox? - javascript

I'm using jQuery Mobile DateBox (in mode "timebox") to make the user select a time.
This works fine, but both hitting the top-left close icon and the Set Time button result in the same callback with the same arguments.
I'm looking for a way to make the close button just dismiss the control.
I found example here, but I fear that the DOM for the control has changed as $('.ui-datebox-controls') gives an empty result. I can't find the control in the DOM either.
So, I hoped for openCallBack or beforeOpenCallBack to realise a similar trick, but neither appear to be called.

Related

How do I locate the function that is stealing DOM focus?

I'm trying to debug the integration between my app and Stripe's Elements component library. Everything works fine in sandbox mode, but we ran into a problem on production in the 3D Secure authentication process. This involves loading an iframe, into our app, that contains a form from the credit card's issuer (usually via a technology partner, like Arcot).
The form loads correctly and its buttons are working as expected, but the element (for a SMS one time code) is not behaving. Every time I click on the input, something is immediately pushing the focus back to the element of the iframe. This makes it impossible to type anything in, since by the time I touch a key, the input is not in focus. For reference, it is possible to change the input's value using document.getElementById('enterPIN').value = '123456';
I'm not sure if my app is triggering focus() calls (I don't think so) or if it is some part of the iframe code or even Stripe's. Is there a good way to monitor DOM events and do a stack trace for the trigger of each one?
I tried two tactics. Neither gave an obvious answer, but they did point my search in the right direction.
I opened the Event Listeners panel (in the Elements tab of my browser's developer tools) and removed everything I could find, but it seems that this doesn't actually change the behavior of the page- focus kept being stolen away. Luckily, I also noticed some listeners that were defined by the Material UI library.
I used monitorEvents() to get a few more details, but the src & target values were not much help and event.relatedTarget was always null.
In the end, I found this discussion and realized that my MUI Dialog component was stealing focus whenever I clicked on the iframe triggered by its content. This was easily fixed by adding the disableEnforceFocus attribute.

GoogleTagManager (fbevent.js) breaks JQuery UI dialog

Recently we implemented the GoogleTagManager (GTM), and certain Jquery UI dialogs are not showing at all (some of them always work, some of them never work, consistently). Unfortunately, I cannot provide sample codes.
When a UI button is clicked that calls .dialog("open") the dialog is not shown but the entire page goes grey (div class="ui-widget-overlay ui-front"). I see in the html that the div has "display:none" style.
If I remove the display: none, the dialog is finally shown, but the form's UI is messed up. Somehow the width of the modal is 300px instead of 1000px, etc. Also, the event listeners from the save/cancel buttons are missing. If I put autoOpen: true on the jquery UI dialog declaration, the dialog is shown, but is still messed up the same way.
I noticed that when I have an adblocker, everything works properly, but when I don't, the bug appears. I also realized that a "fbevents.js" file is in the browser when GTM is used, and if I explicitly disable only this file with an adblocker, the bug disappears.
I also see a facebook.com/tr/ call that stays "pending" forever in the network tab in Chrome, when I click on the icon that calls the dialog("open").
And of course, if there is no GTM, the site works properly.
Do you have any idea what is this bug or how should I continue the investigation? (without updating jquery/jqueryUI or without switching to bootstrap modal)?
Without additional detail is very hard to guess, what causes your problem, but there is one thing, I will try ona first place.
Check, how is your trigger made.
There are some GTM configurations, that steps into link click event processing.
So maybe, there is an event listenning on an A element, that onlky pretends to be a link and GTM is waiting for response.
If this is a true, try to change event listener into just Generic click event (Click - All Elements).
I got lucky. I found a second form that exists for a short period of time, which was facebook related (GTM). I realized that a "xy.appendTo('form')" JS code inserts data into the wrong form... By changing the code to "xy.appendTo('#form1')" the problem is gone.
So a simple appendTo('form') started the domino effect, which resulted in duplicated IDs in the DOM, and messed up everything...
The facebook.com/tr call in the network tab is still in pending state, but I believe that is somehow related to Jakub Kriz's suggestion (I will update my answer soon).
UPDATE:
Even though the GTM debugger shows no trigger has been fired, the GTM sends requests to facebook.com/tr calls every time a "a/a href" or "input type="button"" is clicked. I believe this is a default functionality, and I understand why.
In some cases our website is using these html tags in an invalid way: "a" is used instead of a "div" and "input type button" is used for an icon that opens a modal dialog. If we change these, the unnecessary facebook.com/tr calls will be gone.
But I've got still no clue about the pending state. I believe when I apply the changes I mentioned above, the problem will be gone.

Close popup/dropdown on focusout (keyboard control)

I'm trying to make an accessible popup/dropdown like the example on W3's website. If you click on the keyboard users approach 1 menu, and then tab into the Space Bears menu item, pressing enter will open the menu. Then, if you press tab, you go through the menu. Once the focus is out of the menu, the dropdown automatically disappears. This is the functionality that I'm trying to emulate. I got the rest working, but their JavaScript snippet doesn't explain how to hide the popup on focusout.
I got the following solution of my own, which uses a timeout. The timeout is there, because without it, the activeElement is the body. I need to wait that short bit for the focus to be on an element. I feel like there could be a more reliable approach, rather than relying on a timeout, though.
Note that I called it a modal in my code, but it's likely not actually a "modal". This was just what I named it.
$('.js-modal *').on('focusout', function() {
setTimeout(function() {
var is_in_modal = $(document.activeElement).closest('.js-modal').length;
if (!is_in_modal) {
close_modals();
}
}, 10);
});
Your idea of something that disappears automatically when you go out of it is a bad idea.
You'd better switch to a more classic solution, like a true modal, as already well described by the other answer.
It's a bad idea because it's confusing.
Let's imagine this scenario: we have five elements 1, 2, 3, 4 and 5. 3 and 4 are initially hidden and appear when 2 is focused.
I'm initially on element 1:
I press tab and go to element 2. Element 3 and 4 appear, but since I'm blind, I may not have noticed it at all.
I press tab again. I go to element 3
I press tab. I go to element 4
I press again tab. I go to element 5. Elements 3 and 4 disappear but again, I may not have noticed it.
OK, well, I finally want to go back to element 3, so I press Shift+Tabb. I expect to land on element 4, but went on 2 instead. Where is element 3 ?
I hope that with this little scenario, you understand the problem. If I'm not aware at all that elements appear or disappear, I find elements in a different order than I expect.
If at that moment I don't understand the logic and don't find back the element 3, great are the chances that I leave the site forever.
You aren't convainced ?
I imagine you have been told to do that to have the same logic for keyboard users than with mouse users.
With the mouse, you click on the menu, it opens, but closes as soon as you leave its area.
Note that it's also a poor idea in terms of accessibility, because you require the user to be quite precise. Following precise paths with the mouse isn't' always easy, especially for elder people or people with movement difficulties.
For that reason, we usually recommand to no longer use menus like that, and change their behavior to make them disappear only when clicking outside of it. So, mouse users with some movement difficulties have all their time and freedom to select what they want to select.
For keyboard users, that's kind of the same thing. If I'm blind, I expect focusable elements to always have the same tab order, and expect changes in that order only when I make a conscient action like press enter to expand/collapse a menu.
If I'm sighted and use the keyboard for whatever reason, I don't expect elements to appear or disappear on screen when just pressing tab.
Still not convainced ?
So ask yourself another question: how do I use your interface with a smarphone ?
With a touch device, there's no real focus, as well as there's no real mouseover, until you click on a precise element to interact with it. It's problematic, isn't it ?
You don't have at all these notions, so you must react on clicks. You don't have choice, and that's good.
automatically disappears when the users uses keyboard/TAB navigation to focus out of it.
This is the exact opposite of the behaviour of a modal.
You should trap focus inside your modal and it should close with the Esc key and via a close button (accessible via keyboard).
This article is a good starting place to learn about Modals, although I disagree with the method for point 5 "While Open, Prevent Tabbing to Outside the Dialog" - this should also include using aria-hidden on every element outside the modal as otherwise screen reader users can end up outside the modal (as they may navigate via links or headings etc.) when they shouldn't be.
Final thought - are you sure you need a modal? There may be a better pattern you could use if the above does not apply to your use case.

strange behavior on display|display:none elements

I have a custom modal dialogue that consists of a simple div and some css. There are 2 buttons (OK, CANCEL) buttons. The CANCEL button is always the same; it hides the modal dialogue via onclick="$('#div').css('display','none')" (NB: this is also how the modal is shown; ('display','')). I assign different actions to the OK button depending on the need. This is done via $('#okBTN').attr('onclick','my_function()').
It works, but only the first time ©
The first time I open the modal and walk through the steps, everything works as expected. If I close the modal, however, then re-open it, the OK button has no action on it. I mean, the onclick is assigned (correctly); it's in the source code, and it will alert correctly via .attr('onclick'), but clicking the button does nothing. I have it set that when the modal pops up, the onclick is assigned each time; but it's almost as if there is a shadow copy or something stuck in memory or the DOM. Although, I don't see anything strange in Firebug....
I've tried cloning the button, reassigning it, then replaceWith'ing. I've also tried remove'ing it and re-adding it...
Any clues?
Hate to say it my friend but you're not leveraging the benefits of jQuery.
Why set display via CSS? Just use .hide() .show() or .toggle().
Why are you setting on onclick attribute via javascript? This doesn't make much sense at all. Use $(elem).click(my_function);
The second bullet will likely fix your problem, but I'd do some serious re-evaluation.
Good luck!
Use bind or event-name binders:
$('#okBTN').click(my_function)
I'd try using .css('display','block') instead of .css('display',''), as assigning a blank display value doesn't seem like a good idea (it might work, but just to be safe).
Have you tried setting the .bind() function of the element?
$('#okBTN').bind('click', my_function);

Catching the specific Javascript code being executed onClick

I am working on a site that has loads of legacy Javascript and jQuery includes and there is no documentation to show what is happening when.
I have a specific problem to fix and I cannot find the relevant code that is being executed when a button is clicked. To save me from trawling through (and making sense of) hundreds of lines of legacy script, is there a feature, possibly in Firebug, that will identify what script is being executed when I click on a button?
I believe there is a feature in Firebug's console window called Profile. Click profile, click the button, then click profile again. It should give you what all functions were called in that time. Be warned that if this code includes jQuery, you might get a huge long list of functions because jQuery uses tons in its code. Unfortunately, the profiler will also show anonymous functions, which can really be a pain.
Otherwise, do a search in the code for the button's class or ID and go through them. If you have an id of fancy then you might do a search for #fancy in your code and attempt to find it. That may lead you in a general direction, at least.
You can click Firebug's "Break on next" button (in the Script tab; it looks like a pause button), then push the button that you want to debug.
The next time any JavaScript code executes, Firebug will break into the debugger and show you that line of code.
The break button didn't work for me. Instead I did edit the onclick attribute with FireBug and prepended it with "debugger;" ... then you'll break right there once you click :)
None of the above answers worked for me. I am trying to use Firebug to figure out how a feature on a page is working for a site I have no control over. Here is what worked for me.
First, got the id of the element I am clicking on from the page source, and then get a temporary reference to it by creating a watch (under the script tab):
tmp=document.getElementById("idOfElement")
Next, I assigned the current onclick value to another temporary variable.
oldfunc=tmp.onclick
Next, I defined a new onclick function. Initially I tried putting debugger; as the first thing in the function, but this does not work! So instead, I created an alert:
tmp.onclick = function() { alert("Ok"); oldfunc() }
Now, as soon as I click on the button the alert comes up, at which point I then click the "Break on next" button as outlined in another answer to this question. Then I dismiss the alert and immediately I am in the debugger at the correct place.
In my case, the "Break on next" button did not work by itself, because there are a lot of other events, just mousing over the page was causing the breakpoint to be hit, preventing me from ever clicking the button.
In Firebug you can set a breakpoint in some JS and then you get a stack which will let you know the current function call stack. So if you set the breakpoint in function used by several handlers then you can use this to discover exactly which handler you are in.
This probably won't work if you are dealing with AJAX callbacks and the like though.

Categories

Resources