-
Notifications
You must be signed in to change notification settings - Fork 3.3k
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
Consider allowing multiple editors on the same page & to use the same toolbar. #633
Comments
What is the use case for this? And why is that use case not solved with just hiding the respective toolbar and require there be one and only one toolbar? |
This is something that I am looking for also. I am trying to incorporate Quill into a webpage builder. I'm hoping to have Quill handle the content and have another way to control the background images of the sections. Ideally the toolbar would be attached to the top and not connected to the editable areas. Maybe there's another way to do this? |
@m1kelynn Did you managed to solve the issue with multiple editors with single toolbar in your case? Eager to know if something you could share. |
Hello, this.quill.on("editor-change", (eventName, ...args) =>
{
if(this.quill.getSelection())
{
this.currentFormats = this.quill.getFormat();
}
}); The toolbar buttons will call a format function. format(format, params)
{
if(this.currentFormats[format] && (!params || this.currentFormats[format] == params))
{
this.quill.format(format, false, Quill.sources.USER);
}
else
{
this.quill.format(format, params, Quill.sources.USER)
}
} Then I bind the style of the toolbar button to the currentFormats variable. |
@mrgrimmig, I have a hard time following what you did to solve this problem. I need to do something similar, and would really appreciate some clarification or a workinf code example, if possible. Thanks! -JM |
Sorry for my weird response. <!DOCTYPE html>
<html>
<head>
<script src="https://cdn.quilljs.com/1.2.6/quill.js"></script>
<link href="https://cdn.quilljs.com/1.2.6/quill.snow.css" rel="stylesheet">
<style>
.active {
background: green;
}
</style>
</head>
<body>
<button id="bold" onclick="onBoldClick()">Bold</button>
<div id="editor1">
<p>Hello World!</p>
<p>Some initial <strong>bold</strong> text</p>
<p><br></p>
</div>
<div id="editor2">
<p>Hello World!</p>
<p>Some initial <strong>bold</strong> text</p>
<p><br></p>
</div>
<script>
var currentEditor; // selected / focused editor
var currentFormats; // save the current formattings
createEditor("#editor1");
createEditor("#editor2");
function createEditor(selector)
{
let quill = new Quill(selector, { });
quill.on("editor-change", (eventName, ...args) =>
{
currentEditor = quill;
updateButtons();
});
}
// get current formattings to style the toolbar buttons
function updateButtons()
{
if(currentEditor.getSelection())
{
currentFormats = currentEditor.getFormat();
if(currentFormats.bold)
{
bold.classList.add("active");
}
else
{
bold.classList.remove("active");
}
}
}
// if selected text is bold => unbold it - if it isn't => bold it
function onBoldClick()
{
if(!currentFormats || !currentEditor)
{
return;
}
if(currentFormats.bold)
{
currentEditor.format("bold", false);
}
else
{
currentEditor.format("bold", true);
}
}
</script>
</body>
</html> |
I'd love to talk about my use-case here as well... I'm using Quill as the text-editing component of a word-processor, which may have multiple documents onscreen at the same time. But all the instances should share the same toolbar. For example, here's a screenshot containing three Quill instances, one for the main document, and two containing margin comments: Whenever the user clicks from one editor to another, the toolbar should update itself to reflect the active/enabled/disabled status of each button. And any toolbar clicks should be directed to the currently-focused editor instance. Although some of the toolbar buttons correspond with Quill formatting functions, there are other toolbar buttons for non-Quill functionality, and those should continue to be enabled even when there are no active Quill editors onscreen at all. Right now, I'm implementing my own toolbar, completely separate from Quill, and managing the active/enabled/disabled state of all the toolbar buttons myself. But it's pretty ugly, and I'd love to help Quill address this use case a little better. Thank you for an incredible open-source project! I appreciate all your hard work. |
Sounds like there is sufficient demand for this feature. Can someone propose an API that would fit solve their needs? Short code snippets using the API and high level descriptions of what they do and don't do would be helpful. |
Perhaps some inspiration could be taken from the TextAngular editor, which has this feature. https://github.com/textAngular/textAngular See specifically "a toolbar can be linked to multiple editors" in the accompanying wiki: https://github.com/textAngular/textAngular/wiki/Customising-The-Toolbar -JM |
I don't think we need to change the API very much. The only things I really need are:
Here's a quick example of creating the root Quill object, registering event handlers, attaching a few editors, selecting them for focus, and detaching from them again.
The current Quill constructor, which accepts an editor ID...
...could continue to be supported, as a shorthand for the more verbose version:
It might also be nice to declare which toolbar buttons are enabled and disabled for each editor instance, possibly with something like this:
However, I'd also be happy to add the enable/disable logic to my own event-handler code for the |
To be clear you are proposing that
|
Yep, that's what I'm suggesting! Maybe most users will typically include an editor selector in the constructor In my application, the toolbar is always present from startup onward, even before the user creates their first document. As soon as they create a new document, or navigate into their existing content, I create new Quill editors and manually update the toolbar based on the selection and formatting state within that editor. In my ideal scenario, calling |
Hmm the thing is Quill is the editor with optional modules, one of which is the toolbar. So |
I totally understand, and I'm 100% open to other designs. The one I suggested just seems the most natural to me, as a user. But I'd love to see other proposals too! |
Would it be possible to make multiple editors work if created with the same toolbar? `var quill1 = new Quill('#editor1', { var quill2 = new Quill('#editor2', { |
If you click a button in the toolbar what editor would it modify? Both? |
If you click a button in the toolbar only the editor which lastly had focus should be modified. |
Has there been any progress on this feature? I would really like to switch to Quill from what I'm using today (TextAngular). Anything I can do to help out moving this forward? -JM |
We would love to see this feature as well. For now I have made an Angular wrapper library (ngx-quill-wrapper) that allows this, but the way it handles it is bit hacky and definitely not optimal. |
I'm usinbn AngularJS, so unfortunately I can't use your wrapper. But I think the idea of separating the toolbar from the editor (at least as an option) is well thought out. Hopefully, we'll see this as part of Quill itself in a not-too-distant future, since this is really something that ought to be done independently of any specific framework wrapper. |
I don't believe anyone is working on it and I probably will not get to it as there are other higher priority items at the moment. If someone with this use case wants to take it on please do. I am happy to give feedback on specific proposals but do not have the bandwidth to give general guidance for those new to Quill. |
Hello guys, hope this message everyone fine. Good topic/issue to cover here. I've implement and managed to add some buttons in toolbar by manual way which are functional as it should be, but I'm still facing some issues like Color, Font Size & Font Family etc. Demo link: Codepen Now what i need is to make Color, Font Size & Font Family button functional. Please review and suggest me. Thanks |
Would love to see this feature as well. At the moment I have to create a toolbar for every Quill editor as trying to use a single toolbar leaves the previous editor toolbar event handlers attached. After hours of trying to "hack it out", I finally created an editor + toolbar for every area I wanted to allow editing. I was also wondering if I can use the addContainer API method, but the docs are not specific enough for me to quickly understand what it does. Overall, Quill is amazing btw :) |
I see this topic has not moved, too bad. Any example on how to use the addContainer API method? |
Ok, so I encountered the same issue with this solution: |
@Onouriis It's difficult to help without a code snipped. Do you clear your HTML and reset it? // clean DOM and set content |
@PawelGlow I founded a nasty solution. |
@Onouriis Yes, that's correct. You need to destroy the toolbar HTML to remove the event listeners. I was also not able to find a better solution in the Quill docs but I have a very large app which handles 50+ toolbars and destroying the toolbar then creating a new one each time I create a new Quill instance has not caused any issues. |
@PawelGlow Thanks for your help and your advices. |
Hi, I'm using ngx-quill, an Angular 2+ wrapper for Quill and I'm facing an issue trying to "refresh" the content of the toolbar dynamically. Here is a link of the issue with a couple of exemples : KillerCodeMonkey/ngx-quill#662 To give you a bit more of a context, I've many different editable zones on my interface and to avoid to create a lot of Quill instances I've many "display only" zones and when I click on one of them I display a Quill editor at the same place as the display zone. But, the thing is that those zones can have different configuration options, which mean a different toolbar content. I would like to know if there is a way to trigger the "re-templating" of the toolbar content. |
This is also my exact use case. Is there any hope on getting this feature any time soon? I'm also leveraging Quill through ngx-quill btw. |
Hi @bbottema, |
@benjismith @jhchen |
i found @Yexan give a hack way to archive. https://stackblitz.com/edit/ng-quill-editor?file=src/app/app.component.ts |
@minzojian Yes if you have the same config between your zones it's doable. |
@PawelGlow thanks for your suggestion... I came to the same conclusion after going through the same process as you. Worked a treat and much more efficient than running multiple Quill editors at the same time. |
I have three editors in My Webpage Here my Js File `!function(o){"use strict"; var e=Quill.import("formats/font"); e.whitelist=["sofia","slabo","roboto","inconsolata","ubuntu"], Quill.register(e,!0); new Quill("#bubble-container .editor",{bounds:"#bubble-container .editor",modules:{formula:!0,syntax:!0},theme:"bubble"}), new Quill("#snow-container .editor",{bounds:"#snow-container .editor",modules:{formula:!0,syntax:!0,toolbar:"#snow-container .quill-toolbar"},theme:"snow"}), new Quill("#full-container .editor",{bounds:"#full-container .editor",modules:{formula:!0,syntax:!0,toolbar:[[{font:[]},{size:[]}],["bold","italic","underline","strike"],[{color:[]},{background:[]}],[{script:"super"},{script:"sub"}],[{header:"1"},{header:"2"},"blockquote","code-block"],[{list:"ordered"},{list:"bullet"},{indent:"-1"},{indent:"+1"}],["direction",{align:[]}],["link","image","video","formula"],["clean"]]},theme:"snow"});o("select[class^='ql-'], input[data-link]").addClass("browser-default")}((window,document,jQuery));` |
What is the problem you are trying to solve? @itz-vivekpawar |
Hey guys! I've created a sample React app to show how I resolved this issue. This is basically how it works:
You can test it here: https://codesandbox.io/s/hungry-pine-o8oh9?file=/src/App.js Feel free to use the code however you'd like. |
I am not familiar with React and would like to achieve the same functionality with vanilla js, albeit without the need to double click. Any suggestions on how to do the same thing without React? |
I'm quite busy these days and will not be help you, sorry. My suggestion is that you take a look at the code, the basics of what I'm doing should be quite understandable if you're familiar with javascript. |
I went with the second option that Pawel proposed but did some slight adjustments. Every quill instance will create its own toolbar instance that will be added to a global var toolbarOptions = [
['bold', 'italic', 'underline', 'strike'], // toggled buttons
['blockquote', 'code-block'],
[{ 'header': 1 }, { 'header': 2 }], // custom button values
[{ 'list': 'ordered'}, { 'list': 'bullet' }],
[{ 'script': 'sub'}, { 'script': 'super' }], // superscript/subscript
[{ 'indent': '-1'}, { 'indent': '+1' }], // outdent/indent
[{ 'direction': 'rtl' }], // text direction
[{ 'size': ['small', false, 'large', 'huge'] }], // custom dropdown
[{ 'header': [1, 2, 3, 4, 5, 6, false] }],
[{ 'color': [] }, { 'background': [] }], // dropdown with defaults from theme
[{ 'font': [] }],
[{ 'align': [] }],
['clean'] // remove formatting button
];
var quillOptions = {
modules: {
toolbar: toolbarOptions
},
theme: 'snow'
}
initQuill(document.querySelector('#editor'), document.querySelector('#toolbar'))
initQuill(document.querySelector('#editor2'),document.querySelector('#toolbar'))
initQuill(document.querySelector('#editor3'),document.querySelector('#toolbar'))
initQuill(document.querySelector('#editor4'),document.querySelector('#toolbar'))
initQuill(document.querySelector('#editor5'),document.querySelector('#toolbar'))
initQuill(document.querySelector('#editor6'),document.querySelector('#toolbar'))
function initQuill(element, globalToolbarContainer) {
var quill = new Quill(element, quillOptions);
quill.on('selection-change', (selection) => selectionChange(selection,quill));
var toolbar = quill.getModule('toolbar');
globalToolbarContainer.appendChild(toolbar.container)
// search for existing toolbar and hide it
prevToolbar = toolbar.container.previousElementSibling
if (prevToolbar) {
hideToolbar(prevToolbar)
}
}
function selectionChange(selection,quill) {
console.log("selection change",selection,quill)
const toolbar = quill.getModule('toolbar')
if(selection == null) {
hideToolbar(toolbar.container)
console.log('quill 1 lost focus')
} else {
showToolbar(toolbar.container)
}
}
function hideToolbar(toolbarContainer) {
toolbarContainer.classList.add('hidden')
}
function showToolbar(toolbarContainer) {
// hide all other toolbars
const siblings = getSiblings(toolbarContainer).map((elem) => elem.classList.add('hidden'))
toolbarContainer.classList.remove('hidden')
}
function getSiblings(elem) {
// Setup siblings array and get the first sibling
var siblings = [];
var sibling = elem.parentNode.firstChild;
// Loop through each sibling and push to the array
while (sibling) {
if (sibling.nodeType === 1 && sibling !== elem) {
siblings.push(sibling);
}
sibling = sibling.nextSibling
}
return siblings;
}; I created a codepen that demonstrates this solution. It seems to work quite well. For my use case I will never have more than 5-7 quill instances at the same time so it shouldn't affect the performance that much. |
@Yexan @minzojian This solution dont respect the history (ctrl-z) I did this :
And then call it with the quill.getModule('toolbar').resetToolbar when focusin an editor. It needs further ajustements but it seems not a bad way |
@JGrimbert could you provide a full example (like codesandbox or something) of this? |
I found a another solution. But don't know whether it will be a efficient one. So basically I am wrapping all the quill editors. Then I applied CSS property
|
Woah, this is open for a long time now. Can somebody pin the official solution to this? |
Don't think such a solution exists. |
It's a nice solution, but you're using two toolbars instead of one for both editable areas. But if they're in the same container, it would still appear as one. Though it would be a hassle doing it this way with an unknown amount of editable areas that are all placed at diffent places. |
I have achieve the functionality with angular.
|
i have created a quill module about this issue, maybe it helps; https://github.com/TonyYu2015/quill-free-container |
` <script src="https://cdn.quilljs.com/1.3.6/quill.js"></script> <title>Document</title>
Sans Serif
Serif
Monospace
|
it's working fine for my code example is here https://codesandbox.io/embed/blazing-river-8s9vsl?fontsize=14&hidenavigation=1&theme=dark |
When having more than one editor on a page, each one currently seems to require their own toolbar. If I try to assign a previously assigned toolbar then the events don't work for the second editor.
Steps for Reproduction
Expected behavior: Would be easy enough to simply keep track of which editor was last active and apply and changes to that editor eg. Changing font size etc.
Actual behavior: The tool bar seems broken as soon as the second editor is attached to it. Only the second editor is actually usable, because when trying to type in the first one, the cursor jumps to the second one.
The text was updated successfully, but these errors were encountered: