Skip to content

Commit

Permalink
Add image upload functionality to quill
Browse files Browse the repository at this point in the history
* Move toolbar into template to make it customizable
  • Loading branch information
MartinRiese committed Feb 4, 2025
1 parent 83ca7db commit d94063b
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 25 deletions.
76 changes: 53 additions & 23 deletions corehq/messaging/scheduling/static/scheduling/js/create_schedule.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,35 +38,65 @@ Quill.register({
});

ko.bindingHandlers.richEditor = {
init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
init: function (element, valueAccessor) {
const fontFamilyArr = ["Roboto Condensed", "Times New Roman", "Calibri", "Calibri Light", "Sans-Serif"];
let fonts = Quill.import("attributors/style/font");
fonts.whitelist = fontFamilyArr;
Quill.register(fonts, true);

const toolbarOptions = [
[{ 'header': [false, 1, 2, 3] }],
['bold', 'italic', 'underline', 'strike'], // toggled buttons
// ['blockquote', 'code-block'],
['link', 'image'],

[{ 'list': 'ordered'}, { 'list': 'bullet' }, { 'list': 'check' }],
// [{ 'script': 'sub'}, { 'script': 'super' }], // superscript/subscript
[{ 'indent': '-1'}, { 'indent': '+1' }], // outdent/indent
// [{ 'direction': 'rtl' }], // text direction

[{ 'color': [] }, { 'background': [] }], // dropdown with defaults from theme
[{ 'font': fontFamilyArr }],
[{ 'align': [] }],

['clean'], // remove formatting button
];

const toolbar = element.parentElement.querySelector("#ql-toolbar");
const editor = new Quill(element, {
modules: {
toolbar: toolbarOptions,
toolbar: toolbar,
},
theme: 'snow',
theme: "snow",
});

let currentSelectionRange = { index: 0, length: 0};
const insertImageButton = toolbar.querySelector("#insert-image");
insertImageButton.addEventListener("click", function (clickEvent) {
clickEvent.stopPropagation();
const input = document.createElement("input");
input.onchange = function (onChangeEvent) {
const file = onChangeEvent.target.files[0];
const uploadUrl = initialPageData.reverse("upload_messaging_image");
let formData = new FormData();

formData.append("upload", file, file.name);
fetch(uploadUrl, {
method: "POST",
body: formData,
headers: {
"X-CSRFTOKEN": $("#csrfTokenContainer").val(),
},
})
.then(function (response) {
return response.json();
})
.then(function (data) {
const Delta = Quill.import("delta");
editor.updateContents(
new Delta()
.retain(currentSelectionRange.index)
.delete(currentSelectionRange.length)
.insert({
image: data.url,
}, {
// link: data.url,
alt: file.name,
}),
);
});
};
input.accept = "image/png, image/jpeg";
input.type = "file";
input.click();
});

editor.on("selection-change", (range) => {
if (range) {
currentSelectionRange = range;
}
});

const value = ko.utils.unwrapObservable(valueAccessor());
Expand All @@ -75,7 +105,7 @@ ko.bindingHandlers.richEditor = {
let isSubscriberChange = false;
let isEditorChange = false;

editor.on('text-change', function(delta, source) {
editor.on("text-change", function () {
if (!isSubscriberChange) {
isEditorChange = true;
valueAccessor()(editor.root.innerHTML);
Expand All @@ -91,7 +121,7 @@ ko.bindingHandlers.richEditor = {
}
});

if (initialPageData.get('read_only_mode')) {
if (initialPageData.get("read_only_mode")) {
editor.enable(false);
}
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<div id="ql-toolbar">
<select class="ql-header">
<option value="normal">paragraph</option>
<option value="1"></option>
<option value="2"></option>
<option value="3"></option>
</select>
<select class="ql-font">
<option value="Arial" style="font-family: 'Arial'">Arial</option>
<option value="Times New Roman" style="font-family: 'Times New Roman'">Times New Roman</option>
</select>
<select class="ql-size">
<option value="small">Small</option>
<option selected>Default</option>
<option value="large">Big</option>
<option value="huge">Huge</option>
</select>
<button class="ql-bold"></button>
<button class="ql-italic"></button>
<button class="ql-underline"></button>
<button class="ql-strike"></button>
<select class="ql-color"></select>
<select class="ql-background"></select>
<button class="ql-link"></button>
<button id="insert-image" class="ql-image"></button>
<button class="ql-list" value="ordered"></button>
<button class="ql-list" value="bullet"></button>
<button class="ql-list" value="check"></button>
<button class="ql-indent" value="-1"></button>
<button class="ql-indent" value="+1"></button>
<button class="ql-align"></button>
<button class="ql-clean"></button>
</div>
<div data-bind="richEditor: {{ editableText }}"></div>
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
</div>

<div class="controls translation-controls" data-bind="visible: !translate()">
<div data-bind="richEditor: nonTranslatedMessage"></div>
{% include "scheduling/partials/rich_text_editor.html" with editableText="nonTranslatedMessage" %}
</div>

<div data-bind="visible: translate(), foreach: translatedMessages">
Expand All @@ -23,6 +23,6 @@
>{% trans "Translation" %} (<span data-bind="text: language_code"></span
>):</label
>
<div data-bind="richEditor: html_message"></div>
{% include "scheduling/partials/rich_text_editor.html" with editableText="html_message" %}
</div>
</div>

0 comments on commit d94063b

Please sign in to comment.