Quill Editor script to read from database

Example #1 works in that it will read from the database. This is the code is question:

      // Fetch content from database here
      const editorContent = '<%=Myhtml%>'

#2 which uploads images (#1 does not) DOESN’T read what’s in the database.

Here is #1:

<!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>
      <br />

    <center>
    <form method="POST" action="post.asp" name="mainform">
      <input type="hidden" id="myHtml" name= "myHtml">
      <input type="submit" value="Submit">
    </form>
    </center>
    <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>
      // Fetch content from database here
      const editorContent = '<%=Myhtml%>'
      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>

Here is #2:

<!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="standalone-container">
        <div id="toolbar-container">

        <span class="ql-formats">
          <button class="ql-bold"></button>
          <button class="ql-italic"></button>
          <button class="ql-underline"></button>
        </span>
        <span class="ql-formats">
          <select class="ql-color"></select>
          <select class="ql-background"></select>
        </span>

        <span class="ql-formats">
          <button class="ql-header" value="1"></button>
          <button class="ql-header" value="2"></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>
        </span>

      </div>
      <div id="editor-container"></div>
      <br />

    <center>
    <form method="POST" action="post.asp" name="mainform">
      <input type="hidden" id="myHtml" name= "myHtml">
      <input type="submit" value="Submit">
    </form>
    </center>
    <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>
      // Fetch content from database here
      const editorContent = '<%=Myhtml%>'
      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();
      });

      function selectLocalImage() {
        const input = document.createElement('input');
        input.setAttribute('type', 'file');
        input.click();

        // Listen upload local image and save to server
        input.onchange = () => {
          const file = input.files[0];

          // file type is only image.
          if (/^image\//.test(file.type)) {
            saveToServer(file);
          } else {
            console.warn('You could only upload images.');
          }
        };
      }

      function saveToServer(file) {
        const fd = new FormData();
        fd.append('image', file);
        const xhr = new XMLHttpRequest();
        xhr.open('POST', 'http://localhost/post.asp', true);
        xhr.onload = () => {
          if (xhr.status === 200) {
            console.log(xhr.responseText);
          }
        };
        xhr.send(fd);
      }

      function insertToEditor(url) {
        // push image url to rich editor.
        const range = quill.getSelection();
        quill.insertEmbed(range.index, 'image', `https://mydomain${url}`);
      }

      quill.getModule('toolbar').addHandler('image', () => {
        selectLocalImage();
      });
    </script>
  </body>
</html>

Perhaps it is something as simple as placement of code, but I can’t figure it out. Any help would be appreciated.

So you’re saying that when a user enters text into Quill it is saved to a database. Then when the user returns to the site at a later date, the following line is enough to fetch the text they previously entered and display it in the editor:

const editorContent = '<%=Myhtml%>';

However, when you expand your script to allow users to add images (which are uploaded to your server — not stored in the database), then the above line doesn’t work.

Did I get that right?

YES

In Example #1 (no upload of photo script) all data stored in database displays in editor.

In Example #2 (modified script of #1) even though information is in the database and the images are stored in a folder on the server, it doesn’t show in the editor.

If I move <%=Myhtml%> (the ASP call for the data) outside of the editor then the information is displayed on the page including photos - it’s just not displaying in editor.

Interesting. Sounds like it might be a timing issue, that the script is inserting the images in the editor, before they have had time to load.

I’m not seeing the editorContent variablke used anywhere in the code that you posted. Could you pls add the code that inserts the database response into the editor.

I found the missing line of code - once added - it works.

editor.firstChild.innerHTML = editorContent;

One additional issue: Works in all browsers except IE11. This is the look:
sitepoint6

I remember this was an issue that was fixed before the photo uploader. Do see any minor tweaks to fix that issue?

Thank you.

Can you post your final JavaScript code and I’ll see what’s killing it for IE.


<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>
       // Fetch content from database here
      const editorContent = '<%=rs("myHtml")%>'
      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'
      });

      editor.firstChild.innerHTML = editorContent;

      form.addEventListener('submit', function(e){
        e.preventDefault();
        hiddenInput.value = editor.firstChild.innerHTML
        this.submit();
      });

      function selectLocalImage() {
        const input = document.createElement('input');
        input.setAttribute('type', 'file');
        input.click();

        // Listen upload local image and save to server
        input.onchange = () => {
          const file = input.files[0];

          // file type is only image.
          if (/^image\//.test(file.type)) {
            saveToServer(file);
          } else {
            console.warn('You could only upload images.');
          }
        };
      }

      function saveToServer(file) {
        const fd = new FormData();
        fd.append('image', file);
        const xhr = new XMLHttpRequest();
        xhr.open('POST', 'http://localhost/post.asp', true);
        xhr.onload = () => {
          if (xhr.status === 200) {
            const url = xhr.responseText;
            insertToEditor(url);
          }
        };
        xhr.send(fd);
      }

     

      function insertToEditor(url) {
        // push image url to rich editor.
        const range = quill.getSelection();
        quill.insertEmbed(range.index, 'image', `https://mydomain${url}`);
      }

      quill.getModule('toolbar').addHandler('image', () => {
        selectLocalImage();
      });
    </script>

This should work:

// Fetch content from database here
var editorContent = '<%=rs("myHtml")%>';
var editor = document.getElementById('editor-container');
var hiddenInput = document.getElementById('myHtml');
var form = document.forms.mainform;

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

editor.firstChild.innerHTML = editorContent;

form.addEventListener('submit', function (e) {
  e.preventDefault();
  hiddenInput.value = editor.firstChild.innerHTML;
  this.submit();
});

