WYSIWYG editors


#1

I could use some advise on WYSIWYG editors. Are there any free editors that don’t use plug-ins and use strictly JavaScript and CSS code on a html page for a textarea form input that you can submit to your own database?

Appreciate any help as I don’t have any experience with editors.

Thank you.


#2

Quill is worth a look.


#3

Thank you for that. I did see that one and will look into it further.

When you have an editor like that, should you be able to save in database the html code from the textarea and then have it draw to the page as written? And are there any issues as it relates to saving the data that I should be aware of?

Thanks


#4

I believe Quill is backend agnostic. What you do with the generated HTML is up to you. You can just grab the innerHTML from whatever element you initialized Quill on and send it off to your database, either via form submission or Ajax.


#5

Thank you for that information, it’s truly appreciated.


#6

Do you have any experience with Quill? It’s seems impossible to use it in a textarea to submit to database. Just want something simple like it is here that you submit the innerHTML to database.


#8

I’ve used CKeditor for many years. I think CK4 is more configurable but CK5 has some cool new features. depending what you need. It can just be run from a CDN link if you don’t want to install it.


#9

I haven’t, but I don’t imagine it to be difficult to do what you ask. Where are you getting stuck?

The example shows an example of using it on a <div>. Is this where you are having trouble?


#10

Yes, I am using a div for the form submit, as below, but don’t know how to incorporate that with textarea to submit to database:

<div id="Div1">
<form method="POST" action="post.asp" name="mainform">
  <input type="hidden" id="myHtml"/>
  <button type="submit">Submit</submit>
</form>
</div>

You would usually have a textarea to post to another page, so I am lost at this stage.

I very much appreciate your help.


#11

To submit whatever has been entered into Quill (including formatting) with the form you’d need to catch the submit event, prevent the browser’s default action, grab the contents of the quill editor, stick it in the hidden input, then send the form on its way.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Quill</title>
    <link href="https://cdn.quilljs.com/1.3.6/quill.snow.css" rel="stylesheet">
  </head>
  <body>
    <div id="editor">
      <p>Hello World!</p>
    </div>

    <form method="POST" action="post.asp" name="mainform">
      <input type="hidden" id="myHtml"/>
      <button type="submit">Submit</submit>
    </form>

    <script src="https://cdn.quilljs.com/1.3.6/quill.js"></script>
    <script>
      const editor = document.getElementById('editor');
      const hiddenInput = document.getElementById('myHtml');
      const form = document.forms.mainform;
      const quill = new Quill(editor, {
        theme: 'snow'
      });

      form.addEventListener('submit', function(e){
        e.preventDefault();
        hiddenInput.value = editor.firstChild.innerHTML
        this.submit();
      });
    </script>
  </body>
</html>

Obviously, you’d need to sanitize this on the server before doing anything with it, as otherwise you’re expose yourself to a XSS attack.


#12

Thank you for that, I really appreciate it. Works great!

I wanted to enlarge the placeholder and I thought I could use this code in the head, but it’s not working.

<style>
  .standalone-container {
    margin: 50px auto;
    max-width: 720px;
  }
  #snow-container {
    height: 350px;
  }
</style>

If I wanted to add, lets say an icon to embed a video, would I have to use their full version by using divs?


#13

You’ll need to target div#editor. Just use your dev tools to inspect the HTML that Quill generates and apply CSS rules accordingly.


#14

Ok, thanks.

One last thing, I am looking at their “full” version code and trying to duplicate the submit post but it’s not working. Do I need to alter the code for that version in order for it to work? The placement of the code didn’t seem to make a difference.

Thanks!


#15

Probably, but hard to say without seeing what you’ve got. Could you post your code, so that I can recreate your problem.


#16
<!DOCTYPE html>

<head>
  <title>Full Editor - Quill Rich Text Editor</title>
  <meta charset="utf-8">

<link rel="canonical" href="https://quilljs.com/standalone/full/">
<link type="application/atom+xml" rel="alternate" href="https://quilljs.com/feed.xml" title="Quill - Your powerful rich text editor" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.7.1/katex.min.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/monokai-sublime.min.css" />
<link rel="stylesheet" href="../quill.snow.css" />

<style>
  body > #standalone-container {
    margin: 50px auto;
    max-width: 720px;
  }
  #editor-container {
    height: 350px;
  }
</style>

<style>
#editor-container {
  height: 450px;
}
</style>

<script>
    window.unsavedChanges = false;

    var quill = new Quill('#editor-container', {
        modules: {
            toolbar: [
      [{ header: [1, 2, false]}],
      ['bold', 'italic', 'underline'],
      ['image', 'code-block']
    ]
        },
        placeholder: 'Compose an epic...',
        theme: 'snow' // or 'bubble'
    });

    window.addEventListener("beforeunload", function (e) {
        if (window.unsavedChanges) {
            e.returnValue = 'Unsaved Changes!';
            return 'Unsaved Changes!';
        };
        return;
    });

    var syncHtml = _.debounce(function () {
        var contents = $(".ql-editor").html();
        $('myHtml').val(contents);
        console.log(contents)
        window.unsavedChanges = false;
    }, 500);

    quill.on('text-change', function () {
        window.unsavedChanges = true;
        syncHtml();
    });
         
</script>


</head>
<body>
  
