I am building a third party plugin to the popular platform Atlassian JIRA and where I have implemented a calendar. However when I click on a day outside any event, it triggers a function which will trigger the #create_link event.
When that event gets fired a new modal window opens and the user may fill out a new issue. The thing is that I want to change the issuetype field and then fill in one field automatically. However, I have no idea how to generate a new window with these result (I don't think it's possible) and therefore my only option was Javascript events.
This is my code so far:
jQuery.when(AJS.$('#create_link').trigger('click')).done(function() {
jQuery.when(jQuery('#issuetype-field').trigger('click')).done(function() {
jQuery('.aui-list-item-li-event').find('a').trigger('click');
});
});
//I have also tried to use `.then`
The thing is, the triggers work when run separately in console but it seems like the jQuery.when doesn't. Because the next event triggers long before the window has been loaded.
What I need is a way to wait to trigger the last 2 events by using callbacks on the triggers or what not. How can I solve this problem? Also, if anyone know how to create a new issue window with js in Jira that is also a very acceptable answer.
Using Jira issue collector would make your task much simpler. You can configure it to receive feedback or bug reports etc.
https://confluence.atlassian.com/display/JIRA/Using+the+Issue+Collector
The integration of the issue collector is merely adding a script tag in your HTML page
Related
I have a vanilla js setup that relies on functions being stored in a config object. The stored functions are then assigned to anchor element .onclick events (used to allow clicking headers in a table, but that's not related to the question). Those functions usually fire an alert, show a confirm dialogue, or prompt the user for a string. i.e:
const cfg = {
f1: (hdr) => { alert (`You clicked on ${hdr}`); }
}
anchorElement.onclick = cfg.f1.bind(null, anchorElement.textContent);
Everything works, but whenever one of these functions waits for a user's response (even just clicking OK on an alert), the browser (Chrome in this case) is firing the '[Violation] 'click' handler took ms' message in the console.
I have searched for this issue and tried the various workarounds for similar issues (involving promises, async, and timeouts), but the message persists as seen here:
Fiddle
I have been through all of the 'similar questions' that pop up as I type this. I get that this is not a code-breaking issue and that the most common suggestion is to just ignore it if you know it's not a long-running process that you need to tweak. But the presence of the message indicates to me that there should be a "right" way to handle a click event when you are expecting it to take an unforeseen-but-definitely-longer-than-50ms amount of time.
So, what IS the proper way to wait on a dialogue box in an onclick function?
The right way is probably to never use alerts and other process blocking methods as they are annoying for the user.
Modals are usually created inside the website
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.
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.
This may seem like a simple question, but it doesn't seem to be answered anywhere that i can find.
I am writing an onClick event handler that simply calls dataLayer.push() when an anchor is clicked.
Is dataLayer.push() a synchronous operation?
Will the GET request to google definitely be sent, even though the browser has unloaded the page it was requested from due to the link being followed?
Some browsers show the connection get cancelled, some show it success.
My question is if the computer is slow, is it possible for the page to get unloaded before the request is sent?
This is why i assume that google started using the eventCallback property to redirect the user after the link has been followed.
e.g.
https://developers.google.com/tag-manager/enhanced-ecommerce#product-clicks
This source code does not include the click handler, but implies that the onClick event should stop propogation and let the eventCallback function set document.location.
However, as soon as you cancel the event, all its information has gone.
This (in my opinion) is just the wrong way to do it.
e.g.
(CTRL or COMMAND) + Click opens a new tab on browsers. This will not work unless the onClick event handler allows the prorogation to continue.
Relying on eventCallback also means that if the google scrips didn't load for one of the many reasons it could (but is still unlikely), your links don't work. And your site is broken.
So this leaves the correct way to do it for the onClick event handler to allow the event to propagate and return true.
Which also means that dataLayer.push() would need return after the GET request was sent for any of this to work properly.
Code example:
NOTE: You will get mixed results in mixed environments.
Link
$(document).on('click', 'a', function(event) {
// Is dataLayer.push() guaranteed to fire a GET ?
// data set externally
dataLayer.push(data);
return true;
});
Is there anyone out there that can guarantee that the GET request will get fired to the google server?
Have the google developers forgotten something here?
EDIT: Updated title to be more relevant to the question.
datalayer.push does not send anything to Google. It pushes objects with key/value pairs to the datalayer array. This might contain an event which in turn fires a tag. Whether the tag is sent depends on the setup of the tag, not on the dataLayer.push.
As a consequence, when you write your own click handlers your are yourself responsible to make sure your tags are actually fired.
If you use the built-in click handler you can configure a delay to make sure your tag has time to fire before the link redirects:
Since link clicks usually cause the browser to load a new page and
interrupt any pending HTTP request, you have the option to add a small
delay to allow tags fired by Tag Manager to execute properly before
redirecting to the next page. Checking the “Wait For Tags” option will
delay opening of links until all tags have fired or the specified
timeout has elapsed, whichever comes first.
You should be able to mix both methods (push data on the click, but still use the "native" link click handler for the event).
You can also try to specify "beacon" as the transport method in your Google Analytics tags, on browsers that support this (which I think is only Chrome at the moment) GA will then use the navigator.sendBeacon interface, which sends the data even in case the page unloads.
You might think that Google's solution is not very elegant (but the simple delay has the advantage that it works for all tags, not just for GA), but they have not "forgotten" the problem.
Also solutions that combine GA hit callbacks with timeouts that redirects if the callback fails as proposed i.e. by Simo Ahava somewhere should be be doable with GTM, even if they are probably more cumbersome to implement in GA.
I don't know if this is the effects of an update panel or what, but I basically have a drop down list that allows a user to select an item as a filter. When the item is selected it should bring back only one item into a grid view. That is this specific filter will at most bring back the record you are looking for. This works fine if the user clicks an "apply" link to apply the filter. Behind the apply link is some server-side code (C# within an ASP.NET Web Forms application).
We had a request by a user with something to the effect of:
"Why do I have to click the apply button if I make a selection in this
one drop down filter...it should simply get that one record I am
searching for. This helps me because I don't have to click the
"Apply" button."
I agreed with him and thought what is the easiest way to do this...I thought: Simple, I will have an on change event handler of the drop down such that when a selection is made I'll trigger a click event. Something to this effect:
$("#MainContent_ddlCompany").on("change", function() {
var companyId = $("#MainContent_ddlCompany").val();
$("#MainContent_hdnCompanyValue").val(companyId);
$("#<%=ddlCompany.ClientID %>").trigger("chosen:updated");
if (companyId.length > 0) {
$(".apply").click();
$(".apply").removeClass("applyButton");
$(".apply").addClass("resetButton");
} else {
//cleared selection of a company
$(".apply").removeClass("resetButton");
$(".apply").addClass("applyButton");
}
});
At first this didn't work, and I couldn't tell why, but then after some serious googling I changed this line:
$(".apply").click();
To this:
$('.apply')[0].click();
That worked great...so I decided to test it some more. As I kept selecting one filter value after another I noticed the page started to slow down. In fact by the 6th or 7th time it was pretty unusable. I don't know why it's happening, but I suspect again it has to do with the fact that this linkbutton with the class name .apply is inside an update panel.
But still I thought to myself, it was inside of an update panel before I changed my jQuery code to simulate the click event. So why does the page slow down and drag with this little piece of code? Is calling the event from jQuery code rendering something else in the HTML that could be causing this?
If I change my code back and force the user to click the apply button then we are back to a good normal speed. Why is it if I tell jQuery to simulate clicking the button my page slow down? It's doing the same thing, the simulation of the click of this link button is calling its server-side code method whether the user clicks it or I have jQuery click it.
For now I'm at a loss as to why this is happening because this button is in an update panel in either case, yet when I have jQuery click it via $('.apply')[0].click(); the page slows down after several attempts. Yet when I have the user simply click this button (without the jQuery click event) then it works fine?
What am I missing here?
Ugh, well, I found my issue. Because I was using updatepanels I had to wrap my jQuery code to include an add_endRequest. That is, you have something to the effect of:
$(document).ready(function() {
//Some initial event/triggers
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_endRequest(function () {
//Copy of some initial event/triggers
});
});
Why do I use the endRequest you ask? Well, because updatepanels basically throw away all your events after an asynchronous postback because the HTML at that point (after an update) is rendered again and at that point all events associated with any control inside an update panel are wiped away. At this point of course document.ready() does not run, so I have to resubscribe to these events inside of endRequest. Enter my issue...
I had a huge brain fart where I basically took everything, literally everything inside document ready and copied it into endRequest. In fact, if I remember correctly, I read articles which stated
Whatever you have in document ready simply copy paste into endRequest
That's fine, but you have to be careful here. I was throwing in events that were not wrapped around inside of an updatepanel into endRequest. The result is disastrous...at least for me.
These events would be attached then multiple times..or based on the number of asynchronous postbacks made. In my case, as I was testing I mentioned after the 6th or 7th time performance starts degrading. Well, by that time my controls were being attached that many times to events. For instance, my .apply button along with my dropdownlist were both outside of my updatepanel. But my jQuery code was attaching the change event of my dropdownlist in both document ready and endRequest.
The result is initially it's pretty fast, because it's only in document ready. But as I make asynchronous postbacks these events are being attached every time. For n tests I would have n attached events...in my case the test of 7 yields 7 on change event handlers!
Case in point, do not place any event handlers such as jQuery's on() event for any controls that are NOT inside an update panel. Otherwise you will run into what I ran into which was poor performance as events are happening.