Skip to content

CodeCoupler DOM Basics Editor πŸ”’

What is this?

It's always the same game. First, we need input from the user, then we show them an input option. This input is then checked, validated and converted into the final required data type. Countless errors can occur at this stage.

The goal of this library is to minimize the effort involved in creating input options.

We assume that a variable has been defined for the editor to use. The editor component is intended to allow the user to change the value of a variable. The editor and the variable are linked to each other. The editor should automatically apply changes to the variable and update its value when the user makes changes.

The most important aspect of the editor component is the variable type. The editor always expects a specific type and only ever replaces the value of a variable with one of the same type.

Setup

Install Bundle, Base Extensions, Dependencies:

npm i vue luxon dompurify @codecoupler-pro/ui-bundle @codecoupler-pro/dom-editor-extensions-base

Define Aliases, Externals and Assets:

{
  module: "vue",
  global: "Vue",
  entries: ["dist/vue.runtime.global.prod.js"]
},
{
  module: "luxon",
  global: "luxon",
  entries: ["build/global/luxon.min.js"]
},
{
  module: "dompurify",
  global: "DOMPurify",
  entries: ["dist/purify.min.js"]
},
{
  module: "@codecoupler-pro/dom-editor",
  global: ["codecoupler", "dom", "editor"]
},
{
  module: "@codecoupler-pro/ui-bundle",
  global: ["codecoupler", "ui", "bundle"],
  entries: [
    "dist/codecoupler-pro-ui-bundle.js",
    "dist/codecoupler-pro-ui-bundle.css"
  ]
},
{
  module: "@codecoupler-pro/dom-editor-extensions-base",
  entries: ["dist/codecoupler-pro-dom-editor-extensions-base.js"],
  copy: ["dist/parts"]
}

Basic Usage

Set global variable (read the chapter Loading the Extensions for more details):

1
2
3
4
window.codecoupler.ui.editorExtensions.base.$publicPath =
  window.externalsPath[process.env.PACKAGE_NAME][
    "@codecoupler-pro/dom-editor-extensions-base"
  ] + "/dist/";

Use in JavaScript:

import { EditorJs as Editor } from "@codecoupler-pro/dom-editor";
let editor = new Editor(props);

Use as Vue Component:

<template>
  <editor v-model="value"></editor>
</template>
<script>
import { EditorVue as Editor } from "@codecoupler-pro/dom-editor";
export default {
  components: { Editor },
  data: function () {
    return {
      value: "My String"
    };
  },
};
</script>

Get Started

The easiest way to initialize the editor is to specify only one variable. The editor determines the data type based on the value of the variable. Everything else happens automatically. We will first show you the basic use of the editor using this simple configuration.

The editor can be used both as a Vue component and with JavaScript.

Info

As the following example will show, there are many things to consider when using pure JavaScript. Therefore, when using the editor with JavaScript, it is much easier if we additionally use reactive objects.

Using reactive objects offers the advantage that all changes are automatically synchronized between the editor and the variable, and the code becomes much simpler.

There are two ways to use reactive objects. Either you convert the linked variable into a reactive "ref object", or you pass a "reactive proxy" to the editor during initialization.

We recommend using the second method (reactive proxy) whenever possible. This allows for decoupling between the properties and the editor instance.

For this example, we will assume that we have a DOM element for the editor to use. You can use any element or tag name because it will be replaced in this example. In our JavaScript example, we will use an element with the tag name <editor> as an example.

Your HTML
<editor></editor>

This is how to convert this element into an editor using pure JavaScript:

Your JavaScript
import html from "./basic-demo.html";
import { EditorJs as Editor } from "@codecoupler-pro/dom-editor";

// Prepare Library
window.codecoupler.ui.editorExtensions.base.$publicPath =
  window.externalsPath[process.env.PACKAGE_NAME][
    "@codecoupler-pro/dom-editor-extensions-base"
  ] + "/dist/";

// Insert our HTML into <body> and save the DOM element that we convert into an
// editor into "editorContainer"
let container = document.body;
container.insertAdjacentHTML("beforeend", html);
let editorContainer = container.querySelector("editor");

// This is our Variable which should be updated:
let ourVariable = "My String";

// Instantiate the editor (by replacing our <editor> element)
let editor = new Editor({
  modelValue: ourVariable,
  // This callback will be executed whenever the editor changes the value. Then,
  // we must update the variable.
  "onUpdate:modelValue": (newValue) => {
    ourVariable = newValue;
  }
}).replace(editorContainer);

// If you would like to keep the element and mount the editor inside it, use the
// ".mount(editorContainer)" method instead.

// To change the value of our variable, we must follow two steps:
function changeValue() {
  // First, we change the value of the variable as usual:
  ourVariable = Math.random().toString(36).substring(2, 8);
  // Then we inform the editor instance about this change:
  editor.$props.modelValue = ourVariable;
}

// To change other properties of the editor, you need access to the instance and
// its $props property.
function changeProps() {
  editor.$props.styleControl = {
    borderColor: `#${Math.round(Math.random() * 16777215).toString(16)}`
  };
}

We assume that there is a DOM element for the editor to use. You can use any element or tag name because the element will be replaced in this example anyway. In our JavaScript example, we will use an element with the tag name <editor>.

Your HTML
<editor></editor>

Convert this element into an editor using JavaScript and a ref object:

Your JavaScript
import html from "./basic-demo.html";
import { EditorJs as Editor } from "@codecoupler-pro/dom-editor";
import { ref } from "vue";

// Prepare Library
window.codecoupler.ui.editorExtensions.base.$publicPath =
  window.externalsPath[process.env.PACKAGE_NAME][
    "@codecoupler-pro/dom-editor-extensions-base"
  ] + "/dist/";

