This is driving me nuts. Its a tough one to explain but I'll have a go.
I have one input text field on the front page of my site. I have coded a keydown event observer which checks the keyCode and if its ENTER (or equiv), itll check the input value (email). If the email is valid and unique in the DB itll submit the form. Basic stuff, or so you would think.
If I type my email address in the field and hit enter, it works fine in all browsers. However, if I type the first couple of letters, and then use the arrow keys to select the email from the history dropdown box (hope you know what I mean here), and then press enter the result is different. The value of the form field is being captured as just the couple of letters I typed, and therefore the validation is failing. It seems that when I press the enter key to "select" the email from the history dropdown, the browser is interrupting that as if I was typing.
In Chrome and Safari it works as it should. As it should means that when you press enter to "select" the email from the history dropdown, all it does is puts that email address into the text box. Only on the second ENTER key press does it then trigger the event observer, and the email is validated.
Hope somebody can shed some light on why this is happening... My gut feeling is its a browser thing and will be something I cant fix.
Thanks
Lee
EDIT:
To add clarification to my question let me add that Im using the "keydown" event to capture the moment when the enter key is pressed. I have tried the "keyup" event and this solved my problem above, but then I cant seem to stop the form submitting by itself. The "keyup" event triggers AFTER the default behaviour, therefore its not the right choice for this.
FURTHER EDIT:
Thank you again, and btw, your English is excellent (in response to your comment about bad English).
I have changed my event handler from this:
$("emailInputBox").observe("keydown", function(event) {
return submitViaEnter(event, submitSignupFormOne);
});
to this:
$("emailInputBox").observe("keydown", function(event) {
setTimeout(submitViaEnter.curry(event, submitSignupFormOne),0);
});
submitViaEnter:
function submitViaEnter(event, callback) {
var code = event.keyCode;
if (code == Event.KEY_RETURN) {
event.stop();
return callback(event);
}
return true;
}
Seems to work but the problem now is that the browser is permitted to carry out the default action before running the submitViaEnter function which means the form is being submitted when I hit ENTER.
Answer to the original question
Yeah, it's a Gecko bug (not Mac-specific though).
The last part of this comment contains the description of the work-around: use the time-out.
[edit] since you asked for the clarification of the bug
When you press Enter and the auto-complete is active, Firefox (erroneously) first fires the page's key handler, then the browser's internal key handler that closes the autocomplete popup and updates the text area value, while it arguably should just fire it at the autocomplete popup and only let the page know the textbox value changed.
This means that when your key handler is called, the autocomplete's handler hasn't run yet -- the autocomplete popup is still open and the textbox value is like it was just before the auto-completion happened.
When you add a setTimeout call to your key handler you're saying to the browser "hey, run this function right after you finished doing stuff already in your P1 to-do list". So the autocomplete's handler runs, since it's already in the to-do list, then the code you put on a time-out runs -- when the autocomplete popup is already closed and the textbox's value updated.
[edit] answering the question in "Further edit"
Right. You need to cancel the default action in the event handler, not in the timeout, if you want it to work:
function onKeyPress(ev) {
if (... enter pressed ...) {
setTimeout(function() {
... check the new textbox value after letting autocomplete work ...
}, 0);
// but cancel the default behavior (submitting the form) directly in the event listener
ev.preventDefault();
return false;
}
}
If you still wanted to submit the form on Enter, it would be a more interesting exercise, but it doesn't seem you do.
ok sorted it. Thanks so much for your help. It was the curry function that I was missing before. I was trying to work on the event inside the scope of the setTimeout function.
This works below. The submitViaEnter is called from the eventobserver and responds to the keyDown event:
function submitViaEnter(event, callback) {
var code = event.keyCode;
if (code == Event.KEY_RETURN) {
event.stop();
setTimeout(callback.curry(event),0);
// return callback(event);
// return false;
}
return true;
}
Stopping the default action inside the eventObserver meant that no characters could be typed. So I stuck inside the if ENTER key clause.
Related
My question is about react, onSubmit and preventDefault.
I've got a form, which handles between 2 - 4 steps of user input depending on certain cases.
<Form>
{StepRendersHere}
</Form>
The form has a onSubmit event that prevents default (and stopPropagation).
When using the button for "next step" the event fires, and the form is NOT submitted.
But when using the enter key, the event is fired, but the form is posted. This results in the site refreshing with the form data as url parameters.
The weird thing is that if none of the buttons in the form has type="submit". The onSubmit doesn't even fire on enter key.
isDefaultPrevented returns true in both cases.
Any hints/thoughts on how I can prevent the form from posting when pressing enter? My issue is with Enter key posting the form, despite preventDefault.
Have tried binding the enter key to a event that prevents default, doesn't work. Might have done it the wrong way though.
UPDATE (implementation)
<Form onSubmit={this.inc_step} id="applicationform">
{FormStepRenderedHere}
</Form>
inc_step = e => {
e.preventDefault();
e.stopPropagation();
alert( e.isDefaultPrevented() )
let new_step = this.state.current_step + 1;
alert('INSIDE INC STEP');
if (this.validateForm()) {
this.setState({
current_step: new_step
})
}
}
UPDATE (FIXED IT)
I found a solution, and want to share if anyone else has the same problem.
My solution however might be unique to semantic ui, which i'm using. I solved it by putting as={Form.Group} on the form, mening it wont render as a form, with its standard events, such as enter key submit. Now the enter key does nothing, as I wanted it.
Thank you for the comments!
A much easier way to accomplish this is to add a button element to your form and add the display none css attribute (if you don't want to see the button).
The button automatically adds the ability to use the enter key with onSubmit.
I found a solution, and want to share if anyone else has the same problem.
My solution however might be unique to semantic ui, which i'm using. I solved it by putting as={Form.Group} on the form, mening it wont render as a form, with its standard events, such as enter key submit. Now the enter key does nothing, as I wanted it.
So actually not rendering the form as a form to begin with was the solution.
So (just to start with "so") I want to create a greasemonkey script for a qwebirc platform. I need to send replies automatically based on some events that happen. For those who don't know, once logged in the qwebirc, there is an input text field at the bottom of the screen where you can write your reply and then, by pressing enter, the reply is sent to the server. The input field is contained in a form element, but the form has no submit button.
I can populate the input field (no problem) by writing to its "value" attribute, but I found no way to "submit" the reply to the server. I tried calling the .submit() method on the container form element, but that simply reloads the page (so it's sending to itself - and that makes sense, 'cause there's no "action" attribute on the form element). It seems to me that the only explanation is that once the enter key is pressed in the input field there's a method that's called somewhere on the qwebirc.js.
I can't find the code responsible for this action (though I worked that in Chrome, I set an Event Listener Breakpoint on the Keyboard - Input, and that stopped me when I pressed the enter key and pointed me to the beginning of some function) because the script is minified and there's no way for me to know what those "m", "n", "p", "t" etc mean. If I had the uncompressed version, I could scan it and, maybe, find it out. I also tried downloading the qwebirc project, but there are loads of files there - whereas on the server I'm trying to write the greasemonkey script there's a single script.
The main idea here is that I guess the enter key press simulation should trigger the sending function - wherever and whichever that may be.
In order to do this I found on stackoverflow some questions with the same subject - the simulation of enter key press. I tried that code:
function simulate() {
var evt = document.createEvent('KeyboardEvent'),
input = document.querySelector('.keyboard-input');
evt.initKeyboardEvent(
'keydown',
true,
true,
window,
false,
false,
false,
false,
13,
0
);
input.dispatchEvent(evt);
}
The event is created (I can see it in my DOM panel in FireBug), but no action whatsoever is taken. I mean why doesn't the .dispatchEvent() behave just like a real enter key press ?
Thanks in advance.
For the purposes of this answer, I'm going to assume that the message input pseudo-form is like others - i.e. the message can be sent by either pressing Enter or clicking a Send button.
You've tried the former; it didn't work. It's possible that the page is waiting for the Send button to be clicked (which may be triggered by an Enter keypress (though no, I don't know why your event isn't working - I'm unfamiliar with event intricacies)). Instead, then, try that.
Also, take note: IE uses fireEvent not dispatchEvent - so if you're in IE, this may be the problem.
To fire a click on the Send button:
var e = document.createEvent("MouseEvents");
e.initEvent("click", true, true);
e.target = "button#send";
if(document.fireEvent) {
document.fireEvent(e);
}
else {
document.dispatchEvent(e);
}
Change the string assigned to e.target to the CSS selector that uniquely identifies the Send button.
Scenario:
I have a RadCombobox and I have attached functions to most of the events.
One event of the combobox is OnClientBlur and I am using this to check whether value in Combo is "Unassigned" or not. If it is "Unassigned" I need to cancel the onblur event and keep the focus on to the same combo.
This is the javascript which I has been used to cancel the event.
if (sender.get_text() === "Unassigned") {
eventArgs.get_domEvent().preventDefault();
return false;
}
Problem:
When the user tabs out first time of the ComboBox the event gets cancelled and the focus stays on the same combo box (in this case it is the 3rd Combo).
But when the user hits the tab button again the focus moves to the next control.
When I debugged the code I found that when the user first hits the tab button, following line works
eventArgs.get_domEvent().preventDefault();
I can see the preventDefault function, see following snapshot.
but when the user hits the tab button again I get an error and cannot see preventDefault function, see following snapshot
I am not able to understand what is going wrong here. Anyhelp would be appreciated.
Your problem, revolves around the difference between MouseEvents and KeyEvents. And also the way Telerik implement the OnClientBlur event. As far as it doesn't point to a specific type of browser event, each time it gets triggered
As you see in the first snapshot you got clientX and clientY, which means your OnClientBlur derived from a MouseEvent.
Whereas in the second one you got altKey, altLeft, and also there is no button property, which means that this one is a KeyEvent.
The other point here is as you have these fields in the output:
e.bookmarks
e.behaviorPart
e.behaviorCookie
Means you are using one of the old versions of IE4+ to IE7 or IE8, which they have cancelBubble instead of preventDefault.
Sometimes events are not cancelable, and using event.cancelable you can make sure if the current event is cancelable or not.
At the end to fix you code you can simply do this:
if (sender.get_text() === "Unassigned") {
var domEvent = eventArgs.get_domEvent();
if(domEvent.cancelable){
if(typeof(domEvent.preventDefault)==="function")
domEvent.preventDefault();
else
domEvent.cancelBubble = true;
return false;
}
else{
//you can not cancel the event, do something else to make it manageable
}
}
I have a text field which will accepts only numbers. When the user types any characters and moves out of the textfield,
using onchange I am checking whether user have entered Number or characters. So when user press tab , using onchange the value is checked.
When the user press Enter button, it is set as window.event.keycode =9; as IE supports this. To make it work in other browsers,
I have written logic to move the focus whenever the user presses the enter button.
The problem which I am facing is in Firefox, when the user presses enter button in the text field, now onchange is called as well as onsubmit is also called, which makes my page to refresh again.
The logic which I have written to move the focus to next item , is also working. But I don't know why, onchange and onsubmit is called.
This project composes of huge amount of code, thats why I am not able to post a piece of code.
Any idea why it is working like this?
Some browsers have a global event object, other send the event object to the event handler as a parameter. Chrome and Internet Exlporer uses the former, Firefox uses the latter.
Some browsers use keyCode, others use charCode.
Enter key code is 13
function Numberonly() {
var reg = /^((\d{1,8}(\.\d{0,5})?%)|(\d{1,8}(\.\d{0,5})?))$/;
if (!reg.test(($("#txtunitId").val()))) {
$("#txtunitId").val('');
return false;
}
}
<input type="text" id="txtunitId" style="float: left;" onkeyup="Numberonly();" />
jsfiddle.net/hQ86t/20
want to create a password field where I want to check for capsLock on/off on keystroke. Once a user enters a value in smallcase and try to another field want to validate the password value. Thus want to use onkeypress for every key pressed and then onblur at the end.
But the problem I am facing is every time onkeypress is checked onblur is also executed.
<input type="password" size=50 id='r5PswFld' name="name" value="" onkeypress="checkCapsLock(event)" onblur=chkPsw(this.id) >
can anyone help me how to attain this.
thanks in advance...
better if I am able to do this using only javascript/html/css I me no other technologies like jquery...
This event is getting fired because you in checking the other checkbox input, you are blurring focus away from the current control.
Attach the onblur at the start your checkCapsLock(event) :
document.getElementById("r5PswFld").onblur = function(chkPsw(this.id)'){};
If you find yourself having to perform an action that will focus away, detach it:
document.getElementById("r5PswFld").onblur = function(){};
Next time you fire checkCapsLock it will reacttach if you need to. You could then also remove the onblue attribute completely from your code.
That said, be careful of any onblur validation. If is obtrusive (like an alert) then it could quickly get very frustrating for the user.
EDIT
In repose to the comment below, I thought I'd correct for the problem of other blur bindings. I'll use jQuery for preference.
The correct solution would look something like:
function MyBlurFunc(){
chkPsw(this.id);
}
To bind:
$("#r5PswFld").blur(MyBlurFunc);
To unbind
$("#r5PswFld").unbind('blur', MyBlurFunc);
Unfortunately, onblur will get called whenever focus is left from the field, meaning if you open some sort of message box informing the user of having capslock on, you're removing focus and thus trigger the onblur event.
An alternative might be to activate a flag which you assign to be true prior to opening a message box so that in the case in which you enter chkPsw, you can ignore it.
In other words:
var flgEventsOff = false;
function checkCapsLock(event) {
if (fieldValueIsUpper) {
flgEventsOff = true;
alert('Please turn off capslock!');
flgEventsOff = false;
}
}
function chkPsw(id) {
if(!flgEventsOff) {
// Validate password
}
}
No, the blur event won't be executed the same time a keyPress event is fired. I assume you have an alert() statement within your checkCapsLock() event handler, which causes the loss of focus.
Why would you not just change it to lowecase on the onblur event before it validates?