WYSIWYG editors


#42

Yes, that is correct.


#43

Nope. Still don’t get it sorry. Where is that happening? Are you trying to display the user-entered data elsewhere?


#44

In using the post page, that would be the html data that will be stored in the database. So I want that content to be the same look as the editor. For example, with using this editor, if I click on bold, I would see bold print. This is stored in the database so once drawn to the page, if should show bold.

The only issue with the Quill editor seems to be that if I use this:
editor

The html will go into the database but once displayed it won’t show the same on the page as it did in the editor.


#45

Sorry. I’m lost :frowning:

For example, this doesn’t make any sense to me.

@Mittineague can you spot what I’m missing?


#46

For example, if you put this code into an html file, you wouldn’t get the same as in post #40 that came from the editor:


<p><span class="ql-size-large">I am a paragraph</span></p><p><br></p><p><span class="ql-size-huge">I am a paragraph</span></p><p><br></p><p><span class="ql-size-large">I am a paragraph</span></p><p><br></p><p><span class="ql-font-serif ql-size-large">I am a paragraph</span></p>

#47

The code in post # 21 works for me after making some changes

...
<!--      <button type="submit">Submit</submit> -->
      <button type="submit" name="submit">Submit</button>
...
console.log(editor.firstChild.innerHTML); // check for value 
//        this.submit();

* note I added a name attribute
* I don’t have a post.asp to submit to

The styles come from the quill.snow.css file.

<link rel="stylesheet" href="https:/cdn.quilljs.com/1.3.6/quill.snow.css" />

If you wanted to use the generated HTML in another page, you could likewise pull that CSS file into the page. As long as the selectors aren’t too specific (i.e. class only) it should work.


#48

The post page issue I believe is not formatting because the post page needs css properties… no big deal on that.

Here’s the more important issues. I have created a database and the post.asp page is now an insert into the database page. All works good there.

Here’s the issue: I now want to pull up in the editor the contents of MyHtml field for a given ID number.

I can pull it to the page but want the content in the database to be in the editor to edit.

So how do I bring rs(“myHtml”) to the editor?


#49

Aaahh. Got it.

All you need to do is to set the innerHTML of editor.firstChild to be whatever you have fetched from the database.

An example:

<!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</button>
    </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>
      // Fetch content from database here
      const editorContent = '<p><span class="ql-size-large">Heading</span></p><p>paragraph with <strong>bold</strong> text</p><pre class="ql-syntax" spellcheck="false"><span class="hljs-attr">a</span>=<span class="hljs-number">1</span>;</pre>'

      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
        console.log(editor.firstChild.innerHTML)
      });
    </script>
  </body>
</html>

I’ve hardcoded the values coming from the DB. You’d need to fetch yours dynamically, but the principle is the same.


Note that although Quill seems to take steps to protect you from XXS attacks, as a rule, you should never trust anything the user inputs, especially when outputting it back to the page.

I would therefore advise you to implement some form of sanitization on the server on whatever you are receiving (as per this comment).

HTH


#50

Perfect. Nice job!!!
I really appreciate your input on this and thank you very much!
Have noted your comments on attacks - thanks.


#51

I have spent hours doing research on sanitizing html because I want to get it right. Boy, I am confused more than ever now! I read that use Regex and then don’t use Regex. I read use Javascript and then don’t use Javascript. I use ASP files for my form post - and there is not much about that anymore. I read sanitize on input and then also more important on output page. So if anybody has a good example for me to use, I would appreciate it. For example, my form input field is named “MyHtml” per the editor that I want to use. Thank you!


#52

I don’t have much experience with ASP, so I can’t advise you there, but in broad terms make sure you use a prepared statement when inserting the data into the database and look for ASP string sanitize methods.

We have an .NET category here, so it might be worth starting a new topic there?


#53

I have not studied this topic in depth and have no ASP knowledge but wonder if it is possible to store plain text in the database and use a format similar to the following PHP MVC approach which would eliminate the need for sanitising.

echo '<h1 class="xyz">' .$title .'</h1>';

or

<h1 class="xyz"> <?= title ?> </h1>

Another reason I like this approach is because I have vague memories of trying to pinpoint a formatting problem, It took a long time to resolve and eventually found that CSS formatting was stored in a database table.


#54

I wanted to add an image resizer to the code you provided that works fine. I got this from:

So I added the JS to the bottom of the page and can’t get it to work.
Can you tell what I am missing here?
Thanks


#55