// Insert our HTML into <body> and save the DOM element that we convert into an
// editor into "editorContainer"
let container = document.body;
container.insertAdjacentHTML("beforeend", html);
let editorContainer = container.querySelector("editor");

// This is our Variable which should be updated:
let ourVariable = ref("My String");

// Instantiate the editor (by replacing our <editor> element):
let editor = new Editor({
  modelValue: ourVariable
}).replace(editorContainer);

// If you would like to keep the element and mount the editor inside it, use the
// ".mount(editorContainer)" method instead.

// If we want to change the value of our variable, we just need to make sure to
// change the β€œvalue” property of our variable instead of the variable itself.
function changeValue() {
  ourVariable.value = Math.random().toString(36).substring(2, 8);
}

// To change other properties of the editor, you need access to the instance and
// its $props property.
function changeProps() {
  editor.$props.styleControl = {
    borderColor: `#${Math.round(Math.random() * 16777215).toString(16)}`
  };
}

We assume that there is a DOM element for the editor to use. You can use any element or tag name because the element will be replaced in this example anyway. In our JavaScript example, we will use an element with the tag name <editor>.

Your HTML
<editor></editor>

Convert this element into an editor using JavaScript and a reactive proxy:

Your JavaScript
import html from "./basic-demo.html";
import { EditorJs as Editor } from "@codecoupler-pro/dom-editor";
import { reactive } from "vue";

// Prepare Library
window.codecoupler.ui.editorExtensions.base.$publicPath =
  window.externalsPath[process.env.PACKAGE_NAME][
    "@codecoupler-pro/dom-editor-extensions-base"
  ] + "/dist/";

// Insert our HTML into <body> and save the DOM element that we convert into an
// editor into "editorContainer"
let container = document.body;
container.insertAdjacentHTML("beforeend", html);
let editorContainer = container.querySelector("editor");

// These are the properties for the editor, including the variable, which should
// be updated. We have enclosed the properties in a reactive proxy.
let ourProps = reactive({
  modelValue: "My String"
});

// Instantiate the editor (by replacing our <editor> element):
let editor = new Editor(ourProps).replace(editorContainer);

// If you would like to keep the element and mount the editor inside it, use the
// ".mount(editorContainer)" method instead.

// If we want to change the value of our variable, we just need to change the
// value in our reactive proxy. We no longer need a reference to our editor
// instance.
function changeValue() {
  ourProps.modelValue = Math.random().toString(36).substring(2, 8);
}

// The biggest advantage of this method is that you can use the same object to
// manipulate all other properties of the editor. Here, too, no reference to the
// editor instance is required.
function changeProps() {
  ourProps.styleControl = {
    borderColor: `#${Math.round(Math.random() * 16777215).toString(16)}`
  };
}

In Vue, you can only really start with the v-model attribute to bind the variable that you want to provide to the editor.

Starting with the bootstrap code:

You initial JavaScript
import { createApp } from "vue";
import Component from "./basic-demo-vue.vue";

// Prepare Library
window.codecoupler.ui.editorExtensions.base.$publicPath =
  window.externalsPath[process.env.PACKAGE_NAME][
    "@codecoupler-pro/dom-editor-extensions-base"
  ] + "/dist/";

// Mount Vue Component
createApp(Component).mount("body");

Below is a complete example of a Vue Single-File Component:

Your Vue Component
<template>
  <editor v-model="ourVariable"></editor>
</template>
<script>
import { EditorVue as Editor } from "@codecoupler/cc-ui-pro";
export default {
  components: { Editor },
  data: function () {
    // Define the variable which should be edited as reactive element.
    // Every change in the editor will automatically update the value:
    return {
      ourVariable: "Testing Vue"
    };
  },
  methods: {
    // An example on how to change the value. Changing the value
    // will automatically update the editor component:
    changeValue: function () {
      this.ourVariable = Math.random().toString(36).substring(2, 8);
    }
  }
};
</script>

Loading the Extensions

Before the library can be used, a global variable must be set. This variable is responsible for ensuring that the editor can find its extensions. These are loaded dynamically. If this variable is not set, the extensions will be searched for at the root level of the web server.

The variable that must be set is different for each extension pack. To start with, we use here the basic extension pack @codecoupler-pro/dom-editor-extensions-base. For this extension pack, the variable window.codecoupler.ui.editorExtensions.base.$publicPath must be set. This must refer to the path in which the bundle is available on the web server.

If the CodeCoupler Webpack library is used, it can be set as follows:

1
2
3
4
window.codecoupler.ui.editorExtensions.base.$publicPath =
  window.externalsPath[process.env.PACKAGE_NAME][
    "@codecoupler-pro/dom-editor-extensions-base"
  ] + "/dist/";

Now we will show you an alternative method in which the extensions are loaded in advance. However, this method is not as elegant as allowing the library to load only the resources that are actually needed.

To do this, you must change the definitions of externals and assets. Specify exactly which extensions to preload:

[
  {
    module: "@codecoupler-pro/dom-editor-extensions-base",
    entries: [
      "dist/loader.js",
      "dist/extensions/bsselect.js",
      "dist/extensions/checkbox.js",
      "dist/extensions/imask.js",
      "dist/extensions/input.js",
      "dist/extensions/plaintext.js",
      "dist/extensions/select.js",
      "dist/extensions/sensitive.js"
    ]
  }
];

If you are not using any other extensions as specified here, you do not need to set the global variable.

Reference

Constructor Options

The constructor expects an object with the editor properties. These properties are described in more detail in the following chapters.

The object can be a reactive proxy. Any changes made to this reactive proxy's properties will be passed on to the editor's properties.

Instance Members

$props: Object

Read and modify the values of the editor properties.

mount(Element)

Mount the editor within an HTML element.

replace(Element)

Mount the editor into an HTML element and replace it.