Focus out on enter press not working properly - javascript

I have some input fields and a HTML table on my UI to input some data, my HTML table have some input field inside my HTML table and doing some calculations also all that are working fine
What I am doing is:
I have some input fields inside my table so when I press on tab I am focusing one next input field
now there is last input field which is Disc% here after pressing tab I am creating new row (on focus out) , but that's not a good user interface because whenever I am clicking outside the Disc% field it is crating new row which is not correct
What I am trying to do is:
After disc% when I press enter I want to create a new row so that it will be good for user
I have tried doing this but it is not working correctly as when I reach Disc% and press enter it does nothing and when I focus out and again come back to Disc% and press enter then it creates new row but on one press it shows three times, I don't know what's wrong
Please check my Fiddle, as I have so many calculation that's why code is bit lengthier but I have commented the line where the issue is
when target matches disc% I am doing like below
if (e.target.matches('[name=discPercentagetd]')) {
$(document).keypress(function(event) { // here I am trying to create new row when enter is clicked
var keycode = event.keyCode || event.which;
if (keycode == '13') {
alert("presed")
calcDiscount(e.target.parentElement.parentElement)
if ($(row).parent().find('tr').length - $(row).index() === 1) {
rowappend(e.target.parentElement.parentElement.parentElement)
}
}
});
}
I am doing it like $(document).on('focusout', (e) => { because ItemName field in my table is autoComplete and when creating new row I want it to behave like the above.

What you need to do is move the keypress function out of the focusout function that you have. JSFiddle
Because you are checking to see if they have pressed enter inside the focus out function, it is not behaving as you would expect.
After moving it outside of that function it behaves as expected, the alert is only triggered once, and the row is created even when focus is still inside the input element.
$(document).on('focusout', (e) => {
const row = e.target.parentElement.parentElement
if (e.target.matches("[name=itemNametd]")) { // whene focus is out from itemNametd
getValues(e.target.parentElement.parentElement)
}
if (e.target.matches('[name=unitQtytd]')) { //when focus is out from unitQty
calc(e.target.parentElement.parentElement)
}
});
// Move this outside of the above focusout function,
// you will also need to rename all of the e elements to event,
// or the other way around. Also include line where you declare the row variable
$(document).keypress(function(event) {
const row = event.target.parentElement.parentElement
var keycode = event.keyCode || event.which;
if (keycode == '13') {
alert("presed")
calcDiscount(event.target.parentElement.parentElement)
if ($(row).parent().find('tr').length - $(row).index() === 1) {
rowappend(event.target.parentElement.parentElement.parentElement)
}
}
});
Not question related (since you were talking about user experience):
One thing to keep in mind is "How will the user know to press enter to create a new row". It may be good to also include a button to add a row, and maybe a little element that reveals more information on hover that explains they can use enter to make a new row.
Also, consider styling the total row to look like it is apart of the table, that way the user would know what the numbers match up to.

Related

Prevent contenteditable="plaintext-only" div from creating a new line

I have a div that is used as user input:
<div id="chat-message-input" contenteditable="plaintext-only">
When the user hits the enter key (and is not holding the shift key), the text from the user is submitted.
<script>
document.querySelector('#chat-message-input').onkeyup = function(e) {
// User hits enter key and is not holding shift
if (e.keyCode === 13 && event.shiftKey != 1) {
//Click submit button
document.querySelector('#chat-message-submit').click();
// Clear input field
document.getElementById('chat-message-input').innerHTML='';
};
</script>
Problem: There is a brief moment where the div creates a new line because the enter key was pressed, before the content in the div is cleared.
I only want a new line to be created under these circumstances:
The user's input text reaches the end of the line
The user holds shift and presses enter
Does anyone know how I can prevent a new line from being created given the above requirements?
As suggested by A Haworth, I also intercepted onkeydown (in addition to onkeyup) and prevented the default. This seemed to work well.
document.querySelector('#chat-message-input').onkeydown = function(e) {
// User hits enter key and is not holding shift
if (e.keyCode === 13 && event.shiftKey != 1) {
e.preventDefault()
}
};
This made the input field really solid, which is necessary for my real-time chat app. Thanks!

Simulate Enter press key without specifing the element

I tried sendkeys plugin and others.
Is there a way to simulate Enter key pressed without element?
$("div.myclass").click(); // Put focus on my element - works
$("div.myclass span").sendkeys("Test"); // using sendkeys plugin send the input - works.
setTimeout(function(){
console.log('trigger');
//$("div._1mf").trigger({type: 'keydown', key: 'enter'}); // this one just insert new line...
e = jQuery.Event("keypress")
e.which = 13
$("div.myclass").keypress(function(){ // this one doesn't work
}).trigger(e)
},2000);
I have already element focused and input inserted, I need just simulate Enter press key to send the text, how that can be done?
I think what you might want to do is instead, submit the form that your input resides in?

JavaScript & submit form & Enter & set focus to next element

I'm trying to create a simple submit form in WYSIWYG Web Designer 10 but I have a BIG problem with Enter key. There are several edit boxes on the form and I'd like to have the following functionality (via JavaScript):
1. Enter key on an Edit Box should not submit the form.
2. Enter key on an Edit Box should set focus to the following element (edit box or a submit button). Submit button is the last element in tabIndex order.
3. To submit the form user must:
either click the submit button,
or press Enter when the submit button has the focus.
4. Must work in any browser.
This is a snippet that works quite good (it sets focus to the next element):
var elem = document.activeElement;
var tidx = +(elem.getAttribute('tabindex')) +1,
elems = document.getElementsByTagName('input');
for (var i=elems.length; i--;)
{
var tidx2 = elems[i].getAttribute('tabindex');
if (tidx2 == tidx) elems[i].focus();
}
The only problem I have is Enter key (keyCode) validation which should precede the code to change focus. I have been testing in FF 32, PaleMoon 25 (FF clone), Chrome 38 & IE 10.
Thank you very much for your time in advance.
P.S. I'm a newbie in JavaScript. I use to work with MS Access where similar problem would be solved within two minutes.
I have spent several hours on this simple task but no luck. I have tried many examples that I've found on the web (incl. stackoverflow.com). As to event handling (where I'm trying to test the keyCode) various browsers behave differently.
I tried and mixed a lot of found in web and created this one.
So far it's working for me... just give it a try
$(document).on('keypress', 'input, select, checkbox, radio, button', function (e) {
return focusNextOnEnter(e, this);
})
and the function somewhere in your JS file.
function focusNextOnEnter(e, selector) {
var longSelector = 'input:visible:enabled:not([readonly="readonly"]), textarea:visible:enabled:not([readonly="readonly"]), select:visible:enabled, button:visible:enabled';
var keyCode = e.keyCode || e.which;
if ($(selector).is(':not(textarea)') // it's not a textarea - enter in text area
&& keyCode === 13 // it's enter key
&& !($(selector).attr('id') === 'submitButton')) // it's not submitButton, save-on-enter here
{
e.preventDefault();
$(longSelector)[$(longSelector).index($(selector)) + 1].focus();
return true;
}
}
instead of the last check
$(selector).attr('id') === 'submitButton'
you can always check
$(selector).is('[type="submit"]')
this will hopefully return what you are looking for i.e. submit on enter on submit button

Safari issue with text inputs, text is selected as user enters it causing text to be lost

I have the following input element on my page:
<input class="input" name="custom_fields[new]" placeholder="Enter placeholder" type="text">
I have a Twitter Flight event listener on this element that looks like this:
this.on('keyup', {
inputsSelector: this.updateViewInputs
});
Which triggers this method:
this.updateViewInputs = function(ev) {
var isDeletionKeycode = (ev.keyCode == 8 || ev.keyCode == 46);
// Remove field is user is trying to delete it
if (isDeletionKeycode && this.shouldDeleteInput(ev.target.value, this.select('inputsSelector').length)) {
$(ev.target.parentNode).remove();
}
// Add another field dynamically
if (this.select('lastInputsSelector')[0] && (ev.target == this.select('lastInputSelector')[0]) && !isDeletionKeycode) {
this.select('inputsContainer').append(InputTemplate());
}
// Render fields
that.trigger('uiUpdateInputs', {
inputs: that.collectInputs()
});
}
And finally triggers uiUpdateInputs:
this.after('initialize', function() {
this.on(document, 'uiUpdateInputs', this.updateInputs)
});
this.updateInputs = function(ev, data) {
// Render all inputs provided by user
this.select('inputListSelector').html(InputsTemplate({ inputs: data.inputs }));
}
All of this functionality works as expected on Chrome and Firefox. Users can type into the input and see the page change in 'real time'. Users also get additional fields that they can enter text into and see the page change.
The issue in question arises when using Safari, as a user enters text into the described input field the text in the input field becomes highlighted (selected) and when they enter the next character all the content is replaced with that single character. This results in the user not being able to enter more than 1 or 2 characters before having them all replaced by the next entered character.
I have tried several approaches to fix this problem but none have worked, they include:
Using a setTimeout to delay the code run on the keyup event
Using Selection to try to disable the selection of the text using collapseToEnd.
Using click,focus,blur events to try to remove the selection from the entered text
Triggering a right arrow key event to try to simply move the cursor forward so they user does not delete the selected text
Using setInterval to routinely remove selections made by the window
I am very confused why this is happening and I am wondering if this is a bug in webkit with Flight. I see no issue with the Firefox or Chrome versions of this page. Thanks for any help!
This seems to be an issue with certain versions of Safari. When listening for the keyup function in javascript it will automatically select all of the text in the box and subsequently delete it all when the next key is typed. To prevent this from happening call preventDefault on the event object that is passed to the keyup function.
this.on('keyup', function(e) {
e.preventDefault()
});

How to disable tab key globally except for all forms in a page with JavaScript?

I'm making a single page app that is launching next week, for a pretty huge client, and going live for a pretty big event and well, there's still a ton to finish before then.
There's 100+ 'pages' which are all loaded within a single 700px x 600px window, and I had learned not long ago you could tab through the page/sections, which in-turn would break the app because it would bring focus to hidden off-screen elements, so for this reason, I disabled the tab key for the entire app.
But now there are a couple places where we have a form with a handful of input fields which you are not able to tab through as you fill in the form. It's a pain in the ass.
I need to make it so you can tab through the form fields, but only the form fields. I have the tabindex attribute set for the form, and have tried to make inputs tab enabled but was not able to make it work without causing the app to jump to hidden sections.
Here's the function I need to change so it will disable tab key except from input to input fields in a form.
window.onkeydown = function(e) {
if (e.keyCode === tab) {
return false;
}
}
I tried to do this, which obv didnt work lol
$('input').keydown(function(e) {
if (e.keyCode === tab) {
return true;
}
});
Thanks :)
I made some fixes to what #Joseph posted for an answer to this that handle being able to shift + tab through inputs of a form so you can reverse direction. It was a very annoying thing for me before when I first had to find a way to do this, and didn't have time to waste anymore trying to find a complete solution for this until now. Here it is.
$(function() {
// gather all inputs of selected types
var inputs = $('input, textarea, select, button'), inputTo;
// bind on keydown
inputs.on('keydown', function(e) {
// if we pressed the tab
if (e.keyCode == 9 || e.which == 9) {
// prevent default tab action
e.preventDefault();
if (e.shiftKey) {
// get previous input based on the current input
inputTo = inputs.get(inputs.index(this) - 1);
} else {
// get next input based on the current input
inputTo = inputs.get(inputs.index(this) + 1);
}
// move focus to inputTo, otherwise focus first input
if (inputTo) {
inputTo.focus();
} else {
inputs[0].focus();
}
}
});
});
Demo of it working http://jsfiddle.net/jaredwilli/JdJPs/
Have you tried setting tabIndex="-1" on all elements that you don't want to be able to tab to? I think that's a much better solution.
Otherwise, within your key handler function test event.target (or event.srcElement in IE) to see if the event originated with a form element. You seem to be using jQuery, so you could assign an "allowTab" class just to the fields in your form and then do this:
$(document).keydown(function(e) {
if (!$(e.target).hasClass("allowTab"))
return false;
});
Or
if (e.target.tagName !== "input")
// etc
what we do is to determine what input is next in line and skip to it!:
http://jsfiddle.net/qXDvd/
$(document).ready(function() {
//gather all inputs of selected types
var inputs = $('input, textarea, select, button');
//bind on keydown
inputs.on('keydown', function(e) {
//if we pressed the tab
if (e.keyCode == 9 || e.which == 9) {
//prevent default tab action
e.preventDefault();
//get next input based on the current input we left off
var nextInput = inputs.get(inputs.index(this) + 1);
//if we have a next input, go to it. or go back
if (nextInput) {
nextInput.focus();
}
else{
inputs[0].focus();
}
}
});
});​
may need some optimization but it works. this was originally meant to skip non-form elements. you can add selectors not to skip if you like. additionally, you can add logic for the Shift+Tab behavior (maybe before the tab logic)
obviously, it will still go through some elements according to how they appear in the source. however, why not just remove those hidden elements from the DOM but still keep track of them using the methods found in this question. that way, you won't have the pain of having to cycle back and forth through off-screen elements.

Categories