Selectively enable enter key in HTML textarea (javascript) - javascript

I am using openjs.com's shortcut handling (1)
to disable the enter key in my html forms. However, inside of textareas in those forms I want enter key to emit the normal CR-LF pair (because that's what users expect).
At the moment assuming I have a form/input structure as follows:
<form id="f1">
<fieldset>
<input>
<textarea id="f2"> ...
The following scripts are run:
shortcut.add('Return', function () { /*empty*/ },
{ 'type':'keydown', 'disable_in_input':false,'propagate':true,
'target':document.getElementById('f1')});"
This effectively disables the enter key.
I have tried using the following code to re-enable it for the textarea:
shortcut.add(\"Enter\", function() { }, {'type':'keydown','propagate':false,
'disable_in_input':false, 'target':document.getElementById('f2') } );
But that does not work. What is the order of propagation of this event? Should it bubble up from the textarea or bubble down from the form element?

It doesn't look like this library was really meant to be used this way. I would hazard a guess that adding any shortcut disables the browser's handling of it entirely, no matter what you do afterwards.
What are you actually trying to accomplish? If you just want to prevent the form from being submitted, you could add a submit event listener for the whole form that calls event.preventDefault().

Related

Live form validation using javascript

I want to do live form validation using javascript like if I type number in text field it should give error message instantly or vice versa.How can I achieve this.
You need to start by detecting changes in the input entries. You can do that easily by using the oninput event (read more here).
Looking at that example:
<script>
window.addEventListener('input', function (e) {
console.log("input event detected! coming from this element:", e.target);
}, false);
</script>
<input placeholder="type here and see console.">
Each time your input value changes, an event will be fired an received in that listener.
In your case, you need to add an event listener for each of the inputs and, instead of doing a console.log in the handler function, just call a generic function that will validate all the values for all the inputs in the form.
For the validations, you can look at multiple libraries, like validate.js or jQuery Validation. Also, take a look at validator.js.

how to handle an "enter" in a q-input / preventDefault on submit?

I have a text input field, something like:
<q-input
#blur="checkTextAnswer"
#keyup.enter="submit"
#keydown="checkEnterKey"
v-model.trim="textInput"
When the user hits enter I want to treat it like a submit, ie to handle the input and not add an extra newline in the text.
It's a bit like preventDefault from JQuery days. I did find this:
https://quasar-framework.org/components/other-utils.html
but seems for more general DOM events
I also tried just modifying the string (str.replace the newline) but even that hack has an ugly delay.
You need to use the vue event modifier ".prevent" in your event. It also needs to be a #keydown event since the "add newline" event is called with #keydown events in inputs of type "textarea".
The solution would be:
<q-input
type="textarea"
#keydown.enter.prevent="submit"
v-model.trim="textInput"
EDIT:
The 'submit' is a method that you have to define. Here's an example I made in codepen:
Codepen example
If you instead want to submit a form when pressing enter you can just use javascript for this.
this.$refs[refKeyYouGaveToYourForm].submit()

How to validate the entire form on field blur instead of just the blurred field

I have a form that uses jQuery validation, using unobtrusive validation to declare rules. Currently I'm using the default submit behaviour where there is no validation on blur until the form is submitted (validating every field in the form), after which subsequent blurs validate just the blurred field.
I'd like to change this behaviour so that after a submit, blurring a single field revalidates the entire form, so that the error summary remains on screen until every issue has been addressed. The behaviour before submit should remain the same.
I've tried the following onfocusout methods based on other SO answers, with no luck:
onfocusout: function(element, event) {
$(element).valid();
}
and
onfocusout: function(element, event) {
this.element(element);
}
Both this.element(element) and $(element).valid() are for triggering validation on a single element. In your case, since you're trying to apply this inside of the options of the .validate() or .setDefaults() methods, you cannot use .valid() as it could potentially trigger an infinite recursion.
That leaves .element(). However, as per the docs, you can only use this on a single field, not the entire form.
How to validate the entire form on field blur instead of just the blurred field
I'd like to change this behaviour ... blurring a single field revalidates the entire form
The solution would be to write an external blur event handler attached to all relevant input elements and trigger the .valid() method attached to your form. Edit the selectors in this generic example for whatever is applicable to your particular form.
$('#myform input[type="text"]').on('blur', function() {
$('#myform').valid(); // <- trigger validation on entire form
});
$('#myform input[type="text"]') selects all text inputs within #myform
$('#myform') selects theformbased onid="myform"`

Is there a way to check a form when it actually changes?

I realize there is a onchange event attribute for the purpose of detecting a change in a form and performing a certain javascript function. However, this requires the user to click outside of the form field, making it very similar to onblur.
Is there actually a way to perform a function when a form changes, without having to wait for the user to click outside of the form?
I know you can use JavaScript timeouts to check the form every few milliseconds, but I would prefer a solution without them. Also, I am not limited to just form elements; I'm okay with using contenteditable divs.
I don't think a code is necessary, but I can add a sample code of what I mean if needed.
jQuery has powerful functions that deliver what you're after, but if you just need to run a simple script, you can use functions such as onkeydown and onkeypress.
<input type="text" onkeydown="myFunction()">
Sources:
W3 Schools - OnKeyPress
W3 Schools - OnKeyDown
If I were to do this myself I would listen to the change event on the inputs of a form. Personally I think this would be easier for you to do using jQuery.
$('form input, form select').change(function() {
console.log('form has been changed');
});
If you want to ensure you catch when any type of input in your form changes (ie. checkbox, select lists, radio buttons etc and not just text) then you could use the following snippet I put together (assuming you're using jQuery)
$('form input[type=text]').keyup(formUpdated);
$('form input[type!=text], form select').change(formUpdated);
function formUpdated() {
alert('input changed');
}
You can see it in action here.
This is all just a nice way of removing the need for this:
<input type="text" onkeyup="formUpdated();">
<select onchange="formUpdated();">
</select>
<input type="radio" onchange="formUpdated();">
<input type="checkbox" onchange="formUpdated();">

Enter triggers button click

I have a page with two buttons. One is a <button> element and the other is a <input type="submit">. The buttons appear on the page in that order. If I'm in a text field anywhere in the form and press <Enter>, the button element's click event is triggered. I assume that's because the button element sits first.
I can't find anything that looks like a reliable way of setting the default button, nor do I necessarily want to at this point. In the absence of anything better, I've captured a keypress anywhere on the form and, if it was the <Enter> key that was pressed, I'm just negating it:
$('form').keypress( function( e ) {
var code = e.keyCode || e.which;
if( code === 13 ) {
e.preventDefault();
return false;
}
})
As far as I can tell so far, it seems to be working, but it feels incredibly ham-fisted.
Does anyone know of a more sophisticated technique for doing this?
Similarly, are there any pitfalls to this solution that I'm just not aware of?
Thanks.
Using
<button type="button">Whatever</button>
should do the trick.
The reason is because a button inside a form has its type implicitly set to submit. As zzzzBoz says, the Spec says that the first button or input with type="submit" is what is triggered in this situation. If you specifically set type="button", then it's removed from consideration by the browser.
It is important to read the HTML specifications to truly understand what behavior is to be expected:
The HTML5 spec explicitly states what happens in implicit submissions:
A form element's default button is the first submit button in tree order whose form owner is that form element.
If the user agent supports letting the user submit a form implicitly (for example, on some platforms hitting the "enter" key while a text field is focused implicitly submits the form), then doing so for a form whose default button has a defined activation behavior must cause the user agent to run synthetic click activation steps on that default button.
This was not made explicit in the HTML4 spec, however browsers have already been implementing what is described in the HTML5 spec (which is why it's included explicitly).
Edit to add:
The simplest answer I can think of is to put your submit button as the first [type="submit"] item in the form, add padding to the bottom of the form with css, and absolutely position the submit button at the bottom where you'd like it.
Where ever you use a <button> element by default it considers that button type="submit" so if you define the button type="button" then it won't consider that <button> as submit button.
I don't think you need javascript or CSS to fix this.
According to the html 5 spec for buttons a button with no type attribute is treated the same as a button with its type set to "submit", i.e. as a button for submitting its containing form. Setting the button's type to "button" should prevent the behaviour you're seeing.
I'm not sure about browser support for this, but the same behaviour was specified in the html 4.01 spec for buttons so I expect it's pretty good.
By pressing 'Enter' on focused <input type="text"> you trigger 'click' event on the first positioned element: <button> or <input type="submit">. If you press 'Enter' in <textarea>, you just make a new text line.
See the example here.
Your code prevents to make a new text line in <textarea>, so you have to catch key press only for <input type="text">.
But why do you need to press Enter in text field? If you want to submit form by pressing 'Enter', but the <button> must stay the first in the layout, just play with the markup: put the <input type="submit"> code before the <button> and use CSS to save the layout you need.
Catching 'Enter' and saving markup:
$('input[type="text"]').keypress(function (e) {
var code = e.keyCode || e.which;
if (code === 13) {
e.preventDefault();
// also submit by pressing Enter:
$("form").submit();
}
});
Pressing enter in a form's text field will, by default, submit the form. If you don't want it to work that way you have to capture the enter key press and consume it like you've done. There is no way around this. It will work this way even if there is no button present in the form.
You can use javascript to block form submission until the appropriate time. A very crude example:
<form onsubmit='return false;' id='frmNoEnterSubmit' action="index.html">
<input type='text' name='txtTest' />
<input type='button' value='Submit'
onclick='document.forms["frmNoEnterSubmit"].onsubmit=""; document.forms["frmNoEnterSubmit"].submit();' />
</form>
Pressing enter will still trigger the form to submit, but the javascript will keep it from actually submitting, until you actually press the button.
Dom example
<button onclick="anotherFoo()"> Add new row</button>
<input type="text" name="xxx" onclick="foo(event)">
javascript
function foo(event){
if(event.which == 13 || event.keyCode == 13) // for crossbrowser
{
event.preventDefault(); // this code prevents other buttons triggers use this
// do stuff
}
}
function anotherFoo(){
// stuffs.
}
if you don't use preventDefault(), other buttons will triggered.
I would do it like the following: In the handler for the onclick event of the button (not submit) check the event object's keycode. If it is "enter" I would return false.
My situation has two Submit buttons within the form element: Update and Delete. The Delete button deletes an image and the Update button updates the database with the text fields in the form.
Because the Delete button was first in the form, it was the default button on Enter key. Not what I wanted. The user would expect to be able to hit Enter after changing some text fields.
I found my answer to setting the default button here:
<form action="/action_page.php" method="get" id="form1">
First name: <input type="text" name="fname"><br>
Last name: <input type="text" name="lname"><br>
</form>
<button type="submit" form="form1" value="Submit">Submit</button>
Without using any script, I defined the form that each button belongs to using the <button> form="bla" attribute. I set the Delete button to a form that doesn't exist and set the Update button I wanted to trigger on the Enter key to the form that the user would be in when entering text.
This is the only thing that has worked for me so far.
You can do something like this.
bind your event into a common function and call the event either with keypress or button click.
for example.
function callME(event){
alert('Hi');
}
$('button').on("click",callME);
$('input ').keypress(function(event){
if (event.which == 13) {
callME(event);
}
});
I added a button of type "submit" as first element of the form and made it invisible (width:0;height:0;padding:0;margin:0;border-style:none;font-size:0;). Works like a refresh of the site, i.e. I don't do anything when the button is pressed except that the site is loaded again. For me works fine...

Categories