How to run a function on a page with Capybara/Poltergeist? - javascript

I have a page with JS functions (which are called on mouse click) within <script> ... </script> tags. While I was testing I had encountered problems with .click method not working many times. Therefore I decided to simply call that function manually. However I found no source on the Internet which taught to do this.
I want to avoid clicking the links and simply call for doSumbit('5').
Thank you!
The JS functions are:
<script language="javascript">
function doSubmit(infoTypeId) {
document.forms[1].INFOTYPEID.value = infoTypeId;
document.forms[1].action = document.forms[1].action + "#" + infoTypeId;
document.forms[1].submit();
document.forms[0].INFOTYPEID.value = infoTypeId;
document.forms[0].submit();
}
function doSubmitOne(infoTypeId) {
document.forms[0].INFOTYPEID.value = infoTypeId;
document.forms[0].submit();
}
</script>
and the on-click links are:
<a href="javascript:doSubmit('11')" >Engine News<br></A>
<a href="javascript:doSubmit('5')" >Parts Identification<br></A>

You can run arbitrary JS with execute_script
page.execute_script("doSubmit('5')")
if you expect a return value use evaluate_script - it's all documented here - http://www.rubydoc.info/gems/capybara/Capybara/Session#evaluate_script-instance_method
Of course if you're actually testing an app, you'd be much better off figuring out why click isn't working for you and fixing that, since by just calling JS functions you're not actually testing that your app works.
EDIT: typo doSubit changed to doSubmit

Related

JavaScript button onclick not working

