Don't allow new lines in textarea - javascript

Using jQuery how can I not allow new lines to be inserted (by pressing enter or copying in text) - In semi-pseudo code...
$('textarea').keydown(function(){
$(this).remove_new_lines();
});
Thanks!
EDIT:
Would it be as crude as the following or is there a better way?
function removeNL(s){
return s.replace(/[\n\r\t]/g,);
}
$('textarea').keydown(function(){
$(this).val(removeNL($(this).val));
});

There are two methods to do this: check each character as it is input and return false if you don't want it to show up, or on each change/keyup you can check the entire contents. While the former is more performant, it won't work in situations where the user pastes content in that includes unwanted characters. For that reason, I recommend the latter approach, something like this (which will disallow all vertical whitespace):
With jQuery:
$('textarea').on('keyup', function(){
$(this).val($(this).val().replace(/[\r\n\v]+/g, ''));
});
Or using plain JavaScript (ES2015/ES6):
constrainInput = (event) => {
event.target.value = event.target.value.replace(/[\r\n\v]+/g, '')
}
document.querySelectorAll('textarea').forEach(el => {
el.addEventListener('keyup', constrainInput)
})
Another approach is to wait until the focus leaves the textarea, then apply the transformation. This avoids janky behavior on operating systems using synthetic, conditionally active keyboard controls. The user will see newlines until they leave the field, though, so be aware. To do this, just change the above event listener to listen for blur rather than keyup.
If you're using React, you have it made because it avoids issues with mobile browsers while letting you manage the value as it changes using controlled components:
class TextArea extends React.PureComponent {
state = {
value: ""
};
handleChange = event => {
const value = event.target.value.replace(/[\r\n\v]+/g, "");
this.setState({ value });
};
render() {
return <textarea onChange={this.handleChange} value={this.state.value} />;
}
}

you can check keyCode, if it is equal to 13 simply return false
$('#TEXTAREA').keypress(function(e){
if (e.keyCode == 13) return false
})

$('textarea').keydown(function(e){
var s = $('textarea').val();
while (s.indexOf("\n") > -1)
s = s.replace("\n","");
$('textarea').val(s);
});

Related

Preventing the user from deleting in an input field

