Skip to content

Instantly share code, notes, and snippets.

@dalezak
Last active March 5, 2023 20:44
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save dalezak/834198114f414a79de355e0c2cb664d3 to your computer and use it in GitHub Desktop.
Save dalezak/834198114f414a79de355e0c2cb664d3 to your computer and use it in GitHub Desktop.
Using Tables In Quill.js With Rails and Stimulus
<%= form.hidden_field field, data: { quill: { target: "input" } } %>
<div style="min-height:500px;" data-quill-target="editor" data-action="click->quill#focus"></div>
import ApplicationController from './application_controller';
import Quill from 'quill';
export default class extends ApplicationController {
static targets = ["editor", "input"]
connect() {
this.quill = new Quill(this.editorTarget, {
theme: 'snow',
modules: {
table: true,
toolbar: [
[{ header: [1, 2, 3, 4, 5, 6, false] }],
['bold', 'italic', 'underline'],
[{ 'list': 'ordered' }, { 'list': 'bullet' }],
[{ 'indent': '-1' }, { 'indent': '+1' }],
[{ 'align': [] }],
['blockquote', 'link', 'image'],
['table', 'column-left', 'column-right', 'row-above', 'row-below', 'row-remove', 'column-remove'],
['clean']
]
}
});
this.table = this.quill.getModule('table');
this.quill.container.firstChild.innerHTML = this.inputTarget.value;
this.quill.on('text-change', (delta, oldDelta, source) => {
this.inputTarget.value = this.quill.container.firstChild.innerHTML;
});
document.querySelectorAll('.ql-column-left').forEach(button => {
button.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-caret-left-square" viewBox="0 0 16 16"><path d="M14 1a1 1 0 0 1 1 1v12a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1h12zM2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2z"/><path d="M10.205 12.456A.5.5 0 0 0 10.5 12V4a.5.5 0 0 0-.832-.374l-4.5 4a.5.5 0 0 0 0 .748l4.5 4a.5.5 0 0 0 .537.082z"/></svg>'
button.title = "Add column left";
button.addEventListener('click', () => {
this.table.insertColumnLeft();
});
});
document.querySelectorAll('.ql-column-right').forEach(button => {
button.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-caret-right-square" viewBox="0 0 16 16"><path d="M14 1a1 1 0 0 1 1 1v12a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1h12zM2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2z"/><path d="M5.795 12.456A.5.5 0 0 1 5.5 12V4a.5.5 0 0 1 .832-.374l4.5 4a.5.5 0 0 1 0 .748l-4.5 4a.5.5 0 0 1-.537.082z"/></svg>';
button.title = "Add column right";
button.addEventListener('click', () => {
this.table.insertColumnRight();
});
});
document.querySelectorAll('.ql-row-above').forEach(button => {
button.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-caret-up-square" viewBox="0 0 16 16"><path d="M14 1a1 1 0 0 1 1 1v12a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1h12zM2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2z"/><path d="M3.544 10.705A.5.5 0 0 0 4 11h8a.5.5 0 0 0 .374-.832l-4-4.5a.5.5 0 0 0-.748 0l-4 4.5a.5.5 0 0 0-.082.537z"/></svg>';
button.title = "Add row above";
button.addEventListener('click', () => {
this.table.insertRowAbove();
});
});
document.querySelectorAll('.ql-row-below').forEach(button => {
button.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-caret-down-square" viewBox="0 0 16 16"><path d="M3.626 6.832A.5.5 0 0 1 4 6h8a.5.5 0 0 1 .374.832l-4 4.5a.5.5 0 0 1-.748 0l-4-4.5z"/><path d="M0 2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V2zm15 0a1 1 0 0 0-1-1H2a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V2z"/></svg>'
button.title = "Add row below";
button.addEventListener('click', () => {
this.table.insertRowBelow();
});
});
document.querySelectorAll('.ql-row-remove').forEach(button => {
button.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-dash-square" viewBox="0 0 16 16"><path d="M14 1a1 1 0 0 1 1 1v12a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1h12zM2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2z"/><path d="M4 8a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7A.5.5 0 0 1 4 8z"/></svg>';
button.title = "Remove row";
button.addEventListener('click', () => {
this.table.deleteRow();
});
});
document.querySelectorAll('.ql-column-remove').forEach(button => {
button.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-x-square" viewBox="0 0 16 16"><path d="M14 1a1 1 0 0 1 1 1v12a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1h12zM2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2z"/><path d="M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z"/></svg>';
button.title = "Remove column";
button.addEventListener('click', () => {
this.table.deleteRow();
});
});
}
disconnect() {
if (this.quill) {
this.quill = null;
}
if (this.table) {
this.table = null;
}
}
focus() {
this.quill.focus();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment