Skip to content

Instantly share code, notes, and snippets.

@jim-clark
Last active September 12, 2023 14:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jim-clark/ff11104604bc7fa9c8eb65ee9217ca2b to your computer and use it in GitHub Desktop.
Save jim-clark/ff11104604bc7fa9c8eb65ee9217ca2b to your computer and use it in GitHub Desktop.

Accepting Multi-Line Input and Rendering in EJS

If you'd like a user to be able to enter multi-line text and have that text render the line-breaks within HTML, read on...

Mongoose Schema

As usual, use a String property on a schema to hold the text content, for example:

const logEntrySchema = new Schema({
  content: { type: String, required: true }
}, {
  timestamps: true
});

const logSchema = new Schema({
  user: { type: Schema.Types.ObjectId, ref: 'User', required: true },
  entries: [logEntrySchema]
}, {
  timestamps: true
});

Use a <textarea> Element Instead of an <input>

To allow your users to enter multiple lines, use a <textarea> within your <form> instead of an <input>, for example:

<form action="/logs/<%= log._id %>/entries" method="POST">
  <label for="log-content">Entry: </label>
  <textarea id="log-content" name="content" rows="10" cols="40">
    Default content in here
  </textarea>
</form>

Note that unlike <input> elements, <textarea> elements have a closing tag.

As users type into the <textarea>, they will be able to press [return] to enter line-breaks.

How the Text is Stored Within the MongoDB Document

The string submitted by the form will have new-line characters (\n) embedded wherever the user pressed the [return] key and the MongoDB document will store this string as usual.

However, when the sring is rendered in the HTML page, the \n characters do not result in new lines being displayed.

Rendering <br> Elements Instead of \n Characters

Because the new-line characters won't be rendered as line-breaks in the HTML, we need to replace the \n characters with <br> characters and render the string using EJS's raw output tag so that the <br> characters are rendered as HTML.

Follow this pattern in your EJS templates when rendering strings that contain new-line characters:

<% log.entries.forEach(function(entry) { %>
  <article>
    <%- entry.content.replaceAll('\n', '<br>') %>
  </article>
<% }) %>

Again, be sure to use the raw output EJS tag (<%- %>) instead of the usual output tag (<%= %>) so that the <br> tags render as HTML.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment