Javascript: on blur getting the event's relatedTarget on mobile safari - javascript

So, I have a form with custom validation that is triggered on input blur event...
works fine
the form submit prevents the form to be submitted if there are validation errors on the page...
effectively what that means is if there is an erroneous message and it's focused.... if you click submit button, first the element's blur is triggered and the submit... but coz the element is
in practice I would have to click submit twice.... first time to re-validate the element and second to trigger submit again...(when all the elements are valid)
so on blur, I do
if ( event.relatedTarget && event.relatedTarget.type === "submit" ) {
...
}
and check if the instigator (of element's blur event) is the submit button...if yes, I skip the validation and trigger submit directly.... (that handles validation itself)..
It works perfectly, even in OSX...
the problem is mobile safari... that simply doesn't populate the event.relatedTarget... (is always null on submit click.... it's populated only on some other element's focus)....
how can I get the instigator on iOS?

I had the same problem where I had to hit the submit button on my form twice (on iOS.) Surprisingly I found that this solution worked:
how to prevent blur running
It was not clear at first but using this solution the mousedown event stops my normal blur event from happening but if you click the "Done" on the iOS keyboard it will let the blur event run because there was no mousedown event.

Related

Selenium's HTML Driver not using jQuery form submission event handlers

Using Selenium and Scalatest, having tested with Chrome, Firefox, IE9 and the default as values for drivers:
I have a form called form. It has onSubmit = 'return false;'
There is a separate event handler defined in some JavaScript file that gets attached.
I have a field in that form called field, and a button called button.
When I type things in to the field by hand, and click on button, everything works as expected.
When I run this, nothing happens:
click on id ("field")
enter("searchTerm")
submit
It seems that the submission occurs, and field's value is set back to "".
However, the (seperate) jQuery event handler for the form submission does not fire.

Conflicts of blur and submit/click events

I have two items
item1 is textbox
item2 is submit button
Now item1 has blur event in jquery. In that blur event I have validation and based on that validation if it fails user will have confirmation message.
So if user press yes he can proceed futher
if user press no that textbox will be blank and need to enter detail again.
So now my issue is that if user enter detail in item1 and directly click on item2, button's submit event rejected and item1's blur event called. So first time is rejected and user have to press 2nd time on button(This is the issue).
So how to know in item1's blur event if user click on item2 than I can proceed further with triggering item2's click event.
Consider this code
var $item1 = $('#item1');
var $item2 = $('#item2');
$item1.on('blur', function (oEvent) {
if ($item2.is(oEvent.relatedTarget)) {
// your blur is caused by click on $item2 a.k.a submit button
} else {
// your blur is caused by smth else
}
});
It checks where your focus was moved and you can add some specific boolean flag to use later on in your submit handler or maybe change your validation somehow.
Please note that blur event is event of loosing focus, focus can go away not only because of clicks, but also because of tab-navigation for example.
UPDATE:
added a jsfiddle http://jsfiddle.net/DbjQc/
Try focusing the text input and then clicking somewhere else. After that try focusing the text input again and then click the submit button - you will see how behavior changes.

Detect browser autoclick

I have some problems in implementing my jQuery plugin.
I need a plugin which shows me some element (popup) and hides it when i click out of bounds of this element.
I implemented this plugin. But I have problems with forms in popup. When I calculate coordinates of clicked element I use pageX and pageY properties.
But it is some interesting things when I try to submit form using ENTER key. When I push ENTER browser triggered 'click' event on submit button, but pageX and pageY of this button is equal 0. In event.target I see my button.
When I click submit button myself - everything is OK.
Question: how can I detect who clicked this button? User or browser? (without any spikes like detecting enter key on input or so on)
Additional: as you can see here events are different (when click on submit and press ENTER). But difference is so small... I see only that 'detail' property is set to 0, when we submit form by ENTER.
Detail property is amount of clicks on element for mouse event.
Is it only way to detect submission? Is it correct?
If you're binding a click handler to a click event and later calling the click programmatically as well as from a user click and want to differentiate the two events in the handler, you can check for eventObject.originalEvent which is set in the user click but not the .click() call.
Example:
$('#el').click(function(evt){ if(evt.originalEvent){ //user click } else { // .click() call } });
How about testing for pageX == 0 AND pageY == 0?
Or even better, assuming it is a form (it implies from your post), why not use .submit() rather then .click()?

Run javascript/jquery after text change but before submit

I have an input element on a form along with a submit button.
I want to run the change event on the input element all whenever a change occurs. The problem is if end user changes text and clicks submit button the code in the change event doesn't run.
Immediately after user clicks the submit button, the form submits (like the change is not getting time to run, the same occurs with blur or focus out).
My controls can be placed on any form, and I do not control the click event of the button.
Help please
If you're wanting to catch whenever input in a textbox is changed try this in the document.ready
$("input[type='text']").change( function() {
$("#SubmitButton").attr('disabled', 'disabled');
// check input ($(this).val()) for validity here
// after text is updated..etc, enable the button
$("#SubmitButton").removeAttr('disabled');
});
may be you want use event.preventDefault
Expanding on #Aleks G's comment, the best thing for you to do is trigger your change handling on more than just the change event. Beyond keyup, I've found you also need to be careful to handle pasting with the mouse (doesn't trigger the keyup or change event):
yourInput.bind('change keyup paste', function() {
// Your code
});

DOM problem with click initiating a focusout event on a different input

I have an <input type=text> with focusout event handler
I have a <button> with click event handler
Focusout checks whether format in input box is correct. It does so by testing input value against a regular expression. If it fails it displays a message (a div fades-in and -out after some time) and refocuses my input by calling
window.setTimout(function() { $(this).focus(); }, 10);
since I can't refocus in focusout event handler. focusout event can't be cancelled either. Just FYI.
Click collects data from input elements and sends it using Ajax.
The problem
When user TABs their way through the form everything is fine. When a certain input box failes formatting check it gets refocused immediately after user presses TAB.
But when user doesn't use TAB but instead clicks on each individual input field everything works fine until they click the button. focusout fires and sets time-out for refocusing. Since time-out is so short focusing happens afterwards and then click event fires and issues an Ajax request.
Question
I have implemented my formatting check as an independent jQuery plugin that I want to keep that way. It uses .live() to attach focusout on all input fields with a particular attribute where format regular expression is defined.
Data submission is also generic and I don't want to make it dependant on formatting plugin. They should both stay independent.
How can I prevent click event from executing without making these two plugins dependant?
Example code I'm fiddling with
After some searching I've seen that all major browser support document.activeElement but I can't make it work in Chrome. FF and IE both report this being the active element, but Chrome always says it's BODY that is active even though click fired on the button element.
Check this code http://jsfiddle.net/Anp4b/1/ and click on the button. Test with Chrome and some other browser and see the difference.
You could use a flag...
Live demo: http://jsfiddle.net/Anp4b/4/
So your question is:
How can I prevent click event from executing without making these two plugins dependent?
Well, you obviously cannot prevent the click event. If the user wants to click the button, he will, and the click event will trigger. There's nothing you can do about that.
So the answer to the above question is: You cannot.
Based on the current conditions, you have to - inside the click handler - retrieve the validation result, and based on that result, decide if form submission should or should not occur.
JS Code:
$("#Name").focusout(function(){
var that = this;
valid = this.value.length ? true : false;
!valid && window.setTimeout(function() {
$(that).focus();
}, 0);
});
$("#Confirm").click(function(e) {
if ( !valid ) { return false; }
e.preventDefault();
alert('AJAX-TIME :)');
});
HTML Code:
<input type="text" id="Name">
<button id="Confirm">OK</button>
Is there are reason you use .focusout instead of .blur?
Using a flag is a good idea, but I would rather use a class on the element. By using classes to determine the state you can also style it accordingly. Here's my example based on your fiddle.
Another solution that hopefully gives the result you are looking for.
1) Create a named click handler:
var clickHandler = function(e){ /** submit form or whatever you want to do**/ };
$("button").click(clickHandler);
2) Add the following to the focusout event when it's failing validation:
$("button").unbind("click", clickHandler).one("click", function(){ button.click(clickHandler); return false;});
You can find an example of this here.

Categories