km6
km6

Reputation: 2530

Convert Quill Delta to HTML

How do I convert Deltas to pure HTML? I'm using Quill as a rich text editor, but I'm not sure how I would display the existing Deltas in a HTML context. Creating multiple Quill instances wouldn't be reasonable, but I couldn't come up with anything better yet.

I did my research, and I didn't find any way to do this.

Upvotes: 54

Views: 70679

Answers (18)

Captain Fantastic
Captain Fantastic

Reputation: 452

Here's a full function using quill.root.innerHTML, as the others didn't quite cover the complete usage of it:

function quillGetHTML(inputDelta) {
        var tempQuill=new Quill(document.createElement("div"));
        tempQuill.setContents(inputDelta);
        return tempQuill.root.innerHTML;
    }

This is just a slight different variation of km6's answer.

Upvotes: 9

Mudassar Iqbal
Mudassar Iqbal

Reputation: 33

I'm simply using in this way in MVC razor view and with javascript:

var txtNotes = document.querySelector(".ql-editor").innerHTML;

and when it come back from database then:

<div id="notes-text" class="text-details">
            @Html.Raw(!string.IsNullOrEmpty(Model.Notes) ? Model.Notes.ReplaceLinks().Replace("\n", "<br />") : "(No call notes were added)")
        </div>

Upvotes: 0

LazerDance
LazerDance

Reputation: 338

Just use this clean library to convert from delta from/to text/html

node-quill-converter

example:

const { convertDeltaToHtml } = require('node-quill-converter');

let html = convertDeltaToHtml(delta);

console.log(html) ; // '<p>hello, <strong>world</strong></p>'

Upvotes: 0

Lejossan
Lejossan

Reputation: 149

This is a very common confusion when it comes to Quilljs. The thing is you should NOT retrieve your html just to display it. You should render and display your Quill container just the same way you do when it is an editor. This is one of the major advantages to Quilljs and the ONLY thing you need to do is:

$conf.readOnly = true;

This will remove the toolbar and make the content not editable.

Upvotes: 13

Fifi
Fifi

Reputation: 3605

For Quill version 1.3.6, just use:

quill.root.innerHTML;

Upvotes: 6

NR Ganesh
NR Ganesh

Reputation: 111

Here is a proper way to do it.

var QuillDeltaToHtmlConverter = require('quill-delta-to-html').QuillDeltaToHtmlConverter;

// TypeScript / ES6:
// import { QuillDeltaToHtmlConverter } from 'quill-delta-to-html'; 

var deltaOps =  [
    {insert: "Hello\n"},
    {insert: "This is colorful", attributes: {color: '#f00'}}
];

var cfg = {};

var converter = new QuillDeltaToHtmlConverter(deltaOps, cfg);

var html = converter.convert(); 

Refer https://github.com/nozer/quill-delta-to-html

Upvotes: 2

Michal - wereda-net
Michal - wereda-net

Reputation: 959

Simple, solution is here: https://www.scalablepath.com/blog/using-quill-js-build-wysiwyg-editor-website/

The main code is:

console.log(quill.root.innerHTML);

Upvotes: 14

Genesis
Genesis

Reputation: 8158

For a jQuery-style solution that allows getting and setting the Quill value I am doing the following:

Quill.prototype.val = function(newVal) {
  if (newVal) {
    this.container.querySelector('.ql-editor').innerHTML = newVal;
  } else {
    return this.container.querySelector('.ql-editor').innerHTML;
  }
};


let editor = new Quill( ... );

//set the value    
editor.val('<h3>My new editor value</h3>');

//get the value
let theValue = editor.val();

Upvotes: 1

Joel Colucci
Joel Colucci

Reputation: 461

I put together a node package to convert html or plain text to and from a Quill Delta.

My team used it to update our data model to include both Quill's Delta and HTML. This allows us to render on the client without an instance of Quill.

See node-quill-converter.

It features the following functions: - convertTextToDelta - convertHtmlToDelta - convertDeltaToHtml

Behind the scenes it uses an instance of JSDOM. This may make it best suited for migration scripts as performance has not been tested in a typical app request lifecycle.

Upvotes: 3

Remy
Remy

Reputation: 894

If I've understood you correctly, there's a quill thread of discussion here, with the key information you're after.

I've quoted what should be of most value to you below:

Quill has always used Deltas as a more consistent and easier to use (no parsing) data structure. There's no reason for Quill to reimplement DOM APIs in addition to this. quill.root.innerHTML or document.querySelector(".ql-editor").innerHTML works just fine (quill.container.firstChild.innerHTML is a bit more brittle as it depends on child ordering) and the previous getHTML implementation did little more than this.

Upvotes: 21

agm1984
agm1984

Reputation: 17132

Here is how I did it, for you Express folks. It seems to have worked very well in conjunction with express-sanitizer.