I do not understand what that means. Are you asking if there are any HTML WYSIWYG editors written using JavaScript and CSS or are you asking if there are any HTML WYSIWYG editors that support writing JavaScript and CSS within HTML? I hope you understand there is a big difference.

That sounds strange and I think everyone is ignoring that. It is not normal to do that. In a traditional website HTML is normally stored as a file and the server simply reads the file like a text file is read. Note that something like PHP is different but you are not asking about things like. Either you do not need to store the HTML in a database or that part should be a separate question. Perhaps you are more interested in learning how to upload a website (HTML files) to a host.

There are very many WYSIWYG editors. The choice is often a matter of personal preference. For hard-core work that includes significant amounts of programming, there is Eclipse and Microsoft Visual Studio, among others. Note that Visual Studio Code is very different from what the call Visual Studio IDE. Microsoft Expression Web is closer to what you might want, but as I said, your personal preference makes a big difference.

The World Wide Web Consortium (W3C) is an international community of web developers and such. They were a big part of the creation of the internet. You might want to try their Amaya. It does not appear to be something I would use

Look at List of HTML editors - Wikipedia for a big list of possibilities. Also look at articles such as The 10 Best WYSIWYG HTML Editors - 1stWebDesigner. There are also online editors such as Online HTML Editing Tools.

Since you say JavaScript, you probably want to find an editor that supports debugging JavaScript. That might be a priority for you.


#56

The JS code that I referenced was for an add on to post #21. I didn’t mention anything about CSS.


#57

I don’t know what that is a reply to so I apologize if the following is not relevant.

That is a quote from your initial post. You did say CSS. And I apologize if I seem critical about on a html page; I don’t want to be critical, I am just saying that it is unclear.


#58

Do you see any errors in the console?
If not, could you post your HTML, please.


#59
<!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">
          <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>
      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>

So I am not sure how to use this code and incorporate it with the above code that works fine. In replacing it with the script before the </body>, there is no error in the console but the form doesn’t display menus.

<script>
var quill = new Quill('#editor', {
    theme: 'snow',
     modules: {
        imageResize: {
          displaySize: true
        },
       toolbar: [
         [{ 'header': [1, 2, 3, 4, 5, 6, false] }],
         ['bold', 'italic', 'underline', 'strike'],
         [{ 'color': [] }, { 'background': [] }], 
         [{ 'align': [] }],
         ['link', 'image'],
         
         ['clean']  
       ]
    }
});
</script>

#60

All you need to do is include the module as a script tag and register it in your constructor:

<script src="https://cdn.rawgit.com/kensnyder/quill-image-resize-module/3411c9a7/image-resize.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',
      imageResize: { displaySize: true },
    },
    placeholder: 'Compose an epic...',
    theme: 'snow'
  });
</script>

#61

That was too simple! You know your stuff - wish I did!!
If you go to rawgit website they say that they have reached the end of its useful life and to stop using it by October 2019. The base64 images turn out to be too large for database if you have more than a couple. That being said, I think if I want to store images, it’s best to use my own uploader.

On github.com there is code for that to happen, but I am not sure how to incorporate it. Here is the code:

const editor = new Quill('#quill-editor', {
      bounds: '#quill-editor',
      modules: {
        toolbar: this.toolbarOptions
      },
      placeholder: 'Free Write...',
      theme: 'snow'
    });

      /**
       * Step1. select local image
       *
       */
    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.');
        }
      };
    }

    /**
     * Step2. save to server
     *
     * @param {File} file
     */
    function saveToServer(file: File) {
      const fd = new FormData();
      fd.append('image', file);

      const xhr = new XMLHttpRequest();
      xhr.open('POST', 'http://localhost:3000/upload/image', true);
      xhr.onload = () => {
        if (xhr.status === 200) {
          // this is callback data: url
          const url = JSON.parse(xhr.responseText).data;
          insertToEditor(url);
        }
      };
      xhr.send(fd);
    }

    /**
     * Step3. insert image url to rich editor.
     *
     * @param {string} url
     */
    function insertToEditor(url: string) {
      // push image url to rich editor.
      const range = editor.getSelection();
      editor.insertEmbed(range.index, 'image', `http://localhost:9000${url}`);
    }

    // quill editor add image handler
    editor.getModule('toolbar').addHandler('image', () => {
      selectLocalImage();
    });

It’s the post made on Dec. 18, 2018

If you could incorporate that with my previous code, I would greatly appreciate it. Probably simple but complex for me!
Thank you very much.