Focusing a Bootstrap button for keyboard enter - javascript

I have a Bootstrap 3.0 button on a web page. The button is not part of a form. When this page renders, I would like for the button to be clicked if the user hits return on the keyboard. I have a Marionette event listener set up to handle the click event.
Here is my button:
<button class="btn btn-primary js-new pull-right">New facility</button>
How do I do this?
I have tried several things - including what I thought was the obvious solution: executing $(".js-new").first().focus(). This does not work.

If I understand correctly, you'd like to trigger the click handler for a certain button when "return" is hit. If that's the case, this ought to work; $(".js-new").first().click();, assuming your selector is correct.
You can check whether or not your selector is finding an element by using either alert or console.log to display the length of the selector: console.log($(".js-new").length);.
Once you have verified that you have found the correct element, you can trigger whatever click handler(s) are bound to the element by simply calling the .click() function; if no arguments are passed to it, it executes whatever triggers are already on the element.
--
Edit: if you'd simply like to trigger the click handler when enter is pressed, you could bind an event to the return key:
$(document).keypress(function(e) {
if(e.which === 13) {
// enter has been pressed, execute a click on .js-new:
$(".js-new").first().click();
}
});

Related

Can cancel onclick event after blur(focusout)?

Because I have a check function, and check function happens in textarea when blur and click save button.
All things are good except one case. When I in textarea, I directly click the button. This will happen twice check (first check to happen in a blur, and then happen in onclick event). I don't like it.
I solve this problem using two methods.
1: Use one flag to detect whether check before. When click saves button, check this flag.
2: Use mouse-down replaces of onclick method and event.preventDefault. This first check will happen mouse-down, and not trigger blur.
I think the other method. Firs check happens in a blur, and then "not" happen in onclick event. So I want to know Can cancel onclick event after blur(focus out)? If not why? (I don't know how to cancel or I don't find solutions. Thanks.
Code like
blur() {
checkfunction();
}
onclick() {
checkfunction();
save();
}
you can use event.stopPropagation();
example:
blur(){
// code textarea
};
onclick(e){
e.stopPropagation();
// code button
};

Possible bug in fullcalendar's eventClick?

Here is the code snippet in question:
eventClick: function(calEvent) {
if(user != calEvent.modified_by && calEvent.modified_by != 0){
$('.antoconfirm').css("display", "inline-block");
}
$('#fc_edit').click();
$('#title2').val(calEvent.title);
//-----------Submit button click-------------------
$(".antosubmit2").on("click", function(e) {
e.preventDefault();
e.stopImmediatePropagation();
calEvent.title = $("#title2").val();
calEvent.confirm = 0;
calEvent.backgroundColor = '#ddbd39';
dbTitle = calEvent.title;
//ajax goes here, works fine
calendar.fullCalendar('updateEvent', calEvent);
$(".antosubmit2").off("click");
$('.antoclose2').click();
});
//---------------------------------------------------
//-----------Close button click-------------------
$(".antoclose2").on("click", function() {
console.log(calEvent.title);
$(".antoclose2").off("click");
});
//---------------------------------------------------
return false;
},
$('#fc_edit').click(); calls the modal in which the editing is done. There are two buttons with the classes "antosubmit2" and "antoclose2". You click on an event, the modal comes up, you change the title, click submit, the modal goes away and voila, the title is changed(from "new1" to "new3" in this example):Test events, title change
When ONLY the submit button is used, everything works fine, you can change one event after the other without incident. On the other hand, when you use the close button on one event and try to change the title on another, the first event will be changed:Test events, title change after close
Now at the "ajax goes here, works fine" part is an ajax POST, that sends the correct data despite what the calendar shows and after a page reload everything is edited the way it should be.
Is this a bug with fullcalendar's event rendering or does my code fail somewhere?
I think you need to run .off against all your button click handlers whenever any of your buttons is used. At the moment you only remove the handler for the button that was actually clicked. If you don't remove them, those handlers will remain and get used again if the other button is clicked in future. This is exactly the scenario you have run into.
In the case you described, I suspect because when you closed the first event, you didn't remove the "click" handler related to the "submit" button that went with that event. Then, when you changed the title of the second event, it ran the "click" handler for both events, because you never removed the first handler. Hence why the title for the first event gets changed when it shouldn't.

JQuery Click event loads before change event

I am using a simplified example to describe the issue I am facing.
I have the following HTML markup:
<input ng-model="something" style="margin-top:8px;"/>
And, I have two HTML buttons:
<button id='submit'>Save</button>
<button id='btnGetAnalyzerInput'>Generate Analyzer File </button>
I used jQuery's change event on my input (to track whether any changes have been made to the input - by maintaining a simple JS variable).
When the user clicks "Generate Analyzer file button", what I want to is this:
Look up the JS variable to find out whether any changes have been made.
If yes, then prompt the user to save changes (window.dialog)
However, I find that when the focus is still on the input element, and when the button is clicked, the click event runs before the OnChange event. In all other cases, it is the OnChange event which gets fired before the click event (and so my code works as expected).
Is there any way to ensure that for such a scenario, the click event runs after the onChange event?
I am using Google Chrome to test my application.
Note :
Both events work as expected - the OnChange event gets fired when the textbox loses focus.
I can't use the keypress event since I want to track changes.
You could have the click event call the same function as the OnChange event. Something like this:
function OnChange(){
//Do stuff for on change;
}
function ClickEvent(){
OnChange();
//continue with generate stuff
}
You you may need to set up and pass in arguments to the OnChange function, depending on how you are accessing the data you need. If you need more guidance, post more of your code.

Blur event stops click event from working?

It appears that the Blur event stops the click event handler from working? I have a combo box where the options only appear when the text field has focus. Choosing an option link should cause an event to occur.
I have a fiddle example here: http://jsfiddle.net/uXq5p/6/
To reproduce:
Select the text box
Links appear
Click a link
The blur even occurs and the links disappear
Nothing else happens.
Expected behavior:
On step 5, after blur occurs, the click even should also then fire. How do I make that happen?
UPDATE:
After playing with this for a while, it seems that someone has gone to great lengths to prevent an already-occurred click event from being handled if a blur event makes the clicked element Un-clickable.
For example:
$('#ShippingGroupListWrapper').css('left','-20px');
works just fine, but
$('#ShippingGroupListWrapper').css('left','-2000px');
prevents the click event.
This appears to be a bug in Firefox, since making an element un-clickable should prevent future clicks, but not cancel ones that have already occurred when it could be clicked.
Other things that prevent the click event from processing:
$('#ShippingGroupListWrapper').css('z-index','-20');
$('#ShippingGroupListWrapper').css('display','none');
$('#ShippingGroupListWrapper').css('visibility','hidden');
$('#ShippingGroupListWrapper').css('opacity','.5');
I've found a few other questions on this site that are having similar problems. There seem to be two solutions floating around:
Use a delay. This is bad because it creates a race condition between the hiding and the click event handler. Its also sloppy.
Use the mousedown event. But this isn't a great solution either since click is the correct event for a link. The behavior of mousedown is counter-intuitive from a UX perspective, particularly since you can't cancel the click by moving the mouse off the element before releasing the button.
I can think of a few more.
3.Use mouseover and mouseout on the link to enable/disable the blur event for the field. This doesn't work with keyboard tabing since the mouse is not involved.
4.The best solution would be something like:
$('#ShippingGroup').blur(function()
{
if($(document.activeElement) == $('.ShippingGroupLinkList'))
return; // The element that now has focus is a link, do nothing
$('#ShippingGroupListWrapper').css('display','none'); // hide it.
}
Unfortunately, $(document.activeElement) seems to always return the body element, not the one that was clicked. But maybe if there was a reliable way to know either 1. which element now has focus or two, which element caused the blur (not which element is blurring) from within the blur handler. Also, is there any other event (besides mousedown) that fires before blur?
click event triggers after the blur so the link gets hidden. Instead of click use mousedown it will work.
$('.ShippingGroupLinkList').live("mousedown", function(e) {
alert('You wont see me if your cursor was in the text box');
});
Other alternative is to have some delay before you hide the links on blur event. Its upto you which approach to go for.
Demo
You could try the mousedown event instead of click.
$('.ShippingGroupLinkList').live("mousedown", function(e) {
alert('You wont see me if your cursor was in the text box');
});
This is clearly not the best solution as a mousedown event is not achieved the same way for the user than a click event. Unfortunately, the blur event will cancel out mouseup events as well.
Performing an action that should happen on a click on a mousedown is bad UX. Instead, what's a click effectively made up of? A mousedown and a mouseup.
Therefore, stop the propagation of the mousedown event in the mousedown handler, and perform the action in the mouseup handler.
An example in ReactJS:
<a onMouseDown={e => e.preventDefault()}
onMouseUp={() => alert("CLICK")}>
Click me!
</a>
4.The best solution would be something like:
$('#ShippingGroup').blur(function()
{
if($(document.activeElement) == $('.ShippingGroupLinkList'))
return; // The element that now has focus is a link, do nothing
$('#ShippingGroupListWrapper').css('display','none'); // hide it.
}
Unfortunately, $(document.activeElement) seems to always return the
body element, not the one that was clicked. But maybe if there was a
reliable way to know either 1. which element now has focus or two,
which element caused the blur (not which element is blurring) from
within the blur handler.
What you may be looking for is e.relatedTarget. So when clicking the link, e.relatedTarget should get populated with the link element, so in your blur handler, you can choose not to hide the container if the element clicked is within the container (or compare it directly with the link):
$('#ShippingGroup').blur(function(e)
{
if(!e.relatedTarget || !e.currentTarget.contains(e.relatedTarget)) {
// Alt: (!e.relatedTarget || $(e.relatedTarget) == $('.ShippingGroupLinkList'))
$('#ShippingGroupListWrapper').css('display','none'); // hide it.
}
}
(relatedTarget may not be supported in older browsers for blur events, but it appears to work in latest Chrome, Firefox, and Safari)
If this.menuTarget.classList.add("hidden") is the blur behavior that hides the clickable menu, then I succeeded by waiting 100ms before invoking it.
setTimeout(() => {
this.menuTarget.classList.add()
}, 100)
This allowed the click event to be processed upon the menuTarget DOM before it was hidden.
I know this is a later reply, but I had this same issue, and a lot of these solutions didn't really work in my scenario. mousedown is not functional with forms, it can cause the enter key functionality to change on the submit button. Instead, you can set a variable _mouseclick true in the mousedown, check it in the blur, and preventDefault() if it's true. Then, in the mouseup set the variable false. I did not see issues with this, unless someone can think of any.
I have faced a similar issue while using jQuery blur, click handlers where I had an input name field and a Save button. Used blur event to populate name into a title placeholder. But when we click save immediately after typing the name, only the blur event gets fired and the save btn click event is disregarded.
The hack I used was to tap into the event object we get from blur event and check for event.relatedTarget.
PFB the code that worked for me:
$("#inputName").blur(function (event) {
title = event.target.value;
//since blur stops an immediate click event from firing - Firing click event here
if (event.relatedTarget ? event.relatedTarget.id == "btnSave" : false) {
saveBtn();
}
});
$("#btnSave").click(SaveBtn)
As already discussed in this thread - this is due to blur event blocking click event when fired simultaneously. So I have a click event registered for Save Btn calling a function which is also called when blur event's related Target is the Save button to compensate for the click event not firing.
Note: Didnt notice this issue while using native onclick and onblur handlers - tested in html.

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