Handling a JavaScript Popup Occurring on a Keyup Event

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.

  1. you focus on the button,
  2. you keydown-enter and this will trigger click event.
  3. focus to "#modal" before you keyup-enter
  4. then keyup event will triggered when you keyup-enter

suggest 2 ways.


    • check whether it is clickevent or keyevent with event.detail





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



Leave a reply



Submit