Using monaco editor for HTML form textarea
For one of my personal projects I wanted to have a more convenient way to edit markdown in an HTML form, than the plain text.
I ended up with using the Monaco Editor that powers VS Code, as the form editor.
My form is a really basic one — just a single <textarea>
element, and a submit button:
<form method="POST" id="MyForm">
<input required id="text" name="text">
<input type="submit" value="Save" id="submitButton">
</form>
monaco-editor-samples repository contains a lot of examples on how one can include Monaco editor onto their page, so I just picked one of the examples.
While code samples and Monaco editor playground demonstrated certain bits of functionality, none of the fits my use case exactly, so I had to figure out how to match different features together.
What I wanted to get:
- Full page editor area, if possible, without submit button in the way, and form submitting on some shortcut/hotkey.
- Editor area size should follow browser page resize, both vertically and horizontally.
- Editor color scheme should follow user's light/dark theme preference.
After reading many examples, lots of trial and error, I ended up with the working solution that implemented all of the requirements.
The code below implements a single-field HTML form, you can edit markdown text and submit the form with the “Ctrl-s” or “Cmd-s” shortcuts. You can see it as a standalone demo.
<!doctype html><head><meta charset="utf-8"><title>Editor</title>
<style>
html,body{margin: 0; padding: 0;}
div#editor {height: 100vh; box-sizing: border-box; overflow: hidden;}
</style>
</head>
<body>
<form method="POST" id="MyForm">
<div id="editor"></div>
<input required type="hidden" id="text" name="text">
</form>
<script src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.27.0/min/vs/loader.min.js" integrity="sha512-SExj71Cw3B9C9EE8BC/ad3AKia5zQXDj/2SM4THgkeKh5GIFZhKM/R3uclUG8YZwJrjcVhydAlIHmfNvsBCKZA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script>
require.config({ paths: { 'vs': 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.27.0/min/vs' }});
require(['vs/editor/editor.main'], function() {
let theme = "vs";
if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
theme = "vs-dark";
}
window.editor = monaco.editor.create(document.getElementById('editor'), {
value: "# Document Header\n\nEnter some text, submit the form with Ctrl-s or Cmd-s shortcut.",
language: 'markdown',
lineNumbers: "off",
wordWrap: "bounded",
wordWrapColumn: 100,
wrappingIndent: "same",
fontSize: 14,
roundedSelection: false,
scrollBeyondLastLine: false,
quickSuggestions: false,
minimap: {enabled:false},
theme: theme,
});
window.editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KEY_S, function() {
var inp = document.getElementById('text');
inp.value = window.editor.getValue();
document.forms['MyForm'].submit();
});
window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", e => {
if (e.matches) {
monaco.editor.setTheme("vs-dark");
} else {
monaco.editor.setTheme("vs");
}
})
const divElem = document.getElementById('editor');
const resizeObserver = new ResizeObserver(entries => {
window.editor.layout();
});
resizeObserver.observe(divElem);
});
</script>
</body>