Handling a javascript popup occurring on a keyup event
For Watir:
There are some actions that currently wait for a pageload, such as .click
, .select
, because after such actions the page is often updated via a postback or form post. The _no_wait
variant exists for those , as a way to tell the script to proceed without waiting for the page load to occur when a popup will be occurring.
Currently .set
has no wait for page load logic (as far as I know anyway) and thus no _no_wait
variant of the method. So you can probably just proceed straight from setting the value, to looking for the popup.
Note that if you don't see the popup after using .set
, you may need to fire the 'onkeyup' event to trigger your client side scripting. Also be sure it's really a JS popup, there's lots of other ways of doing stuff that looks like the JS popups, but are really just things like divs etc.
Since this is a Javascript Popup, you should be able to get rid of it via code similar to the examples in the Watir Wiki
browser.javascript_dialog.button('OK').click
For Watir-Webdriver:
If you are using Watir-Webdriver then things are a bit different. I'm going into a bit more detail here because this info is not as easily available (yet)
Webdriver has an Alerts API, and Watir-Webdriver has an alerts helper which makes use of that, with a few different methods in it to deal with various styles of javascript popups. The methods are described in the RDoc for watir-webdriver look for 'alerthelper' under the main watir class. These are the examples given there.
require "watir-webdriver/extensions/alerts" #add to require section at top of script)
browser.alert do
browser.button(:value => "Alert").click
end #=> "the alert message"
browser.confirm(true) do
browser.button(:value => "Confirm").click
end #=> "the confirm message"
browser.prompt("hello") do
browser.button(:value => "Prompt").click
end #=> { :message => "foo", :default_value => "bar" }
Note that these examples are taken pretty much straight from the rspec tests for the alerthelper code. As such they may not make perfect sense to you without knowing this particular little detail. The click method inside the loop is the action that makes the alert appear. The test webpage has three buttons, with values Alert, Confirm, Prompt, which cause the popups to appear as the tests run against that page.
To use this stuff in your code, replace that middle line with whatever action in your script is causing the popup. For example in one of my scripts I click a button to delete the user's credit card, and there is a confirm dialog that pops up. So my code ends up looking like this (note this code is designed to work for both watir and watir-webdriver, $webdriver gets set to true or false depending on which is being used.
if $webdriver #watir-webdriver
$browser.confirm(true) do
$browser.div(:id => 'credit_cards').link(:text =>'Delete').click
end
else #watir
$browser.div(:id => 'credit_cards').link(:text =>'Delete').click_no_wait
$browser.javascript_dialog.button('OK').click
end
BTW the comment after 'end' in each of those examples? That's what you get back if you assign the output from the loop to a variable
confirm_message = browser.confirm(true) do
browser.link(:text => "Add Lasers").click
end
puts confirm_message
> "do you really want to put lasers on sharks?"
Keyup not firing when keydown opens an alert
The alert prevents the event from happening. What you could do instead is trigger this function manually, because it happens anyways.
var keyupfunction = function(e){
alert('up');
console.log('up');
}
window.addEventListener('keyup', keyupfunction);
window.addEventListener('keydown', function(e) {
if (i++ % 2) alert('down');
console.log('down');
keyupfunction(e);
});
But really, you shouldn't be using alerts. It prevents these events, but who knows what else it might break. Use something custom instead.
Assigning click event handler inside keyup event causes the click event to be fired multiple times
$('this').off();
should be $(this).off();
also probably you'd better go using the input
event instead of keyup
. input
event will trigger even if one pastes content into your fields.
nevertheless I'd go the other way around:
// (cache your selectors)
var $newName = $("#newName"),
$newFrom = $("#newFrom");
// create a boolean flag
var haveNewValue = false;
// modify that flag on fields `input`
$newName.add( $newFrom ).on("input", function() {
haveNewValue = ($.trim($newName.val()) + $.trim($newFrom.val())).length > 0;
});
// than inside the click test your flag
$('#add-person').click(function (e) {
if(!haveNewValue) return; // exit function if no entered value.
// do stuff like adding row to table
});
What was wrong:
on every keyup
you was assigning a new (therefore multiple) click
event/s to the button, but the (corrected to:) $(this).off()
was triggered only after an actual button click.
Also a better way to use .on()
and off.()
(notice the difference in using the .click()
method and the .on()
method) is:
function doCoffee() {
alert("Bzzzzzzzz...BLURGGUZRGUZRGUZRG");
}
$("#doCoffeeButton").on("click", doCoffee); // Register "event" using .on()
$("#bossAlertButton").click(function() {
$("#doCoffeeButton").off("click"); // Turn off "event" using .off()
});
Keyup event listener fires when enter is pressed on Chrome's Ominbox
This happens because once you hit enter in the omnibox, the focus turns to the page. If you tried the same thing with onkeydown
, the omnibox would change nothing, because as you said, it isn't a part of the document. One way to filter the omnibox's false event out would be to check that every keyup
has a pair keydown.
<script>
var down = false;
document.addEventListener('keydown', function (){
down = true;
}, false);
document.addEventListener('keyup', function (){
if(down === true){
alert('It was from the page!');
}
else{
alert('Omnibox. Ignore it.');
}
down = false;
}, false);
</script>
Demo.
Make your own HTML page and try it preferably, because PasteHTML.com stuffs it into an iframe. For it to work correctly there, click on the text first to give the iframe focus.
Demo.
Remember to use your mouse to focus on the omnibox and type, not a keyboard shortcut. (That fires the onkeydown event, creating a false positive)
Update: As of Chrome 35, this doesn't happen anymore. I don't know which version they fixed it on, however.
focus() on element triggers keyup event
if you press space or enter when focus on a button, (keyevent
, click
) - both event will be triggered.
it just browser default behavior.
details.
- you focus on the button,
- you keydown-enter and this will trigger
click
event. - focus to "#modal" before you keyup-enter
- then
keyup
event will triggered when you keyup-enter
suggest 2 ways.
- check whether it is
clickevent
orkeyevent
withevent.detail
- check whether it is
document.getElementById('testButton').addEventListener('click', e => {
if (e.detail != 0) {
document.getElementById('modal').focus();
}
});
document.getElementById('modal').addEventListener('keyup', e => {
console.log('Modal element triggered!');
});
document.getElementById('modal').addEventListener('focus', e => {
console.log('focus!');
});
:focus {
outline: 3px solid #3f3;
}
<div id="modal" tabindex="-1">Some content here</div>
<button id="testButton" >Focus on content</button>
Keyup event behavior on tab
I ended up using this solution:
HTML:
<form id="myform">
<input id="firstfield" name="firstfield" value="100" type="text" />
<input id="secondfield" name="secondfield" value="200" type="text" />
</form>
jQuery:
jQuery(document).ready(function () {
$('#firstfield').keyup(function (e) {
var charCode = e.which || e.keyCode; // for cross-browser compatibility
if (!((charCode === 9) || (charCode === 16)))
alert('Handler for firstfield .keyup() called.');
});
$('#secondfield').keyup(function (e) {
var charCode = e.which || e.keyCode; // for cross-browser compatibility
if (!((charCode === 9) || (charCode === 16)))
alert('Handler for secondfield .keyup() called.');
});
});
This solution doesn't run the alert if the key is tab, shift or both.
Solution: http://jsfiddle.net/KtSja/13/
Related Topics
Notices for Sequence After Running Migration in Rails on Postgresql Application
Creating Permutations from a Multi-Dimensional Array in Ruby
Converting from Xml Name-Values into Simple Hash
Net::Ssh Sudo Command Hangs After Entering Password
Regex, How to Match Multiple Lines
How Is Each_With_Object Supposed to Work
Force Browser to Download File Instead of Opening It
Which Ruby Version am I Really Running
Ruby Timeouts and System Commands
How to Calculate How Many Years Passed Since a Given Date in Ruby
How to Test 'Rand()' with Rspec
How to Get Past "Http://Gems.Rubyforge.Org/ Does Not Appear to Be a Repository" Error Message
Ruby Gets/Puts Only for Strings