<div id="standalone-container">
  <div id="toolbar-container">
    <span class="ql-formats">
      <select class="ql-font"></select>
      <select class="ql-size"></select>
    </span>
    <span class="ql-formats">
      <button class="ql-bold"></button>
      <button class="ql-italic"></button>
      <button class="ql-underline"></button>
      <button class="ql-strike"></button>
    </span>
    <span class="ql-formats">
      <select class="ql-color"></select>
      <select class="ql-background"></select>
    </span>
    <span class="ql-formats">
      <button class="ql-script" value="sub"></button>
      <button class="ql-script" value="super"></button>
    </span>
    <span class="ql-formats">
      <button class="ql-header" value="1"></button>
      <button class="ql-header" value="2"></button>
      <button class="ql-blockquote"></button>
      <button class="ql-code-block"></button>
    </span>
    <span class="ql-formats">
      <button class="ql-list" value="ordered"></button>
      <button class="ql-list" value="bullet"></button>
      <button class="ql-indent" value="-1"></button>
      <button class="ql-indent" value="+1"></button>
    </span>
    <span class="ql-formats">
      <button class="ql-direction" value="rtl"></button>
      <select class="ql-align"></select>
    </span>
    <span class="ql-formats">
      <button class="ql-link"></button>
      <button class="ql-image"></button>
      <button class="ql-video"></button>
      <button class="ql-formula"></button>
    </span>
    <span class="ql-formats">
      <button class="ql-clean"></button>
    </span>
  </div>
  <div id="editor-container"></div>
</div>

   
<script src="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.7.1/katex.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"></script>
<script src="../quill.min.js"></script>
<script>
  var quill = new Quill('#editor-container', {
    modules: {
      formula: true,
      syntax: true,
      toolbar: '#toolbar-container'
    },
    placeholder: 'Compose an epic...',
    theme: 'snow'
  });
</script>


</body>
</html>

Here’s the code - just want to be able to submit like the first example.

Thanks


#17

Not sure what you’re trying to do here.

You’re initializing the editor twice. Why is that?

The debounce function seems like it relies on underscore or lodash, which you’re not including.

window.beforeunload is also a bit flaky regarding browser support, as it was so abused by advertisers and less reputable sites.

Are you trying to autosync changes to a database, or do you want the user to manually sync changes themselves?


#18

Not really sure what that means. The code is from Quill and has their full version with more options. So what I wanted to do is be able to submit to the database like the first small version you did for me. I copy and pasted some of the code on the first example and can’t get it to post on the full version.

So what I am looking to do is to do the same thing to the full version by submitting to the post.asp page. That’s the problem; can’t seem to figure how that is done.


#19

In the head of your document, you have:

var quill = new Quill('#editor-container', { ... }

And at the foot of the page you have:

var quill = new Quill('#editor-container', { ... }

You are initializing Quill, then re-initializing it on the same element, which in the best case is superfluous and the worst case will result in the second configuration overwriting the first.


But to summarize what you are trying to do: you want to apply the previous demo (of submitting the contents of the editor at the push of a button) to the Quill editor as it is seen here: https://quilljs.com/standalone/full/

Did I get that right?


#20

I do see the duplication, but that was on the Quill form.

YES - you got it right. I want to be able to submit on that form which has more tools.


#21

Like this:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Full Editor - Quill Rich Text Editor</title>
    <meta charset="utf-8">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.7.1/katex.min.css" />
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/monokai-sublime.min.css" />
    <link rel="stylesheet" href="https:/cdn.quilljs.com/1.3.6/quill.snow.css" />
    <style>
      body > #standalone-container {
        margin: 50px auto;
        max-width: 720px;
      }
      #editor-container {
        height: 350px;
      }
    </style>
  </head>
  <body>
    <div id="standalone-container">
      <div id="toolbar-container">
        <span class="ql-formats">
          <select class="ql-font"></select>
          <select class="ql-size"></select>
        </span>
        <span class="ql-formats">
          <button class="ql-bold"></button>
          <button class="ql-italic"></button>
          <button class="ql-underline"></button>
          <button class="ql-strike"></button>
        </span>
        <span class="ql-formats">
          <select class="ql-color"></select>
          <select class="ql-background"></select>
        </span>
        <span class="ql-formats">
          <button class="ql-script" value="sub"></button>
          <button class="ql-script" value="super"></button>
        </span>
        <span class="ql-formats">
          <button class="ql-header" value="1"></button>
          <button class="ql-header" value="2"></button>
          <button class="ql-blockquote"></button>
          <button class="ql-code-block"></button>
        </span>
        <span class="ql-formats">
          <button class="ql-list" value="ordered"></button>
          <button class="ql-list" value="bullet"></button>
          <button class="ql-indent" value="-1"></button>
          <button class="ql-indent" value="+1"></button>
        </span>
        <span class="ql-formats">
          <button class="ql-direction" value="rtl"></button>
          <select class="ql-align"></select>
        </span>
        <span class="ql-formats">
          <button class="ql-link"></button>
          <button class="ql-image"></button>
          <button class="ql-video"></button>
          <button class="ql-formula"></button>
        </span>
        <span class="ql-formats">
          <button class="ql-clean"></button>
        </span>
      </div>
      <div id="editor-container"></div>
    </div>

    <form method="POST" action="post.asp" name="mainform">
      <input type="hidden" id="myHtml"/>
      <button type="submit">Submit</submit>
    </form>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.7.1/katex.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"></script>
    <script src="https://cdn.quilljs.com/1.3.6/quill.min.js"></script>
    <script>
      const editor = document.getElementById('editor-container');
      const hiddenInput = document.getElementById('myHtml');
      const form = document.forms.mainform;

      const quill = new Quill(editor, {
        modules: {
          syntax: true,
          toolbar: '#toolbar-container'
        },
        placeholder: 'Compose an epic...',
        theme: 'snow'
      });

      form.addEventListener('submit', function(e){
        e.preventDefault();
        hiddenInput.value = editor.firstChild.innerHTML
        this.submit();
      });
    </script>
  </body>
</html>