function selectLocalImage() {
  var input = document.createElement('input');
  input.setAttribute('type', 'file');
  input.click(); // Listen upload local image and save to server

  input.onchange = function () {
    var file = input.files[0]; // file type is only image.

    if (/^image\//.test(file.type)) {
      saveToServer(file);
    } else {
      console.warn('You could only upload images.');
    }
  };
}

function saveToServer(file) {
  var fd = new FormData();
  fd.append('image', file);
  var xhr = new XMLHttpRequest();
  xhr.open('POST', 'http://localhost/post.asp', true);

  xhr.onload = function () {
    if (xhr.status === 200) {
      var url = xhr.responseText;
      insertToEditor(url);
    }
  };

  xhr.send(fd);
}

function insertToEditor(url) {
  // push image url to rich editor.
  var range = quill.getSelection();
  quill.insertEmbed(range.index, 'image', "https://mydomain".concat(url));
}

quill.getModule('toolbar').addHandler('image', function () {
  selectLocalImage();
});
1 Like

That works as far as inserting the data into the editor, but only in IE on an Windows 8.1, the upload icon doesn’t work (interesting). Works in IE, Windows 10 though.

In all of IE when you click on the image it is surrounded with square dots as a placeholder. This is good for deleting or hyperlinking. In Chrome and FF it doesn’t have the squares around the image, so if you want to hyperlink it you have to place the cursor next to it; then it will hyperlink.

Not sure if that is fixable or not? Maybe that is a characteristic of FF and Chrome, not sure.

image2

Again, thanks for your help - appreciated.

No worries. I’m not sure how much help I can be with IE specific stuff, as I am on Linux and haven’t used IE in ages.

If you’d like to seek help in this matter, I’d recommend making a working demo you can link to, then posting a question in the HTML/CSS forum.

1 Like

Not a problem - you have been a tremendous help and your knowledge in this matter is impressive. Thank you very much!

PS… The alignments of left, right, center, justify don’t work. In the editor they properly display, but once posted all alignments are left. I am guessing that must be a Quill issue.

Not sure I quite follow here. Do you mean that you can justify text in the editor just fine, but when you save it to the database, then reload the saved text, the justify styles are no longer applied?

YES

I am surprised I didn’t catch that earlier. I have double and triple checked it with different browsers and different web pages. Here you can see the results: First the editor view and second the output page.
editor%20test
OUTPUT PAGE:
editor%20output

This is the html on the output page:

<h1 class="ql-align-center">Hello, this is a test!</h1><h1>Hello, this is a test!</h1><h1 class="ql-align-right"><span style="color: rgb(230, 0, 0);">Hello, this is a test!</span></h1><h1><u style="color: rgb(0, 102, 204);">Hello, this is a test!</u></h1></font>

I also tried, thinking this was my issue, putting the css links from Quill on the output page and that didn’t make any difference.

So it’s a mystery to me!

Is it possible that you can PM me a link where I can see this error in action?

Thanks for the link. For me, in latest Firefox, the justification works as expected. This is what I see when I align the text differently, then press the back button and refresh the page.

Is the problem only occurring in IE?

The text alignments (not just justifications, but center, right) and the font formatting isn’t correct on the OUTPUT page. It’s okay in the editor, but the editor is what is not going to be viewed ultimately from the customer. What is in the Editor in terms of formatting should carryover to the post or output page.

All browsers are the same in terms of results.

sitepoint8

Take the html from the output page and insert into a different page and you will get the same results.

<h1 class="ql-align-right">Right Align</h1><h1 class="ql-align-center">Centered Text</h1><h1 class="ql-align-justify"><br></h1><h1 class="ql-align-justify">Justified Text Justified Text Justified Text Justified Text Justified Text Justified Text</h1><p><br></p><p class="ql-align-center"><br></p>

Yeah, you’ll need to include the Quill CSS to make that work. One of these, I would imagine:

<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" />

Yes, I had mentioned that I had tried that before and it doesn’t change the outcome. Take another look at your view source because I added that to my post page.

Thanks!

The styles are in the quill.snow.css file. Here you find:

.ql-editor .ql-align-right {
  text-align: right;
}

Which means the CSS is looking for an element with a class of ql-align-right inside an element with a class of ql-editor.

Add that to your outputted HTML and you should be good.

i.e. change this:

Done! - Below is the the response.write myHtml<br><br>
You can use your back arrow key to go back to the editor<br><br>
Be sure to REFRESH the page to see the changes in the editor<br><br>
Right click to view source.
<h1>Left Align</h1>
<h1 class="ql-align-right">Right Align</h1>
<h1 class="ql-align-center">Centered Text</h1>
<h1 class="ql-align-justify"><br></h1><h1 class="ql-align-justify">Justified Text Justified Text Justified Text Justified Text Justified Text Justified Text</h1>

to:

<div class="ql-editor">
  Done! - Below is the the response.write myHtml<br><br>
  You can use your back arrow key to go back to the editor<br><br>
  Be sure to REFRESH the page to see the changes in the editor<br><br>
  Right click to view source.
  <h1>Left Align</h1>
  <h1 class="ql-align-right">Right Align</h1>
  <h1 class="ql-align-center">Centered Text</h1>
  <h1 class="ql-align-justify"><br></h1><h1 class="ql-align-justify">Justified Text Justified      Text Justified Text Justified Text Justified Text Justified Text</h1>
</div>

Added that to the post page and still no difference.

Once I get this correct, would probably need to add center and justify - plus Sans Serif and Serif. The larger text sizes and colors work but not what we are currently discussing.

Thanks