I am new to JavaScript so struggling to get this over the line. I have a form with a textarea field. After each keypress event of the enter key I need each line to get wrapped in li tags. Then once submitted the data is outputted as a list. I am using Javascript not JQuery. The problem is when I add the li tags the opening tag is always added to the first item and ends up having multiple opening li tags and the closing tags work as they should.
I have tried this so far. HTML
<textarea id="form__comments" name="comments" rows="10" onkeypress="addLiTag(event);"></textarea>
JS
function addLiTag(e) {
const commentValue = document.getElementById("form__comments").value
var lines = commentValue.split(/\r?\n/)
var key = e.keyCode
// If the user has pressed enter
if (key === 13) {
document.getElementById("form__comments").value = "<li>" lines "</li>"
return false
} else {
return true
}
}
This is the output within the Textarea
<li><li><li>One</li>,two</li>Three,</li>
CodePudding user response:
So the main issue with your existing code is that when you add the value back to your textarea
, you wrap an array (the lines
variable) inside of an opening and closing <li>
tag, rather than wrapping each line inside of its own tag.
Also when adding the value back, I'm assuming you want to preserve the lines as well (meaning each <li>
is also on its own line), in which case you also would need to add back the newline character after each line.
And lastly, to prevent duplicate <li>
tags being added, the simplest thing is to just remove the tags and parse the value of your text area again (this also can prevent issues with editing previous lines).
const addLiTag = e => {
let lines = document.querySelector("#form__comments").value.replaceAll("<li>", "").replaceAll("</li>", "").split(/\r?\n/)
if(e.keyCode === 13) document.querySelector("#form__comments").value = "<li>" lines.join("</li>\n<li>") "</li>"
}
document.querySelector("#form__comments").addEventListener("keypress", addLiTag)
<textarea id="form__comments" name="comments" rows="10"></textarea>
Notes
I'm sure this could also be done with a single Regular Expression that splits on either a newline or the </li>\n<li>
delimeter, rather than using two .replaceAll()
calls, however I'm not that great at Regular Expressions. But hopefully this answer demonstrates the concept of removing all of the <li>
tags and re-parsing the value each time.