Hey all so I'll keep it short. I know there've been some questions asked similar to this but none of them are able to answer what I'm trying to achieve. This is what I want the code to do:
- Show a div when forward slash "/" is typed in textarea
- Not show a div when forward slash is not typed
- hide the pop up when the forward slash is deleted/backspaced
I can achieve the first two with the following code I'm working with right now: https://jsfiddle.net/jtk37vs8/1/. However the problem is, whenever I type forward slash and then delete it, the pop up still stays there. I'm new to JS and the code is kinda unorganized but it's quite easy to understand. So basically I'd appreciate if any of you could at least tell me if there is any straightforward way to achieve this? Thank you for your patience and reading my query.
function getCaretCoordinates() {
let x = 0,
y = 0;
const isSupported = typeof window.getSelection !== "undefined";
if (isSupported) {
const selection = window.getSelection();
// Check if there is a selection (i.e. cursor in place)
if (selection.rangeCount !== 0) {
// Clone the range
const range = selection.getRangeAt(0).cloneRange();
// Collapse the range to the start, so there are not multiple chars selected
range.collapse(true);
// getCientRects returns all the positioning information we need
const rect = range.getClientRects()[0];
if (rect) {
x = rect.left; // since the caret is only 1px wide, left == right
y = rect.top; // top edge of the caret
}
}
}
return { x, y };
}
function getCaretIndex(element) {
let position = 0;
const isSupported = typeof window.getSelection !== "undefined";
if (isSupported) {
const selection = window.getSelection();
// Check if there is a selection (i.e. cursor in place)
if (selection.rangeCount !== 0) {
// Store the original range
const range = window.getSelection().getRangeAt(0);
// Clone the range
const preCaretRange = range.cloneRange();
// Select all textual contents from the contenteditable element
preCaretRange.selectNodeContents(element);
// And set the range end to the original clicked position
preCaretRange.setEnd(range.endContainer, range.endOffset);
// Return the text length from contenteditable start to the range end
position = preCaretRange.toString().length;
}
}
return position;
}
$("#contenteditable").bind("keypress", function toggleTooltip(e) {
const tooltip = document.getElementById("tooltip");
if(String.fromCharCode(e.keyCode) == '/') {
const { x, y } = getCaretCoordinates();
$(".tooltip").show();
// tooltip.setAttribute("aria-hidden", "false");
tooltip.setAttribute( "style", `display: inline-block; left: ${x - -10}px; top: ${y - 160}px`
);
}
else if (document.getElementById('contenteditable').innerHTML.indexOf("/") != -1) {
// $(".tooltip").hide();
// tooltip.setAttribute("aria-hidden", "true");
tooltip.setAttribute("style", "display: none;");
}
// else if (document.getElementById('contenteditable').innerHTML.indexOf("/") >=0) {
// tooltip.setAttribute("aria-hidden", "true");
//tooltip.setAttribute("style", "display: none;");
// }
else {
// $(".tooltip").hide();
// tooltip.setAttribute("aria-hidden", "true");
//tooltip.setAttribute("style", "display: none;");
}
} )
CodePudding user response:
I am a bit busy but I hope this will help. You can capture backspace How to capture a backspace on the onkeydown event
CodePudding user response:
You're close. BTW, doing it this way is definitely not the most performant way to be handling this, but it works.
First, you need to change your event listener to keydown. Keypress doesn't work for backspace / delete, if I remember correctly. Once you do that, it's as easy as adding what you already have.
if (e.keyCode == 46) {
// ... check if '/' is in the text area value, you already have this code
// OR
// ... check if the last index of document.getElementById('textarea-id').value is a '/'
}
There's a lot wrong with the conditionals here though, but using indexOf (like you have already) will be the most user friendly, I guess. That way, nothing changes in the case of multiple '/', and the tooltip is deleted when all the '/' are deleted.
CodePudding user response:
Change the value == instead of != as you want to hide if the slash is missing
else if (document.getElementById('contenteditable').innerHTML.indexOf("/") == -1) {
and the backspace is not handled by the keypress event so use the keypress and the keydup at the same time like this .
$("#contenteditable").on("keypress keyup", function toggleTooltip(e) {
Working fiddle code https://jsfiddle.net/BETOMBO_Mariot/a5ntzjg4/