Quill: isEmpty()

Created on 9 Jul 2014  路  12Comments  路  Source: quilljs/quill

It would be nice to have an isEmpty function that returns a boolean.

I originally went with this

var empty = $(scope.ngModel).text().length == 0

but then if someone posted only an image it would report empty even though it isn't.

There might be some ambiguity over what exactly is empty, but this seems like a generalized feature that many forms would need.

Most helpful comment

I ended up going with:

function isQuillEmpty(quill) {
    if (JSON.stringify(quill.getContents()) == "\{\"ops\":[\{\"insert\":\"\\n\"\}]\}") {
        return true;
    } else {
        return false;
    }
}

That should catch if there is any text, images, or combination thereof.

All 12 comments

What about something like quill.getLength() === 0? Or if you want to ignore whitespace quill.getText().trim().length === 0.

ah, should have un-angularized the example I gave. For some reason, both locally and on http://quilljs.com, when I remove everything from the main editor(cmd-a + delete) and run

quill.getLength()

1 is returned. As I type it increments correctly, but it's always overestimating by 1.

Ah a non-obvious 'feature' of Quill is that there's almost always a trailing newline (I believe it can be removed via the API but I can't think of a way a user via the interface could get rid of it). So checking for the text to be equal to \n as an empty check _should_ be safe but getText().trim() would work too.

Just a note:

What about something like quill.getLength() === 0? Or if you want to ignore whitespace quill.getText().trim().length === 0.

If I only add an image, but no text, quill.getText().trim().length returns 0 too. (And getLength() returns 1)

This is what i end up using.
isQuillEmpty(){
return this.quill.getContents().ops[0].insert == '\n' && this.quill.getLength() < 2;
}
Use getContents() since it doesn't ommit image delta.
If its a newline check op length.
--if there's only one op, than that's quill's default newline and it is considered empty.
--otherwise that's probably user's newline because quill creates new op when you press enter.

Suppose we have an image upload. Images are inserted as IMG tags.
Cases:
"Hit Enter or several Enters" = Quill is empty = Don't save/submit.
"Only image uploaded (no any text)" = Quill is not empty = Save/Submit.

`js isQuillEmpty() { return this.quill.getText().trim().length === 0 && this.quill.container.firstChild.innerHTML.includes("img") === false; }

@alexdroronin That won't work if there's a formula. We need a solution that's a bit more general...

@nathanieltagg I would suggest using some regex to validate content. I use this, quite reliable.

/**
 * Check whether editor content is empty or not.
 * @return {Bool}
 */
isEmpty = () => {
    const commentText = this.quill.getText().trim();
    const re = /^<p>(<br>|<br\/>|<br\s\/>|\s+|)<\/p>$/gm;
    return re.test(commentText);
};

I ended up with something like this:

const isEmpty = htmlString => {
    const parser = new DOMParser();

    const { textContent } = parser.parseFromString(htmlString, "text/html").documentElement;

    return !textContent.trim();
}

I ended up going with:

function isQuillEmpty(quill) {
    if (JSON.stringify(quill.getContents()) == "\{\"ops\":[\{\"insert\":\"\\n\"\}]\}") {
        return true;
    } else {
        return false;
    }
}

That should catch if there is any text, images, or combination thereof.

Empty for my use case is both:

  1. nothing but text inserted (no media, formulas, etc, so only one op) _and_
  2. no text except potentially spaces/tabs/returns/etc (text removed via js trim())
isQuillEmpty(quill) {
  if ((quill.getContents()['ops'] || []).length !== 1) { return false }
  return quill.getText().trim().length === 0
}
isQuillEmpty(quill) {
  if ((quill.getContents()['ops'] || []).length !== 1) { return false }
  return quill.getText().trim().length === 0
}

This is the proper solution. Thanks.

Was this page helpful?
0 / 5 - 0 ratings