Skip to content

Widget: Scroller

What are we learning here?

  • Each widget automatically takes care of scrolling the content

Let's explore another feature of a widget by adding some more content. We add some buttons and attach some handlers to them:

src/demo/apps/component-basics/content.ejs.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<div>
  <h2><%= locals.myHeader %></h2>
  <div class="mt-2 card">
    <div class="card-header">Loading Components</div>
    <div class="card-body"><div data-role="stage"></div></div>
  </div>
  <div class="mt-2 card">
    <div class="card-header">Pass Options</div>
    <div class="card-body">
      Option 1: <span data-role="option1"></span><br />
      Option 2: <span data-role="option2"></span>
    </div>
  </div>
  <div class="mt-2 card">
    <div class="card-header">
      Adding Content
      <button class="btn btn-xs btn-success" data-role="text-plus">
        <i class="fas fa-plus"></i>
      </button>
      <button class="btn btn-xs btn-danger" data-role="text-minus">
        <i class="fas fa-minus"></i>
      </button>
    </div>
    <div data-role="content" class="card-body"></div>
  </div>
  <div class="arrow left"><i class="fas fa-chevron-circle-left"></i></div>
  <div class="arrow right"><i class="fas fa-chevron-circle-right"></i></div>
  <div class="arrow up"><i class="fas fa-chevron-circle-up"></i></div>
  <div class="arrow down"><i class="fas fa-chevron-circle-down"></i></div>
</div>

src/demo/apps/component-basics/content.js

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
  import { Widget } from "@codecoupler/cc-ui";
  import template from "./content.ejs.html";
  import style from "./content.module.css";
  import LoadingComponents from "../../components/loading-components";
  import { watchEffect } from "vue";
  export default class extends Widget {
    myHeader = "Component Basics";
    static defaults = {
      $map: "@codecoupler.walkthrough",
      "@codecoupler": {
        walkthrough: {
          myOption1: "Default 1",
          myOption2: "Default 2"
        }
      }
    };
    async start() {
      let tpl = template({
        myHeader: this.myHeader
      });
      this.element.replaceWith(tpl);
      this.element.classList.add(style.widget);
      let stage = this.registerStage(
        this.element.querySelector("[data-role=stage]")
      );
      await stage.load(LoadingComponents);
      watchEffect(() => {
        this.element.querySelector("[data-role=option1").innerHTML =
          this.#options.myOption1;
        this.element.querySelector("[data-role=option2").innerHTML =
          this.#options.myOption2;
      });
      let contentEl = this.element.querySelector("[data-role=content]");
      let addText = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr";
      this.element
        .querySelector("[data-role=text-plus]")
        .addEventListener("click", () => {
          contentEl.insertAdjacentHTML("beforeend", `<p>${addText}</p>`);
        });
      this.element
        .querySelector("[data-role=text-minus]")
        .addEventListener("click", () => {
          Array.from(contentEl.getElementsByTagName("p")).at(-1)?.remove();
        });
    }
  }

Now click on the plus button multiple times. You will see the down arrow will disapear because your widget is now bigger as it's container. You can now scroll down and a scrollbar will appear.

All this logic will be done automatically. Because of not using the browser scrollbar you can use always the full width of a widget.