When using contentEditable in Firefox, is there a way to prevent the user from inserting paragraph or line breaks by pressing enter or shift+enter?
You can attach an event handler to the keydown or keypress event for the contentEditable field and cancel the event if the keycode identifies itself as enter (or shift+enter).
This will disable enter/shift+enter completely when focus is in the contentEditable field.
If using jQuery, something like:
$("#idContentEditable").keypress(function(e){ return e.which != 13; });
...which will return false and cancel the keypress event on enter.
contenteditable
elements on page, but not just one –
Footless This is possible with Vanilla JS, with the same effort:
document.getElementById('idContentEditable').addEventListener('keypress', (evt) => {
if (evt.which === 13) {
evt.preventDefault();
}
});
You should not use jQuery for the most simple things. Also, you may want to use "key" instead of "which": https://developer.mozilla.org/en-US/docs/Web/Events/keypress
Update, since keypress
is deprecated:
document.getElementById('idContentEditable').addEventListener('keydown', (evt) => {
if (evt.keyCode === 13) {
evt.preventDefault();
}
});
keyCode
is deprecated too so use evt.key === "Enter"
. Can't speak to backwards compatibility here. Docs. –
Scrivner Add the following CSS rule to hide line breaks. This is only a style setting, you should add some event handlers to prevent inserting line breaks:
.your_editable br {
display: none
}
<DIV>
s too, so might add .your_editable * { display: inline }
before that. –
Soggy Other than adding line breaks, the browser adds additional tags and styles (when you paste text, the browser also appends your pasted text style).
The code below covers it all.
- When you press enter, no line breaks will be added.
When you paste text, all elements added by the browser are stripped from the text.
$('[contenteditable]').on('paste', function(e) { //strips elements added to the editable tag when pasting var $self = $(this); setTimeout(function() {$self.html($self.text());}, 0); }).on('keypress', function(e) { //ignores enter key return e.which != 13; });
another option is to allow breaks to be entered but remove them on blur. this has the advantage of dealing with pasted content. your users will either love it or hate it (depending on your users).
function handle_blur(evt){
var elt=evt.target; elt.innerText=elt.innerText.replace(/\n/g,' ');
}
then, in html:
<span onblur="handle_blur(event)" contenteditable>editable text</span>
If you are using JQuery framework, you can set it with the on method which will let you have the desired behavior on all elements even if this one is added lately.
$(document).on('keypress', '.YourClass', function(e){
return e.which != 13;
});
Add:
display: flex;
On the contenteditable html element
div
element. When the line breaks, it adds a div
element automatically to start the current new line. By using display: flex
, you make the DIVs appear horizontally in the same line, unlike display: block
which is applied by default. This does not prevent the addition of new lines. It just makes them appear directly next to each other. You could confirm this behavior by using the DevTools or pressing shift
+enter
. –
Supralapsarian $("#idContentEditable").keypress(function(e){ return e.which != 13; });
Solution proposed by Kamens doesn't work in Opera, you should attach event to document instead.
/**
* Pass false to enable
*/
var disableEnterKey = function(){
var disabled = false;
// Keypress event doesn't get fired when assigned to element in Opera
$(document).keypress(function(e){
if (disabled) return e.which != 13;
});
return function(flag){
disabled = (flag !== undefined) ? flag : true;
}
}();
If you want to target all the contentEditable fields use
$('[contenteditable]').keypress(function(e){ return e.which != 13; });
I came here searching for the same answer, and was surprised to find it's a rather simple solution, using the tried and true Event.preventDefault()
const input = document.getElementById('input');
input.addEventListener('keypress', (e) => {
if (e.which === 13) e.preventDefault();
});
<div contenteditable="true" id="input">
You can edit me, just click on me and start typing.
However, you can't add any line breaks by pressing enter.
</div>
Use the beforeinput
event and when you hear the event and it has an inputType
of either insertParagraph
(Enter) or insertLineBreak
(Shift+Enter) you can simply cancel the event using event.preventDefault()
and use event.stopPropagation()
to stop the event from getting propagated to other event listeners.
You can test this yourself using this HTML:
<html>
<body>
<p>Write in the contentEditable div below!</p>
<div contentEditable="true" style="width:100%;height:200px;border:1px solid black;"></div>
<script>
document.addEventListener('beforeinput', event => {
const {
dataTransfer,
inputType,
isComposing,
data,
} = event;
if (dataTransfer) {
console.log('dataTransfer.getData(text/html) ===', printR(dataTransfer.getData('text/html')));
console.log('dataTransfer.getData(text/plain) ===', printR(dataTransfer.getData('text/plain')));
}
const convertToRange = staticRange => {
if (staticRange instanceof StaticRange) {
const {
startContainer, startOffset,
endContainer, endOffset,
} = staticRange;
const range = document.createRange();
range.setStart(startContainer, startOffset);
range.setEnd(endContainer, endOffset);
return range;
}
};
// Get the static ranges that will be affected by a change to the DOM if the input event is not canceled
const ranges = event.getTargetRanges?.() || [];
ranges.forEach(staticRange => {
const range = convertToRange(staticRange);
console.log(`Range text content: "${range}"`);
});
console.log('ranges.length ==', ranges.length);
console.log('The "inputbefore" event was detected! event ==', {
dataTransfer,
inputType,
isComposing,
data,
});
if (['insertParagraph', 'insertLineBreak'].includes(inputType)) {
console.log('CANCELING event with inputType ==', inputType);
event.preventDefault();
event.stopPropagation();
}
});
</script>
</body>
</html>
When you press Enter
(or Shift
+Enter
) you should notice nothing changing inside the <div contentEditable="true">
element.
stopPropagation()
and preventDefault()
? EDIT : After doing some tests, it seems like preventDefault()
is doing the work fo actually preventing input while stopPropagation
probably juste prevents other event listeners to be fired –
Yvoneyvonne In the KeyboardEvent
interface e.which
and e.keyCode
are deprecated and have been replaced by e.key
.
A list of possible values for e.key
can be found here on MDN or here on W3.
To prevent possibility of typing a new line or a tab which would exit the input consider the following for react/next:
onKeyDown = {(e) => {
return ["Enter", "Tab"].includes(e.key) ? e.preventDefault() : null
}}
Use CSS:
word-break: break-all;
For me, its worked!
© 2022 - 2024 — McMap. All rights reserved.