strange behavior on display|display:none elements - javascript

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);

Related

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.

Prevent same function from firing twice

I'm using jquery's bPopup() to open a modal window. When the user clicks a button, jquery loads an ajax page and then shows the modal windows. Due to this small delay when loading the page, the button remains active, and if the user clicks twice, it will fire twice, making two ajax requests to the server and opening two windows.
Is there a simple way to prevent this from happening? Since it's relatively a common problem, I wonder if there's a "right" way the pros handle it.
I've tried assigining the popup to a window.object, so that it would be overwritten on the second call, but it's still opening two popups.
That depends on what UX you're after, but I'd suggest you disable the button.
That way your user will:
Know the click was "registered".
Not try to click again.
Not crash / confuse you code.
EDIT
According to the comment, the "button" is actually not a <button>, but an element with an onclick handler. So:
You can disable the click handler by reversing what you did to set it (removeEventHandler, onclick=null...), but you'd then have to set it back once the pop-up is done, and that might be quite annoying.
You'd have to somehow manipulate the UI to indicate the button was clicked and is disabled. Could probably be quite simple to do with a CSS class.
But really, you're probably better off having 2 "versions" of your button element (<div>...), with only 1 visible at a time, with the other hidden via display: none. The "clicked" version should not have a click event handler set at all. Then, when the button is clicked, you immediately switch between the 2 (can be done with a single CSS class), and once the pop-up is done, switch back.

Using glDatePicker (or similar) into modal Boostrap 3

I've a simple page that requires 2 date input and I would use a datepicker to get them.
I've found glDatePicker http://glad.github.io/glDatePicker (thanks a lot!) that is simple, light and works very well.
My problem is use it in modal with bootstrap 3.
I can call function to display the datepicker, for example
$(window).load(function() {
$('#date').glDatePicker();
});
and it works perfectly anywhere, except in modal where it look likes to appear behind the modal and/or it's not entirely shown (malformed).
I've alredy tried to put it in a specific div (like the author suggest), but the result is the same.
I think that it can't be attached correctly to the input field because of modal, but I'm not sure and anyway I don't know how to solve it :)
Thanks!
I had the same problem with another library. The fact is that the calendar that is shown is attached to "body" element and for this reason it cannot be seen in the modal popup. For this reason you can try if changing z-index property or positioning for you is enough. Otherwise (like in my case) was hacking the library in order to accept one additional optional parameter that was meant to store the dom element to attach the calendar to.

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

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.

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