app.js

 import expressSanitizer from 'express-sanitizer'

 app.use(expressSanitizer())

 app.post('/route', async (req, res) => {
     const title = req.body.article.title
     const content = req.sanitize(req.body.article.content)
     // Do stuff with content
 })

new.ejs

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

 ...

 <form action="/route" method="POST">
     <input type="text" name="article[title]" placeholder="Enter Title">
     <div id="editor"></div>
     <input type="submit" onclick="return quillContents()" />
 </form>

 ...

 <script src="https://cdn.quilljs.com/1.3.2/quill.js"></script>
 <script>
     const quill = new Quill('#editor', {
         theme: 'snow'
     })

     const quillContents = () => {
         const form = document.forms[0]
         const editor = document.createElement('input')

         editor.type = 'hidden'
         editor.name = 'article[content]'
         editor.value = document.querySelector('.ql-editor').innerHTML
         form.appendChild(editor)

         return form.submit()
     }
</script>

express-sanitizer (https://www.npmjs.com/package/express-sanitizer)

document.forms (https://developer.mozilla.org/en-US/docs/Web/API/Document/forms)

My view only has one form, so I used document.forms[0], but if you have multiple or may extend your view in the future to have multiple forms, check out the MDN reference.

What we are doing here is creating a hidden form input that we assign the contents of the Quill Div, and then we bootleg the form submit and pass it through our function to finish it off.

Now, to test it, make a post with <script>alert()</script> in it, and you won't have to worry about injection exploits.

That's all there is to it.

Upvotes: 2

Ara&#250;jo Everson
Ara&#250;jo Everson

Reputation: 75

Try

console.log ( $('.ql-editor').html() );

Upvotes: 2

agrim2936
agrim2936

Reputation: 51

quill.root.innerHTML on the quill object works perfectly.

 $scope.setTerm = function (form) {
                var contents = JSON.stringify(quill.root.innerHTML)
                $("#note").val(contents)
                $scope.main.submitFrm(form)
            }

Upvotes: 3

Talha
Talha

Reputation: 1636

I guess you want the HTML inside it. Its fairly simple.

quill.root.innerHTML

Upvotes: 35

yo_0
yo_0

Reputation: 21

If you want to render quill using nodejs, there is a package quite simple based on jsdom, usefull to render backside (only one file & last update 18 days from now) render quill delta to html string on server

Upvotes: 0

Ankush Tanwar
Ankush Tanwar

Reputation: 239

I have accomplished it in the backend using php. My input is json encoded delta and my output is the html string. here is the code , if it is of any help to you.This function is still to handle lists though and some other formats but you can always extend those in operate function.

function formatAnswer($answer){
    $formattedAnswer = '';
    $answer = json_decode($answer,true);
    foreach($answer['ops'] as $key=>$element){
        if(empty($element['insert']['image'])){
            $result = $element['insert'];
            if(!empty($element['attributes'])){
                foreach($element['attributes'] as $key=>$attribute){
                    $result = operate($result,$key,$attribute);
                }
            }
        }else{ 
            $image = $element['insert']['image'];
            // if you are getting the image as url
            if(strpos($image,'http://') !== false || strpos($image,'https://') !== false){
                $result = "<img src='".$image."' />";
            }else{
                //if the image is uploaded 
                //saving the image somewhere and replacing it with its url
                $imageUrl = getImageUrl($image);
                $result = "<img src='".$imageUrl."' />";
            }
        }
        $formattedAnswer = $formattedAnswer.$result;
    }
    return nl2br($formattedAnswer);
}

function operate($text,$ops,$attribute){
    $operatedText = null;
    switch($ops){
        case 'bold': 
        $operatedText = '<strong>'.$text.'</strong>';
        break;
        case 'italic':
        $operatedText = '<i>'.$text.'</i>';
        break;
        case 'strike':
        $operatedText = '<s>'.$text.'</s>';
        break;
        case 'underline':
        $operatedText = '<u>'.$text.'</u>';
        break;
        case 'link':
        $operatedText = '<a href="'.$attribute.'" target="blank">'.$text.'</a>';
        break;
        default:
        $operatedText = $text;
    }
    return $operatedText;
}

Upvotes: 7

km6
km6

Reputation: 2530

Not very elegant, but this is how I had to do it.

function quillGetHTML(inputDelta) {
    var tempCont = document.createElement("div");
    (new Quill(tempCont)).setContents(inputDelta);
    return tempCont.getElementsByClassName("ql-editor")[0].innerHTML;
}

Obviously this needs quill.js.

Upvotes: 43

user2994322
user2994322

Reputation:

quill-render looks like it's what you want. From the docs:

var render = require('quill-render');
render([
    {
        "attributes": {
            "bold": true
        },
        "insert": "Hi mom"
    }
]);
// => '<b>Hi mom</b>'

Upvotes: 0

Related Questions