Source RapidContext_Widget_Overlay.js

1/*
2 * RapidContext <https://www.rapidcontext.com/>
3 * Copyright (c) 2007-2023 Per Cederberg. All rights reserved.
4 *
5 * This program is free software: you can redistribute it and/or
6 * modify it under the terms of the BSD license.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * See the RapidContext LICENSE for more details.
13 */
14
15// Namespace initialization
16if (typeof(RapidContext) == "undefined") {
17    RapidContext = {};
18}
19RapidContext.Widget = RapidContext.Widget || { Classes: {} };
20
21/**
22 * Creates a new overlay widget.
23 *
24 * @constructor
25 * @param {Object} attrs the widget and node attributes
26 * @param {boolean} [attrs.loading] the display loading icon flag, defaults to
27 *            `true`
28 * @param {string} [attrs.message] the overlay message text, defaults to
29 *            "Working..."
30 * @param {boolean} [attrs.dark] the dark overlay flag, defaults to `false`
31 * @param {boolean} [attrs.hidden] the hidden widget flag, defaults to `true`
32 *
33 * @return {Widget} the widget DOM node
34 *
35 * @class The overlay widget class. Used to provide a layer on top of the
36 *     parent node, using a `<div>` HTML element. This widget is useful for
37 *     disabling the user interface during an operation.
38 * @extends RapidContext.Widget
39 *
40 * @example <caption>JavaScript</caption>
41 * let workOverlay = RapidContext.WidgetOverlay({ message: "Doing Stuff..." });
42 *
43 * @example <caption>User Interface XML</caption>
44 * <Overlay id="workOverlay" message="Doing Stuff..." />
45 */
46RapidContext.Widget.Overlay = function (attrs) {
47    let cover = MochiKit.DOM.DIV({ "class": "widgetOverlayCover" });
48    let msg = MochiKit.DOM.DIV({ "class": "widgetOverlayMessage" });
49    let o = MochiKit.DOM.DIV({}, cover, msg);
50    RapidContext.Widget._widgetMixin(o, RapidContext.Widget.Overlay);
51    o.addClass("widgetOverlay");
52    o.setAttrs(Object.assign({ loading: true, message: "Working..." }, attrs));
53    return o;
54};
55
56// Register widget class
57RapidContext.Widget.Classes.Overlay = RapidContext.Widget.Overlay;
58
59/**
60 * Returns the widget container DOM node.
61 *
62 * @return {Node} returns null, since child nodes are not supported
63 */
64RapidContext.Widget.Overlay.prototype._containerNode = function () {
65    return null;
66};
67
68/**
69 * Updates the widget or HTML DOM node attributes.
70 *
71 * @param {Object} attrs the widget and node attributes to set
72 * @param {boolean} [attrs.loading] the display loading icon flag
73 * @param {string} [attrs.message] the overlay message text
74 * @param {boolean} [attrs.hidden] the hidden widget flag
75 */
76RapidContext.Widget.Overlay.prototype.setAttrs = function (attrs) {
77    attrs = Object.assign({}, attrs);
78    if ("loading" in attrs) {
79        attrs.loading = RapidContext.Data.bool(attrs.loading);
80    }
81    if ("dark" in attrs) {
82        attrs.dark = RapidContext.Data.bool(attrs.dark);
83        this.classList.toggle("widgetOverlayDark", attrs.dark);
84    }
85    this.__setAttrs(attrs);
86    this.lastChild.innerHTML = "";
87    let icon = this.loading && RapidContext.Widget.Icon("fa fa-refresh fa-spin m-1");
88    this.lastChild.append(icon || "", this.message || "");
89    this.lastChild.classList.toggle("widgetHidden", !this.loading && !this.message);
90};
91