I want to have a text field (<input> in HTML) that the user can only use to write text, but when deleting the text, it should prevent him from updating the state of the input element.
<input type="text" />
I couldn't come up with a solution except to detect the user key presses on the keyboard, i.e, using the onKeyUp attribute, and watch the user keystrokes until he presses the Backspace character:
const input = document.querySelector('input')
input.addEventListener('keydown', (e) => {
const keyCode = e.keyCode
if (keyCode === 8) console.log("Backspace pressed!")
})
<input type="text" />
However, there's a missing part here, even though the user won't be able to clear the input content by the Backspace key, he can instead use the Del key.
So I would have then to handle the Del key the same way I handle the Backspace key.
Now, there's another problem, which is trying to modify the input content by overwriting the content as follows:
and then, after that, I will have to prevent the user from editing the text by cutting the content (which I have no idea how to do).
So, what are the alternatives?
Please feel free to use HTML, JavaScript, CSS.
If you're using React, I was able to solve this problem simply by checking if the length of the input value is shorter than the one being memorized in the state, then prevent the user from updating the state:
The answer resides between controlling the value prop (or attribute if you wish) and the onChange handler.
const [inputVal, setInputVal] = useState('')
const handleChange = (e) => {
const value = e.target.value
if(value.length < inputVal.length) return // prevent modifications
setInputVal(value)
}
return <input value={inputVal} onChange={handleChange}/>
Now, the question is, how to do the same when using only HTML/JavaScript?
Perhaps something like this? Then it doesn't matter what they press.
const input = document.querySelector('input')
let previousState = input.value;
input.addEventListener('keydown', (e) => {
if ( previousState.length > input.value.length ) input.value = previousState;
previousState = input.value;
})
In the keydown event, put whatever keycodes you want in an array and see if the current keycode is included. Then create a select event, and blur the input when it fires.
const input = document.querySelector('input');
input.addEventListener('keydown', (e) => {
if ([8, 46].includes(e.keyCode)) {
e.preventDefault()
}
})
input.addEventListener('select', (e) => {
e.target.blur()
})
<input type="text" />
#dqhendricks answer is in the right way, but misses some possibilities:
User can hit backspace (reduce length by one) (covered)
User can select a piece of text and hit backspace or other key (covered)
User can select a piece (or all text) and replace by a different string with same length. (Not covered)
So my suggestion is:
You should listen for change event, then compare the previous string, if the new string starts with the previous string, it's ok. Otherwise we revert the change.
In code ir should look like:
const input = document.querySelector('input');
let previousState = input.value; // initial state
input.addEventListener('change', (e) => {
if (!input.value.startsWith(previousState)) {
input.value = previousState; // revert change
}
previousState = input.value;
})
you can check the length of the input's value, if it became shorter replace it with the previous value
let value;
input.addEventListener('change', ()=>{
if(value && input.value.length < value.length) input.value=value;
else value=input.value;
}
You must have some piece of code that sets the value from the barcode scanner. Once that is being set, also do input.dataset.barcodeValue="scanresult".
Then to make it sufficiently difficult for a regular user to ruin the barcode, you need to prevent several things:
pasting
cutting
typing over the barcode value
dragging text into the input
pressing delete or backspace which would mess up the barcode value.
All of this is covered in the input event.
const input = document.querySelector('#bc-value');
function setValueFromBarcodeScanner(val) {
input.value = input.dataset.barcodeValue = val;
input.addEventListener('input', (e) => {
const { barcodeValue } = input.dataset;
if (barcodeValue && !input.value.startsWith(barcodeValue)) input.value = barcodeValue;
})
}
<input type="text" id="bc-value" />
<button type="button" onclick="setValueFromBarcodeScanner('433-224-221-456')">Set value from Barcode Scanner</button>
I think this might work for you:
const inputElement = document.getElementById('write-only-input');
let lastValue = '';
inputElement.oninput = function(e) {
if (inputElement.value.startsWith(lastValue)) {
lastValue = inputElement.value;
} else {
inputElement.value = lastValue;
}
}
<input type="text" id="write-only-input" />

Prevent keyUp event when onPaste event is triggered

I have the following input field:
<input onPaste={pasteFunction} keyUp={keyupFunction} />
I want either the pasteFunction or keyupFunction to run, NOT both. But when a user pastes text into this field both events get triggered and both run.
Is there a way to prevent keyUp if something was pasted into the field?
I tried to set a flag and reset it:
function pasteFunction() {
pasteInProgress = true;
//etc...
pasteInProgress = false;
}
function keyupFunction() {
if (pasteInProgress) return;
//etc...
}
But this doesn't work as pasteInProgress is set to false before keyupFunction is triggered.
You could try storing the time instead, for example.
function pasteFunction() {
lastPaste = Date.now();
//etc...
}
function keyupFunction() {
//less than one second has passed.
if (Date.now()-lastPaste<1000) return;
//etc...
}
Maybe try experimenting with different times depending on the application, but it is still a "hacky" way to solve it. I think there could be better ways.
Is there a way to prevent keyUp if something was pasted into the field?
Assuming you are using a ui library (react?), you could store a value in the component state when something was pasted into the field.
this.state = {
hasPasted: false;
}
function pasteFunction() {
this.state.hasPasted = true; // could also be a timestamp if you need granularity
}
function keyupFunction(e) { // assuming you can pass event here
if (this.state.hasPasted){
// you may want to preventDefault() here
e.preventDefault();
return;
};
}
Without you sharing more context/code, this should do it.

How to disable hotkeys when inputting?

When the user presses a certain key, a component shows. I have four such components. When the user is typing or editing, I want to disable the hotkeys.
I have this code in each of the four components
componentDidMount(){
document.body.addEventListener("keypress", (e) => {
if (e.key === "t") { // "n" "w" "," for the others
this.setState({opened: !this.state.opened});
}
});
}
I only want to disable hotkeys when the user is typing or editing. Is there a way to know if any input is in focus? Or the other way, can we add the event listeners only if all the inputs are 'on blur'?
So we need to know if any of the inputs on the page are in focus and if any of them is focused then we just will not do anything to show or hide components.
Let's assume that our component has in the state some property which indicates that some input on the page is focused, let's call it isFocus.
So, we need to collect all inputs on the page, iterate over them all and assign to each input the focus and the blur event handlers, so we will be able to know when to change the isFocus property in the state.
First of all, we need to collect all of the inputs on the page, we do it with:
const inputs = document.getElementsByTagName('input').
Iterate over them all and assign the focus and blur event handlers:
for (let input of inputs) {
input.addEventListener('focus', () => this.setState({isFocus: true}));
input.addEventListener('blur', () => this.setState({isFocus: false}));
}
And finally, let's change the condition for the keypress event:
document.addEventListener('keypress', e => {
if (!this.state.isFocus && e.key === "t") {
this.setState({opened: !this.state.opened});
}
});
Everything together will look like this:
componentDidMount() {
const inputs = document.getElementsByTagName('input');
for (let input of inputs) {
input.addEventListener('focus', () => this.setState({isFocus: true}));
input.addEventListener('blur', () => this.setState({isFocus: false}));
}
document.addEventListener('keypress', e => {
if (!this.state.isFocus && e.key === "t") {
this.setState({opened: !this.state.opened});
}
});
}
Hope this helps. Good luck.
You could move the current open component state to the most upward component, like the following:
state: {
openComponent: null
}
your hotkey function would look like this:
hotkey(e){
const componentKeyHandlers = {
"n": {openComponent: "componentN"},
"m": {openComponent: "componentM"}
}
if (e.keyCode === 27) { //ESC
this.setState({openComponent: null});
} else if (!this.state.openComponent) {
this.setState(componentKeyHandlers[e.key]);
}
}
I'm assuming you could only have ONE open component each time. Also, you could close them by hitting ESC.
For each component, its visibility would be controlled by comparing props.openComponent to its name, given that the current state component is passed down to each one via props.
This way you don't need to unregister the hotkey function. When you start typing with an open component, the setState is going to be ignored due to the if (!this.state.openComponent) condition.

Preventing ckeditor to display character on keypress

I have a CKEditor 3.0 instance 'editor' and on its 'key' event a listener is attached so that when that function is returning false it should not type that key character on editor, that is if key 'k' is pressed it should not be displayed on the editor if the function is returning false
editor.on('key', function(e)
{
alert(""+e.data.keyCode);
return false;
});
I used above code for this but it is not working, means the character is getting typed on the editor
Trying the same using a plugin where on keypress of keycode 65 the other language character should show up instead of english language character.
CKEDITOR.plugins.add( 'typing',
{
init: function( editor )
{
editor.addCommand( 'insertcharacter',
{
exec : function( editor )
{
alert(editor.id);
alert(editor.name);
editor.on('key', function(e)
{
alert("Hello"+e.data.keyCode);
if(e.data.keyCode == 65)
{
editor.insertText('Other Language Character');
}
return false;
});
}
});
can u suggest me any solution for this.
Thanks
found the answer recently. this worked for me in the latest version(4.x).
editor.document.on('keypress', function(e) {
e.data.preventDefault(); // this will prevent the default action for any event
//your code goes here
});
In v4 you can use editor.on('key') and cancel() the event when the appropriate key is pressed.
So to ignore k keypresses,
editor.on('key', function(evt) {
var keyCodeToIgnore = 'K'.charCodeAt(); // Upper case K. Only one k key.
var pressedKeyCode = evt.data.keyCode;
if ( pressedKeyCode === keyCodeToIgnore ) {
evt.cancel();
}
}
(That wouldn't prevent 'k's being added by other means, of course, such as pasting.)
See http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-key
You can also configure the editor to block specified keystrokes. Using that you can specify case. So to ignore k and not K:
config.blockedKeystrokes = [75]; // To ignore k and K: [75, 107]
Though you'd probably want to keep the default blockedKeystrokes as well.
See http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-blockedKeystrokes
The first method lets you do other stuff of course. You could drive people crazy by ignoring a 'u' if the previous keypress was a 'q', for example.
use following code before return from function to Cancel/block the character/event.
e.cancelBubble = true;
e.returnValue = false;
e.cancel();
e.stop();
return false;
where e is in parameter of function
I came looking for a way to bind something to the the enter key press. Except I'm using contenteditable div tags, and maybe that made the above solutions not work for me.
However I came to this, that seems to be working perfectly
$(function () {
CKEDITOR.instances['<the DOM ID of your element>'].on('key', function (e) {
if (e.data.keyCode === 13) {
//yeet
e.cancel();
}
});
});

Question on tabbing to next NON-READONLY field

On blur of field1, field2 is set to READONLY but the cursor on my page then defaults to field2 and the cursor is located at the END of the value and when the user clicks the backspace button the value can be erased. I would like the ability to have the cursor move to the next NON-READONLY or ENABLED field on the page. Is that do-able with jQuery?
Any help/direction would be appreciated.
Here is my code:
$(function() {
$("#ARTransferForm\\:fromAccountAmt").blur(function() {
var origAccountAmount = $("#ARTransferForm\\:fromAccountAmt").val();
var fromAccountAmount = $("#ARTransferForm\\:fromAccountAmt").val();
// Call validation "r2" function
var modFromAccountAmount = r2(fromAccountAmount);
//alert("modFromAccountAmount = " + modFromAccountAmount);
fromAccountAmount = $("#ARTransferForm\\:fromAccountAmt").val(modFromAccountAmount).val();
//alert ("modified fromAccountAmount = " + fromAccountAmount);
if (modFromAccountAmount != "N.aN") {
var firstChar = fromAccountAmount.charAt(0);
var fromAcctAmtLen = $("#ARTransferForm\\:fromAccountAmt").val().length;
if (firstChar == "-") {
var revFromAcctAmt = fromAccountAmount.substring(1, fromAcctAmtLen);
$("#ARTransferForm\\:toAccountAmt").val(revFromAcctAmt);
$("#ARTransferForm\\:toAccountAmt").attr("readonly", "readonly");
} else {
$("#ARTransferForm\\:toAccountAmt").val("-"+fromAccountAmount);
$("#ARTransferForm\\:toAccountAmt").attr("readonly", "readonly");
}
} else {
$("#ARTransferForm\\:fromAccountAmt").val(origAccountAmount);
$("#ARTransferForm\\:fromAccountAmt").select();
alert("Invalid From Amount Format. Use ##.## (NO commas or $ sign)");
}
});
});
Have you tried modifying tabindexes onblur, before RETURN TRUE, to control where the cursor goes? It's kind of a hack, but there you go.
Also, you could use a delegated event (perhaps on the form) to intercept and return false on any keypress events that would modify the value of any readonly input. Something like:
$('#ARTransferForm *[readonly]').live("keypress", function(event) {
// compare keycode to blacklist: backspace, perhaps delete too?
if(bKeyIsBlacklisted) {
event.preventDefault();
return false;
}
});
(Note: that is pretty pseudocodeonous. You'll want to double-check the syntax for sizzle's attribute selectors, as well as jquery's event delegation signature. And be real careful about how wide you cast your "no keys" net: try to avoid disallowing Copy and other operations performed with keyboard shortcuts. You will need to check for a modifier key to distinguish between the user trying to type "c" and Ctrl+C.
Which browser(s) are you testing this in?

Categories