-
Notifications
You must be signed in to change notification settings - Fork 3.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for check boxes #759
Comments
Barring surprises, it may actually be fairly straightforward to add this. Other editors like Dropbox Paper uses the CSS content property and a background image to show the check and box and Quill also uses the content property for showing bullets and lists. It would not be possible to change the checkbox's color in an edit session with this approach, though this is probably an acceptable limitation. Alternatively a unicode character could be used instead of a background image which could allow for color customization in an edit session. To distinguish between the checklist from a bulleted list you could use either an attribute or class and check for this in the List blot implementation so Other than that I'm not sure anything else needs to be done but surprises do come up. |
So I was able to use your suggested approach to create a new list attribute value "checkbox" in addition to "bullet" and "ordered" that will then render a checkbox image using a CSS content property instead of a bullet. I'm successfully creating new items in this list type with the rendered checkbox image. But I'm struggling to figure out where and how I should I attach the event handler to handle checking the checkbox. It doesn't seem like I can target an event handler to a :before element. I could target the whole li item, but when they click on the item's text, I just want to focus the editor on the line so they can edit the value of the checklist item as opposed to toggling the checkbox. After I figure out where to target, then I'm not sure how I go about modifying the list item's value to update the checked state. I could attach an event handler in the static create method, but then I'd need to know the specific index of the clicked element to be able to issue a quill.formatLine() command, but it doesn't look like I have access to that. Any thoughts? |
I would explore attaching to the You could format the blot directly with something like this: var listBlot = Parchment.find(listNode);
listBlot.format('list', 'checked'); Quill's |
Thanks for the suggestions, they both helped. I ended up moving away from creating the checklist type as an extension of the list type. That's because it kept resulting in checking one list item causing all of the items within the parent list becoming checked as well, given each list item was part of the same list and I was keeping the value for checked or unchecked at the list level. I instead implemented the checklist as an independent block-level format with tag DIV and className ql-checklist and still using a :before element to render the checkboxes. This worked a lot better since each checklist item could have it's independent checked or unchecked value that wasn't affected by neighboring items. I used the offsetX approach to decide when the click was on the checkbox, which is a bit brittle because it depends on coordinating the padding-left of the ql-checklist css class with the acceptable offsetX. But overall the checklist is now working great for me. I assume you'd be interested in a PR only after 1.0? |
I can take a look at a PR now but depending on the potential surface area for bugs it might be included after 1.0. |
@sachinrekhi would it be possible to take a look at the format module you came up with? |
@sachinrekhi I was troubled by this problem for a long time, look forward to your PR! |
@sachinrekhi I'm really interested as well in the solution you found for this! It would be a great feature |
I implemented a task list plugin https://github.com/koffeinfrei/quill-task-list.
|
Thank you for sharing your implementation @koffeinfrei. I made some additions that supports checklist on model/data layer along with some tests demonstrating how work. The missing piece is how to check/uncheck on user click, and also which layer that belongs in. The following does work to try out but hardcodes some pixel values and is probably operating at the wrong abstraction layer: this.quill.root.addEventListener('mousedown', (e) => {
if (!this.quill.isEnabled()) return
let blot = Parchment.find(e.target)
if (blot == null || blot.statics.blotName !== 'list-item') return
let value = blot.parent.formats().list
if (value !== 'checked' && value !== 'unchecked') return
let range = this.quill.getSelection()
let index = blot.offset(this.quill.scroll)
let bounds = this.quill.getBounds(index)
let left = e.offsetX + blot.domNode.offsetLeft + blot.parent.domNode.offsetLeft
if (left < bounds.left - 18 || bounds.left < left) return
blot.format('list', value === 'checked' ? 'unchecked' : 'checked')
this.quill.setSelection(null, Quill.sources.SILENT)
this.quill.setSelection(range, Quill.sources.SILENT)
e.preventDefault()
}) I'd appreciate if people can try this develop branch out with the checklists. |
@jhchen there's also an open PR koffeinfrei/quill-task-list#1 where @CJEnright came up with a better solution for the click handling. |
From reading the code it looks like the list will check/uncheck when the user clicks anywhere on the list, not just the box? That's the main challenge is locate/detect a click on just the box. |
I think (and sorry if this is wrong) that because the matches function, e.target.matches('ul.task-list > li'), uses the immediate child selector (>) it only affects the the li element itself and none of its child elements, including the text. |
That does exclude child elements but not child text nodes: https://jsfiddle.net/c335pu4e/ |
Well, I wonder if there is any final solution. |
Thanks for the reminder @seekforwings, @jhchen's jsfiddle proves the concept doesn't work, but in practice it seems to function fine (besides the bugs issued on @koffeinfrei's repository). I've tried to look for the differences but wasn't able to find anything concrete as of yet. I've made a demo repository if anyone wants to test out the module in a full Quill environment. |
It's because of |
Thanks for the pointer @koffeinfrei ! I added a change adb980d that hooks up the click handlers and it seems to be working well. The only thing left I think is I cannot get the toolbar to light up both in the checked and unchecked case. |
Regarding getting the toolbar to light up, would the following be an acceptable hack: to check if the formats[format] contains the input.getAttribute('value') substring?
|
@ftwang I think the behavior would be too magical for my tastes. Thank you for the suggestion though. I'm leaning towards allowing a way to specify an array of values to match on ex: <button class="ql-header" value="1">Header 1</button>
<button class="ql-header" value="1">Header 1</button>
<button class="ql-list" value="checked,unchecked">Checklist</button> |
I couldn't find much documentation on this feature, but it seems like @jhchen Is this feature still in development? Would it be feasible to use it in production? Thank you! |
@patleeman The API works but as stated earlier I still need to get the toolbar to work before official documentation + support. |
@jhchen side question: Have you considered adding such functionality as plugins, similar to the one I built? This would lead to a cleaner separation. The current design will eventually lead to a very bloated core. |
There already is the concept of modules which may be internal or external. How is this different from plugins you are describing? |
The reason I asked was that you started implementing the checkbox functionallity in the core, while I had already written a plugin which could be used instead. The module concept may be appropriate (although I didn't have a close look at it) but my point was that you didn't use that concept, but added more code to the existing list. |
This was always envisioned to be added to core as checklists very useful and becoming commonplace in modern editing products (ex. Dropbox Paper, Quip) and the code for it is pretty minimal. I'm not sure I agree that your plugin could be used instead. It was and still is in a demonstration/proof of concept stage in terms of robustness and completeness in terms of interacting with other parts of Quill in a bug free way. I also had asked for a PR and no one submitted one nor expressed interest so I started working on it myself in the meantime. Quill has high code quality standards and this is not the easiest feature to implement (though there is not much code if one is familiar) so my expectation for a PR was not high. Your implementation, which I did thank you already for sharing, came in the middle my working on a core implementation and was not implemented in the optimal way or layer given my attempts up to that point. I apologize if I misread your intentions. Either way our Contribution Guide is a great resource for those that want to get more involved in the future. |
I didn't necessarily imply that my plugin should be used instead. I just merely stated that this could be implemented not in core directly, due to the above stated reasons and also because my attempt seemed easier. I was actually surprised how easily I was able to achieve this. Some things even seem to be easier the way I implemented it:
Curiously this just worked for me.
What parts do you think aren't robust or complete enough? I'm aware of
No need to apologize. I didn't have any intentions actually other than just providing my implementation as a possible inspiration for the final implementation. That you're going in a different direction with this is totally up to you and fine with me. It's your project anyway, and you'll know better what's right. |
whoah, checkboxes are already in core. I was browsing through the list Attributor code and noticed checkbox code all over. So I tried adding the list check item to my toolbar like so
And guess what the checkbox icon appears! And it even works with the history stack. @jhchen aside from the icon in the toolbar lighting up, is this feature production ready? Also, the checkbox CSS could look better. It is quite small and hard to see. With the new checklist option there are now 3 list options. Would it be better to design the list element as a drop-down in the toolbar similar to the alignment drop-down? |
@patleeman The css you provided for larger checkboxes appears to not work on mobile (tested with iOS 10.3.3). The checked icon shows, but the box disappeared. |
Oh, the unicode character might not render, i didn't check that. You can use any unicode symbol by using the last 4 chars of the hex representation where it says
|
I used this task-list in my project, I have a problem, if I press the enter key after an empty task list, this list should be deleted, instead of generating another list, is this a bug? |
I've just tried following @sferoze suggestion:
And put it on a codepen: https://codepen.io/anon/pen/JLdyQq and it looks really good! Great work @jhchen! Any ETA for official support? |
@patleeman, @sferoze, Regarding mobile have you had any issues ticking or un-ticking the boxes? While using Chrome on android, more often than not it seems to register 2 presses, instead of one. This results in the box returning to previous state instead of changing. I'm inclined to think some sort of |
It might be interpreting both touchstart and mousedown events and triggering twice. Instead of debounce, I wonder if there is a way to trigger only one of these events? |
Funny, this morning I was thinking about this and the same thought came to mind. I've tested Android Chrome with this jsfiddle (origin) and confirmed indeed both I see 2 options:
var waiting = false;
var touchmouseFunc = function(e) {
if (waiting) return;
waiting = true;
setTimeout(function() {
waiting = false;
}, 300);
document.getElementById('testArea').innerHTML += 'touchmouse ';
};
document.addEventListener("touchstart", touchmouseFunc, false);
document.addEventListener("mousedown", touchmouseFunc, false); |
@patleeman, the solution can be made simpler, we can prevent the
I've tested the below code in this jsfiddle. On my desktop browser I only get var touchFunc = function(e) {
e.preventDefault()
document.getElementById('testArea').innerHTML += 'touch ';
};
var mouseFunc = function() {
document.getElementById('testArea').innerHTML += 'mouse ';
};
document.addEventListener("touchstart", touchFunc, { passive: false });
document.addEventListener("mousedown", mouseFunc, false); |
Hello guys, thanks for your work. I need to catch the Is there a way for me to disable this formating? |
Hi, is there a way to check/uncheck the checkbox, when the Quill is not on editing mode? |
Hello, is there any progress about check toolbar light up? |
To those running into issues implementing checklists (toolbar icon's active status incorrectly rendering, inconsistent value parsing of 'check'/'checked'/'unchecked'), a custom toolbar module might be of use. |
What is current most recommended package for checkbox /task-list ? I currently use buildin
|
If you wanna use Font Awsome icons user buidIn: Customize CSS:
|
anyone ever figure out how to change the background color of the checkboxes? So it's not default blue. |
Is there any way to make users able to check/uncheck the checkboxes, but not edit any other things? (this is for when we want to display the content of the editor in a non-editor instance, but currently the only way it seems is to have a disabled quill editor, but that doesn't allow checking/unchecking the checklists.) |
@cccindyyyl I, too, need this feature. The way I've solved it is to use this package https://github.com/nozer/quill-delta-to-html to convert the delta to HTML. Then during representation, I iterate over the exported html to grab all the li elements with a I'm forced to be in jquery right now for this project, which is not ideal, but overall it still works fine. Here's a link to my proof of concept in codesandbox https://codepen.io/djones4822/pen/NWeEBab The implementation I use stores the delta in the preview in a data attribute, and fetches and updates it on each interaction. On preview toggle the delta is stored in the database. Some users only see the rendered html, and in that case we still serve the delta on their client and on update we store it in the db. Hope that helps |
@luin can we close this now that check box supported? |
Can you point me to the docs for this? |
Where can we find the docs about it or why do you say it's supported? |
This is a feature request to add support for a check box list type.
In addition to the unordered and ordered list types, a checkbox list type would also be very helpful. It would enable users to create very light-weight task lists within a Quill editor instance.
The experience I'm imagining is that this list type would largely function exactly list the unordered list type in Quill with just a few additions:
I understand this won't be in Quill 1.0, but wanted to get it on the list so others can express interest as well for future prioritization.
Also would be helpful to know if this could be added purely using the extensibility of blots? Could be a good third-party contribution.
The text was updated successfully, but these errors were encountered: