gd-sprest-bs
Version:
SharePoint JavaScript, TypeScript and Web Components designed using the Bootstrap framework.
169 lines (143 loc) • 5.53 kB
text/typescript
import { Components } from "gd-bs";
import Quill from "quill";
import * as Toolbars from "./toolbar";
import { IRichTextBox, IRichTextBoxProps, IFormControlPropsRichTextBox } from "./types";
/**
* Toolbar Types
*/
export enum RichTextBoxTypes {
None = 0,
Basic = 1,
Full = 2
}
/**
* Rich TextBox
*/
export const RichTextBox = (props: IRichTextBoxProps): IRichTextBox => {
// Create the editor element
let elRichTextBox = document.createElement("div");
elRichTextBox.classList.add("rich-textbox");
// Create the toolbar element
let elToolbar = document.createElement("div");
elToolbar.classList.add("toolbar-container");
props.disabled ? null : elToolbar.classList.add("form-control");
elRichTextBox.appendChild(elToolbar);
// Create the editor element
let elEditor = document.createElement("div");
elEditor.classList.add("editor-container");
props.disabled ? elEditor.classList.add("rounded") : elEditor.classList.add("form-control");
elRichTextBox.appendChild(elEditor);
// Get the options and default the values
let options = props.options || {};
options.modules = options.modules || {};
options.placeholder ? options.placeholder = props.placeholder : null;
options.readOnly == null && typeof (props.disabled) === "boolean" ? options.readOnly = props.disabled : null;
options.theme = options.theme == null ? "snow" : options.theme;
// See if are setting the default toolbar options
let showToolbar = true;
if (options.modules.toolbar == null) {
// Set the toolbar options
switch (props.toolbarType) {
// None
case RichTextBoxTypes.None:
elToolbar.innerHTML = "";
showToolbar = false;
break;
// Basic
case RichTextBoxTypes.Basic:
elToolbar.innerHTML = Toolbars.BasicToolbar;
break;
// Default - Full
default:
elToolbar.innerHTML = Toolbars.FullToolbar;
break;
}
// Set the toolbar
options.modules.toolbar = elToolbar;
} else {
// Set the toolbar container
options.modules.toolbar.container = elToolbar;
}
// Create the element
let el = document.createElement("div");
el.appendChild(elRichTextBox);
// See if we are rendering it to an element
if (props.el) {
// Ensure the parent element exists
if (props.el.parentElement && props.el.parentElement.classList) {
// Set the bootstrap class
props.el.parentElement.classList.contains("bs") ? null : props.el.parentElement.classList.add("bs");
}
// Append the elements
while (el.children.length > 0) {
props.el.appendChild(el.children[0]);
}
// Update the element
el = props.el as any;
} else {
// Set the bootstrap class
el.classList.add("bs");
}
// Apply the plugin
let quillObj = new Quill(elEditor, options as any);
// See if we are hiding the toolbar
if (!showToolbar) {
// Remove the snow class
elToolbar.classList.remove("ql-snow");
}
// Create the object
let obj = {
el: elRichTextBox,
elContents: quillObj.root,
quillObj,
getHtml: () => { return obj.getText() ? quillObj.root.innerHTML : ""; },
getText: () => { return quillObj.getText().trim(); },
setHtml: (value: string) => {
// Convert the html to allow the library to run any conversions to display it correctly
quillObj.setContents(quillObj.clipboard.convert({ html: value || "" }));
}
};
// Set the value
props.value ? obj.setHtml(props.value) : null;
// Execute the assign to event
props.assignTo ? props.assignTo(obj) : null;
// Return the object
return obj;
}
// Customize the form control
export const RichTextBoxControlType = 102;
Components.FormControlTypes["RichTextBox"] = RichTextBoxControlType;
Components.CustomControls.registerType(RichTextBoxControlType, (props: IFormControlPropsRichTextBox) => {
let rtb: IRichTextBox = null;
// Set the created method
let onRendered = props.onControlRendered;
props.onControlRendered = ctrl => {
// Render a date/time
rtb = RichTextBox({
className: props.className,
disabled: props.isDisabled || props.isReadonly,
el: ctrl.el,
options: props.options,
rows: props.rows,
toolbarType: props.toolbarType,
placeholder: props.placeholder,
value: props.value
});
// See if the label exists
let elLabel: HTMLElement = ctrl["_elLabel"];
if (elLabel) {
// Set the id and aria properties
elLabel ? elLabel.id = (props.id || props.name) + "_label" : null;
//rtb.el.querySelector("input").setAttribute("aria-labelledby", elLabel.id);
}
// Set the control
ctrl.setControl(rtb);
// Call the custom render event
onRendered ? onRendered(ctrl) : null;
}
// Register a people picker
props.onGetValue = (ctrl) => {
// Return the value
return rtb ? rtb.getHtml() : ctrl.value;
};
});