all forms on my website are getting submitted by AJAX. And I can't find where it is implemented.
When I look into HTML I see the plain <form> with submit button, but form is always sent asynchronously.
I know that some .js file contains something like this:
$("form").onsubmit(function(e) {
var form = $(this).serialize();
$.post(......
e.preventDefault();
.....
});
But I cant find this code. My JavaScript doesn't do such things.
Where I can get the event subscriptions for events of particular element (or all form elements)?
Thank you
UPD:
Ok. It seems I found the suspect. When I remove script reference to jquery.mobile my forms are sending normally.
How to disable sending by AJAX for one particular form?
You can download chrome, select an element. Then at the right side of your developer tools (Where you also have css). There is a tab called "Event listeners". You can see all events bound to the element here - and their location (file + line number). Note that you need to check parents aswell, as events bubble up the dom tree.
If you are a firefox user, You can use firebug to see the events.
You can also see the events by using the below code. But this will not tell you which script and line.
$('selector').data('events');
Like this on this page:
$('#show-editor-button input').data('events')
Related
I did the following:
Created a Google Form (e.g. form ID = ABC)
Created a Google Sheet (let's call it sheet1)
In sheet1's script editor, installed a trigger to my form with code such as the following:
var form = FormApp.openById("ABC");
ScriptApp.newTrigger("testFunctionSheet1").forForm(form).onFormSubmit().create();
When I call the following, I see my trigger was installed properly:
ScriptApp.getUserTriggers(form);
Everything is great. I can execute code whenever a Google Form is submitted.
Problem is, later on I go ahead and create a new Google Sheet (let's call it sheet2), which has similar code:
ScriptApp.newTrigger("testFunctionSheet2").forForm(form).onFormSubmit().create();
To be safe, though, I attempt to remove all the previous triggers from all my old scripts (i.e. sheet1). However, when I run:
ScriptApp.getUserTriggers(form);
... it returns one result (testFunctionSheet2) instead of returning both testFunctionSheet1 and testFunctionSheet2. Turns out it only returns triggers that are executed by the current script!
This is problematic because it may mean I accidentally have many scripts that are all executing upon a form's submission. If I never wrote down which scripts execute for which forms, I would have no idea what exactly is run from each submission. Some of those scripts may either do the same thing (which is a waste of CPU cycles at best, or will interfere with each other at worst), or they may do completely different things and potentially clash with each other.
I want a simple way to find all script triggers that will be executed on form submission. Something like if the function actually behaved as I would expect...
I.e. ScriptApp.getUserTriggers(form) should return something like:
sheet1: testFunctionSheet1
sheet2: testFunctionSheet2
This way I can easily tell which scripts will be executed upon form submission and can manually remove the old ones, to ensure nothing clashes.
Is there a way to find out which triggers will execute across all my scripts upon form submission?
Update: The documentation for getUserTriggers() clarifies that it will never return triggers for different scripts:
Gets all installable triggers owned by this user in the given form, for this script or add-on only. This method cannot be used to see the triggers attached to other scripts.
How, then, would I know all triggers associated with a given Google Form? Note: this doesn't necessarily have to be a programmatic solution. If there was a UI element in Forms that gave me this information, that would suffice too.
There doesn't seem to be a way to do this, but there are some workarounds that can make things a bit more organized:
Instead of installing the form trigger on a Sheet, install it on the Form. If you get into this habit, you can easily tell if there are scripts installed because the first place you'd check is in the Form's script. Simply run the get all triggers command as you tried above, and it'll work.
Instead of installing the form trigger on a Form, set the form to submit its responses to the Sheet, and use the onFormSubmit() method in SpreadsheetTriggerBuilder. To find out which trigger is associated with a form becomes as simple as opening the form, then going to its destination, and then looking if that script has a trigger for the form.
Hide the trigger script names in some property on the Form that you don't plan on showing to the user (e.g. customClosedFormMessage). Set it to something like This script has an active trigger associated with sheet1. You can create a helper function that before installing a trigger, it ensures that that text doesn't exist there (if you want to limit to 1 trigger per form, for example).
Go to https://script.google.com/home/triggers?trigger_type=3&document_id=ABC
That should give a list of all triggers from form with id ABC. You can clear filters there and add new filters.
As the OP already mentioned on the question, the documentation says that a script can't get triggers created by other scripts.
If you are the only one that create triggers from your script projects, then go to https://script.google.com > Triggers, there you will find a list of all the triggers created by your account.
I didn't tried it yet, but I think that one alternative is to enable the Google Apps Script API on the projects that create triggers and add a function to be called through Google Apps Script API to "log somewhere" the triggers created by that project.
Regarding to "log somewhere" maybe the easier setting is to email the log to the "active user".
I have this page where an angularjs modal-content popup, in there i fill up some fields and click save. After save is initiated, popup should dissapear an event should happen and so on.
My selenium test does all that perfectly except that when it clicks on the save button, popup dissapears but no event is triggered or saved so when i open up the window again everything is empty. I've tried stuff that i know with selenium and it still doesn't work. Can anyone help me out here?
This is the save button:
<button class="save-button" data-ng-click="onSettingsSave()" ng-hide="readOnlyMode || !canSave()">Save</button>
Stuff i've tried:
var saveButton = driver.FindElement(By.CssSelector("button.save-button"));
saveButton.Click();
var saveButton = driver.FindElement(By.XPath(saveXpath));
saveButton.SendKeys(Keys.Enter);
((IJavaScriptExecutor)driver).ExecuteScript("arguments[0].focus();",saveButton);
((IJavaScriptExecutor)driver).ExecuteScript("arguments[0].click();",saveButton );
Try force clicking the element using pure JS:
driver.execute_script("arguments[0].click();", yourElement)
You can't use $ as a shortcut for document.querySelector in a script like that.
driver.ExecuteScript("document.querySelector('#base_element_id div input').click()");
Also this probably won't trigger an onClick in react / angular
Like the OP I have tried everything I can think of to get Selenium to trigger client side javascript events. I've seen some posts across the web of people having partial success where it randomly works; in my case it never works.
Selenium does successfully trigger the browsers primary click action, be it checking a checkbox or pressing a button, but it does not trigger any attached client side javascript events.
Both the native element.Click() method in selenium, and the abstracted ExecuteScript with arguments method of clicking as suggested by #csaladenes have the same result.
The only solution I have found so far is to use pure JS through that same ExecuteScript method; basically avoid the overload with params selenium can embed.
driver.ExecuteScript("$('#base_element_id div input').click()");
In my case I am using the JQuery that is already on my page to make locating the element easier, but any form of truly pure JS should do the same thing.
EDIT:
After some additional testing, it turns out that my "fix" really did nothing. However, performing the same click more than once did cause the client side events to fire.
In my case I am checking a checkbox, so I needed to perform the click 3 times to leave it in the correct state and still have the client side events run.
This is very odd, and definitely needs some more work to figure out where the issue is at that makes this necessary.
Edit 2:
I think I have finally found a solution, and at least partial answer, that does not make me cringe.
It seems as though Selenium has an issue where sometimes it "loses" the focus of the browser. Considering how consistent and repeatable my issue is I don't think focus is the only problem in my case, however the solution works pretty well.
I was able to get the immediate parent of my checkbox, which was a div element, click that first to return focus to the page, then click the checkbox. After that sequence of events the client side events worked correctly.
I have a form that gets completed on a webpage by the user,
when the user submits the form, I bring up a bootstrap modal dialog, this dialog has an iframe in it that loads the form from the parent window calling a function in it like so:
//parent window
var formToSubmit;
function getForm(){
return formToSubmit;
}
$("#submitButton").click(function(){
//alterations to the elements in $("mainForm")
formToSubmit = $("mainForm");
$("#modalDialog").modal();
//...
});
//modal iframe
var parentForm = parent.window.getForm();
$("#mainDiv").append(parentForm[0].outerHTML);
$("form").submit(function(){
parent.window.closeModalWindow(); //not sure whether this will close AFTER the form is completely submitted yet
});
$("form").submit();
My problem is that I'm submitting these forms to microsoft sql server reporting services and it takes every input element as a parameter. I have no control over this.
So when the user clicks submit in the main form, I disable all the elements that must not be set as parameters, the thing is; as soon as I get the form from the parent window and append it to the modal iframe, it seems as all of those changes are lost, is there any way to preserve this?
Your problem likely has to do with the call to outerHTML on the form. First of all, implementations of outerHTML have been different across browsers, so I would avoid using it if possible. Second, outerHTML does not necessarily contain the live DOM element, but merely a dump of it as a string.
Therefore, I suggest deep cloning the form before passing it to your IFRAME.
With jQuery (see docs):
$("#mainDiv").append(parentForm.clone(true));
Or plain JavaScript (see docs):
document.getElementByid('mainDiv').appendChild(parentForm[0].cloneNode(true));
I ran some tests to verify this, and as long as you're cloning the form, you will get the results you're expecting.
As a side note, why are you duplicating the form in a modal? Are you re-creating it as a "please review" type thing for the user? It seems like a strange process. I only ask, because perhaps there are better ways to do what you're asking. Anyway, the answer I've given should help.
In web development, JavaScript is often executed when clicking on elements.
In both Internet Explorer 9 and FireFox 4 a little message pops up in the bottom left hand corner with the JavaScript function will be executed by clicking on elements these elements.
ASP.NET makes use of the JavaScript __doPostback(...ugly parameter names..) on almost every element that sends a request to the server. This JavaScript is automatically added to the HTML elements that are generated by the ASP.NET controls and I have no way to circumvent this.
For example, an ASP.NET DropDownList is rendered as an HTML Select element and the __doPostBack() method is added to it so that whenever the user selects a new element, the server can process this action.
The __doPostaback() method is embedded into many of the ASP.NET controls and there is no easy way to change this.
One of my end users commented that this new feature makes it feel as if they are in "Debug-mode"....
So, my question is: how do I either make this popup show something user friendly...or is there a way to tell the browser (via HTML) not to display this nastiness?
Thanks!
-Frinny
Why don't you make the href of the link a hashtag and attach the actual action via JavaScript:
HTML
<a id="foo" href="#foo">Foo</a>
JS
var foo = document.getElementById('foo');
foo.onclick = function(e){
//script foo!
return false;
};
Your location will still be #foo to look nice, but the actual action will be in the foo.onclick function.
Alternatively you can specify the event inline (Foo), but I try to keep a clear MVC separation with HTML, CSS, & JS.
Using a hashtag also gives you the ability to listen for hash-change events or check the hash tag onload so that a user can still middle-click a link and have it work correctly in a new tab.
To my knowledge there isn't a way to make it not display, as that is part of the browser and not the page.
What I would do is create javascript functions at the top of the page with user readable names that contain the other functions inside.
I have a website, where I allow other developers to host content.
My aim is to log clicks on every hyperlink (even the content that is hosted by other developers) ,which exists on the page.
My initial approach was as follows:
$('a').click(function(event)
{
//do my logging
return true;
}
);
Now with the above approach , I am facing the following issues:
Developers may have images inside the anchor link, so the events target is an image rather than href
Many developers have their own way of handling an href click , using an onclick event rather than a simply href='' attr
Some developers add their custom attr , to the tag, and have custom functions to handle the clicks
so basically , the issue is , there is a huge variety of anchor tags available, and logging clicks is not as simple.
Many cases allowed me to log the data I wanted, but a few cases , broke the code badly.
My aim to post on this forum was:
to discuss what is the right approach to do hyperlink clicks logging in a dynamic environment
is there a plugin out there , which allows a functionality like this.
I know facebook and google have this , but they have a totol control, on what is being hosted in their environments.
Any help is greatly appreciated.
Adding a click handler to every link is not a good idea. You should make use of event delegation (which will only attach one event handler at the root of the document):
$(document).delegate('a', 'click', function(event) {
// logging
});
Update (17.12.2011):
Since jQuery 1.7, one would use .on() [docs]:
$(document).on('click', 'a', function(event) {
// logging
});
Regarding your problems:
Developers may have images inside the anchor link, so the events target is an image rather than href
Events bubble up as long as propagation is not canceled. It depends on what you want to log. With delegate the event.target property will point to the image, but this (inside the handler) will point to the a element.
So you should have no problems here (example: http://jsfiddle.net/cR4DE/).
But that also means to you will miss clicks if the developers cancel the propagation.
(Side note: You could solve this letting the event handler fire in the capturing phase, but IE does not support this (hence jQuery does not either).)
Many developers have their own way of handling an href click , using an onclick event rather than a simply href='' attr
This will not touch existing event handlers.
Some developers add their custom attr , to the tag, and have custom functions to handle the clicks
Not sure what you mean here.
It also depends on how the other content is included. E.g. the above code won't track clicks in iframes.
In your logging code you should check for the bad cases and deal accordingly.
For example in your first case i you get the image and walk the dom up until i would find an a tag and log the href from there.
There will be some cases in which you will not be able to do the logging but if they are small compared with the cases you can do that you will be fine :).