<button onclick="hello()">Hello</button>
<script>
function hello() {
alert('Hello');
}
</script>
This is my code. But it's not working. When I click on the button nothing happens.
Note to other developers coming across this, you can run into this if you use a reserved method names e.g. clear.
<!DOCTYPE html>
<html>
<body>
<button onclick="clear()">Clear</button>
<button onclick="clear2()">Clear2</button>
<script>
function clear() {
alert('clear');
}
function clear2() {
alert('clear2');
}
</script>
</body>
</html>
How about this?
<button id="hellobutton">Hello</button>
<script>
function hello() {
alert('Hello');
}
document.getElementById("hellobutton").addEventListener("click", hello);
</script>
P.S. You should place hello() above of the button.
Ran into this problem myself so I can confirm something's not right. The difference is that I am generating the DOm Element at runtime. Replacing onclick with onmousedown seemed to do the trick if you can't find a place to addEventListener in your code.
I had a similar issue. I had child.js and a common.js files. In my case, My HTML file was using both the JS files and both of them had a function with the same name,
child.js
function hello(){}
and also
common.js
function hello(){}
After I remove one of these my code works fine and onclick started working. hope this helps!
using onclick vs EventListeners.
The question is a matter of browser compatibility and necessity. Do you need to attach more than one event to an element? Will you in the future? Odds are, you will. attachEvent and addEventListener are necessary. If not, an inline event may seem like they'd do the trick, but you're much better served preparing for a future that, though it may seem unlikely, is predictable at least. There is a chance you'll have to move to JS-based event listeners, so you may as well just start there. Don't use inline events.
jQuery and other javascript frameworks encapsulate the different browser implementations of DOM level 2 events in generic models so you can write cross-browser compliant code without having to worry about IE's history as a rebel. Same code with jQuery, all cross-browser and ready to rock:
$(element).on('click', function () { /* do stuff */ });
Don't run out and get a framework just for this one thing, though. You can easily roll your own little utility to take care of the older browsers:
function addEvent(element, evnt, funct){
if (element.attachEvent)
return element.attachEvent('on'+evnt, funct);
else
return element.addEventListener(evnt, funct, false);
}
// example
~```
addEvent(
document.getElementById('myElement'),
'click',
function () { alert('hi!'); }
);
Try it: http://jsfiddle.net/bmArj/
Taking all of that into consideration, unless the script you're looking at took the browser differences into account some other way (in code not shown in your question), the part using addEventListener would not work in IE versions less than 9.
There is no problem with your code.. run this snippet
function hello() {
alert('Hello');
}
<button onclick="hello();">Hello</button>
and if you want to alert this on window load. change your code like this way
(function(){
alert('hello')
})();
Add:
type="button"
to the button element. The default type is "submit" which is submitting the form before the script is run.
In my case there are was two same elements with position: absolute. I set onclick on the first one so it haven't been called because second element was covering it
I had the same issue, for me, it did not work because of my main.js having type="module", if you don't need type="module" this will work.
<body>
<button onclick="onBtSave()">Save filter model script type module</button>
<button onclick="onBtRestore()">Restore filter model no script type</button>
<script type="module">
// broken
function onBtSave() {
console.log("saving current filter model");
}
</script>
<script >
// working
function onBtRestore() {
console.log("restoring current filter model");
}
</script>
This happened to me when I opened another folder in visual studio code. I just opened new window of visual studio code and only opened one folder this time and it now works
I had the same problem and that's because of reserved method names. We just change the function name.
function click() {
alert('hi')
}
function click1234() {
alert('hi')
}
<body>
<button onclick="click()">login</button>
<button onclick="click1234()">login1234</button>
</body>
For other devs with more advanced code, sometimes an absolute position element is blocking the button. Make sure no element is blocking the button(s) from being clicked.
Write a semicolon after hello function like this
<button onclick="hello();">Hello</button>

Code claims function does not exist only if it is called from html-set onclick event

I have a very strange issue preventing my code from firing a JQUERY function - but only if the event is declared in an onclick attribute tag within the page's html. If that same function is assigned to an element with a javascript ".click(function()..." event, then the function is called properly and the code doesn't say "This event doesn't exist!", essentially.
I trawled through the internet looking for someone with the same issue, and while there are a lot of questions that look superficially like the issue I am having, none seem to address it exactly.
Here is an example:
//Delete an existing exclusion.
$.fn.deleteExclusion = function (idExclusion) {
document.cookie = idExclusion + "=; expires=; path=/";
$.fn.buildExclusions();
}
If I call this method by saying:
$("#someButton").click(function(){
$.fn.deleteExclusion();
)
... then the function exists and is run properly.
However, if I assign this function as follows (created on page load as part of page html):
Some Button
... then the function doesn't exist when I click that link.
This does not happen for one of my company's websites, which uses ASP.NET .aspx page structures. However, I am working on a new MVC application, which is where this behavior is occurring.
I am stumped, frankly. Right now, I am not sure what else to provide code-wise to demonstrate, without probably overdoing it with unnecessary details. Please let me know if you need additional code to help me figure this out.
You need to include Jquery
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
jQuery(document).ready(function($){
$.fn.deleteExclusion = function (idExclusion) {
document.cookie = idExclusion + "=; expires=; path=/";
$.fn.buildExclusions();
}
});
We found a workaround. To get this working, we added:
//Set onclick events for delete exlusion anchor tag buttons created dynamically.
$(document).on("click", "a.deleteExclusion", function () {
$.fn.deleteExclusion($(this).attr("id").replace("delete", ""));
});
This created the onclick event on page load, but applied it to elements as they were created. It allowed elements created in our cshtml file initially, along with dynamically created html elements, to have a working click event.

why do my onClick functions take two clicks

I've noticed from a few different projects of mine that whenever I click something I add an onClick function to, it always takes two clicks to get them going when a page is freshly loaded. The general structure I use for them is:
function PageChange(){
var welc_p = document.getElementById("welcome");/**gathers page DIVs**/
var page01 = document.getElementById("page01");
var page02 = document.getElementById("page02");
var start = document.getElementById("start_btn");/**gathers buttons**/
var p1_back = document.getElementById("p1_back");
var p1_next = document.getElementById("p1_back");
var p2_back = document.getElementById("p2_back");
var p2_next = document.getElementById("p2_back");
start.onclick=function(){
page01.style.display="block";
welc_p.style.display="none";
window.location="#page01";
};
}/**function**/
then the way I call it in the html is
<div class="some_class" id="start_btn" onClick="PageChange()">!!!LETS GET STARTED!!!</div>
Here's a fiddle of it as well.
https://jsfiddle.net/Optiq/42e3juta/
this is generally how I structure it each time I want to create this functionality. I've seen tons of other posts on here about their items taking 2 clicks to activate but none of them were doing anything near what I was trying to accomplish and it seemed their problem was within their coding. Does anybody know why this is happening?
This is because you are attatching a event handler to your button on click of your button.
This means that one click of the button activates the event handler, not the code within start.onclick=function() {
Then, the second click works becasue the event handler has been activated, and now the code will run.
Try moving your code out of the function, then it will work with just one click
Just had the same issue, and found an easy solution based on the above answer.
Since your function needs two clicks to work, I just called the function above the function and it works fine. This way the function already gets called one time on load, then it gets called the second time when you click it.
yourFunction();
function yourFunction(){
-- content --
}
I also had the same 2 clicks required on intitial interaction and after many searches couldn't find the best solution for my specific nav menu. I tried this solution above but couldn't get it to work.
Stumbled upon this code from a youtube example and it solved my issue. I wanted to nest submenu's for multiple levels and modified it from its original implementation to work best for my responsive mobile menu.
var a;
function toggleFirstLevelMobileSubMenu(){
if(a==1){
document.getElementById("mobile-sub-menu-depth-1").style.display="none";
return a=0;
}
else {
document.getElementById("mobile-sub-menu-depth-1").style.display="flex";
return a=1;
}
}
var b;
function toggleSecondLevelMobileSubMenu(){
if(b==1){
document.getElementById("mobile-sub-menu-depth-2").style.display="none";
return b=0;
}
else {
document.getElementById("mobile-sub-menu-depth-2").style.display="flex";
return b=1;
}
}
Of course, in the CSS I had display: none set for both ID's.
First, the problem:- On first click instead of running js your browser runs the button aka the event.
Solution:- in order to resolve this we need to make sure our function is already before the event is run (this is one of the ways to solve the problem). To achive this we need to load the function aka call the function in some way.
So, i just simply called the function after function is completed.
Code answer-
Just add at the end of your code
PageChange();

How to create a global function that closes a jQuery colorbox?

First I am using the jQuery colorbox plugin that is working fine so far but then I want to close the colorbox using a button. Unfortunately I can't just trigger the click event on that button by selecting its ID using jQuery, instead of that the button must call a javascript function called closepan() (this behavior is unfortunately mandatory for me).
I tried to create the function
closepan() {
$.colorbox.close();
}
first case : inside the
$(document).ready(function(){...});
but then I got the error closepan is undefined.
second case : before the
$(document).ready(function(){...});
but then it's the colorbox method that is undefined!
I gave up after gazillion hours of fiddling with several solutions I've found all around stackoverflow.com regarding this topic! I can't figure out how to make this working!
In other words, how to create a function named closepan() that can execute $.colorbox.close(); while being available globally for my button?
No matter where you create a variable or function if you create it on window it will be available globally.
window.closepan = function() {
// hello there
}
function closepan() {
if($.colorbox) {
$.colorbox.close();
}
}
However, at the point where someone clicks your button all external scripts should have been loaded so that check shouldn't be necessary...
Don't forget to put the keyword function in front of your declaration...
function closepan() {
$.colorbox.close();
}
Working JSFiddle

JavaScript: changing the value of onclick with or without jQuery

I'd like to change the value of the onclick attribute on an anchor. I want to set it to a new string that contains JavaScript. (That string is provided to the client-side JavaScript code by the server, and it can contains whatever you can put in the onclick attribute in HTML.) Here are a few things I tried:
Using jQuery attr("onclick", js) doesn't work with both Firefox and IE6/7.
Using setAttribute("onclick", js) works with Firefox and IE8, but not IE6/7.
Using onclick = function() { return eval(js); } doesn't work because you are not allowed to use return is code passed to eval().
Anyone has a suggestion on to set the onclick attribute to to make this work for Firefox and IE 6/7/8? Also see below the code I used to test this.
<html>
<head>
<script type="text/javascript"
src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.js"></script>
<script type="text/javascript">
$(document).ready(function(){
var js = "alert('B'); return false;";
// Set with JQuery: doesn't work
$("a").attr("onclick", js);
// Set with setAttribute(): at least works with Firefox
//document.getElementById("anchor").setAttribute("onclick", js);
});
</script>
</head>
<body>
Click
</body>
</html>
You shouldn't be using onClick any more if you are using jQuery. jQuery provides its own methods of attaching and binding events. See .click()
$(document).ready(function(){
var js = "alert('B:' + this.id); return false;";
// create a function from the "js" string
var newclick = new Function(js);
// clears onclick then sets click using jQuery
$("#anchor").attr('onclick', '').click(newclick);
});
That should cancel the onClick function - and keep your "javascript from a string" as well.
The best thing to do would be to remove the onclick="" from the <a> element in the HTML code and switch to using the Unobtrusive method of binding an event to click.
You also said:
Using onclick = function() { return eval(js); } doesn't work because you are not allowed to use return in code passed to eval().
No - it won't, but onclick = eval("(function(){"+js+"})"); will wrap the 'js' variable in a function enclosure. onclick = new Function(js); works as well and is a little cleaner to read. (note the capital F) -- see documentation on Function() constructors
BTW, without JQuery this could also be done, but obviously it's pretty ugly as it only considers IE/non-IE:
if(isie)
tmpobject.setAttribute('onclick',(new Function(tmp.nextSibling.getAttributeNode('onclick').value)));
else
$(tmpobject).attr('onclick',tmp.nextSibling.attributes[0].value); //this even supposes index
Anyway, just so that people have an overall idea of what can be done, as I'm sure many have stumbled upon this annoyance.
One gotcha with Jquery is that the click function do not acknowledge the hand coded onclick from the html.
So, you pretty much have to choose. Set up all your handlers in the init function or all of them in html.
The click event in JQuery is the click function $("myelt").click (function ....).
just use jQuery bind method !jquery-selector!.bind('event', !fn!);
See here for more about events in jQuery
If you don't want to actually navigate to a new page you can also have your anchor somewhere on the page like this.
<a id="the_anchor" href="">
And then to assign your string of JavaScript to the the onclick of the anchor, put this somewhere else (i.e. the header, later in the body, whatever):
<script>
var js = "alert('I am your string of JavaScript');"; // js is your string of script
document.getElementById('the_anchor').href = 'javascript:' + js;
</script>
If you have all of this info on the server before sending out the page, then you could also simply place the JavaScript directly in the href attribute of the anchor like so:
Click me
Note that following gnarf's idea you can also do:
var js = "alert('B:' + this.id); return false;";<br/>
var newclick = eval("(function(){"+js+"});");<br/>
$("a").get(0).onclick = newclick;
That will set the onclick without triggering the event (had the same problem here and it took me some time to find out).
Came up with a quick and dirty fix to this. Just used <select onchange='this.options[this.selectedIndex].onclick();> <option onclick='alert("hello world")' ></option> </select>
Hope this helps

Categories

Resources