@qtoggle/qui 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintignore +2 -0
- package/.eslintrc.json +492 -0
- package/.github/ISSUE_TEMPLATE/bug_report.md +33 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +23 -0
- package/.github/ISSUE_TEMPLATE/improvement_proposal.md +20 -0
- package/.github/workflows/main.yml +74 -0
- package/.pre-commit-config.yaml +8 -0
- package/LICENSE.txt +177 -0
- package/README.md +4 -0
- package/font/dejavusans-bold.woff +0 -0
- package/font/dejavusans-bolditalic.woff +0 -0
- package/font/dejavusans-italic.woff +0 -0
- package/font/dejavusans-regular.woff +0 -0
- package/img/qui-icons.svg +1937 -0
- package/js/base/base.js +47 -0
- package/js/base/condition-variable.js +92 -0
- package/js/base/errors.js +36 -0
- package/js/base/i18n.js +20 -0
- package/js/base/mixwith.js +135 -0
- package/js/base/require-js-compat.js +78 -0
- package/js/base/signal.js +91 -0
- package/js/base/singleton.js +66 -0
- package/js/base/timer.js +126 -0
- package/js/config.js +184 -0
- package/js/forms/common-fields/check-field.js +42 -0
- package/js/forms/common-fields/choice-buttons-field.js +30 -0
- package/js/forms/common-fields/color-combo-field.js +37 -0
- package/js/forms/common-fields/combo-field.js +108 -0
- package/js/forms/common-fields/common-fields.js +23 -0
- package/js/forms/common-fields/composite-field.js +132 -0
- package/js/forms/common-fields/custom-html-field.js +51 -0
- package/js/forms/common-fields/email-field.js +30 -0
- package/js/forms/common-fields/file-picker-field.js +46 -0
- package/js/forms/common-fields/jquery-ui-field.js +111 -0
- package/js/forms/common-fields/labels-field.js +69 -0
- package/js/forms/common-fields/numeric-field.js +39 -0
- package/js/forms/common-fields/password-field.js +28 -0
- package/js/forms/common-fields/phone-field.js +26 -0
- package/js/forms/common-fields/progress-disk-field.js +69 -0
- package/js/forms/common-fields/push-button-field.js +138 -0
- package/js/forms/common-fields/slider-field.js +51 -0
- package/js/forms/common-fields/text-area-field.js +34 -0
- package/js/forms/common-fields/text-field.js +89 -0
- package/js/forms/common-fields/up-down-field.js +85 -0
- package/js/forms/common-forms/common-forms.js +16 -0
- package/js/forms/common-forms/options-form.js +77 -0
- package/js/forms/common-forms/page-form.js +115 -0
- package/js/forms/form-button.js +202 -0
- package/js/forms/form-field.js +1183 -0
- package/js/forms/form.js +1181 -0
- package/js/forms/forms.js +68 -0
- package/js/global-glass.js +100 -0
- package/js/icons/default-stock.js +173 -0
- package/js/icons/icon.js +64 -0
- package/js/icons/icons.js +16 -0
- package/js/icons/multi-state-sprites-icon.js +362 -0
- package/js/icons/stock-icon.js +219 -0
- package/js/icons/stock.js +98 -0
- package/js/icons/stocks.js +57 -0
- package/js/index.js +232 -0
- package/js/lib/jquery.longpress.js +79 -0
- package/js/lib/jquery.module.js +4 -0
- package/js/lib/logger.module.js +4 -0
- package/js/lib/pep.module.js +4 -0
- package/js/lists/common-items/common-items.js +5 -0
- package/js/lists/common-items/icon-label-list-item.js +86 -0
- package/js/lists/common-lists/common-lists.js +5 -0
- package/js/lists/common-lists/page-list.js +53 -0
- package/js/lists/list-item.js +147 -0
- package/js/lists/list.js +636 -0
- package/js/lists/lists.js +26 -0
- package/js/main-ui/main-ui.js +64 -0
- package/js/main-ui/menu-bar.js +144 -0
- package/js/main-ui/options-bar.js +181 -0
- package/js/main-ui/status.js +185 -0
- package/js/main-ui/top-bar.js +59 -0
- package/js/messages/common-message-forms/common-message-forms.js +7 -0
- package/js/messages/common-message-forms/confirm-message-form.js +81 -0
- package/js/messages/common-message-forms/simple-message-form.js +67 -0
- package/js/messages/common-message-forms/sticky-simple-message-form.js +27 -0
- package/js/messages/message-form.js +107 -0
- package/js/messages/messages.js +21 -0
- package/js/messages/sticky-modal-page.js +98 -0
- package/js/messages/sticky-modal-progress-message.js +27 -0
- package/js/messages/toast.js +164 -0
- package/js/navigation.js +654 -0
- package/js/pages/breadcrumbs.js +124 -0
- package/js/pages/common-pages/common-pages.js +6 -0
- package/js/pages/common-pages/modal-progress-page.js +83 -0
- package/js/pages/common-pages/structured-page.js +46 -0
- package/js/pages/page.js +1018 -0
- package/js/pages/pages-context.js +154 -0
- package/js/pages/pages.js +252 -0
- package/js/pwa.js +337 -0
- package/js/sections/section.js +612 -0
- package/js/sections/sections.js +300 -0
- package/js/tables/common-cells/common-cells.js +7 -0
- package/js/tables/common-cells/icon-label-table-cell.js +68 -0
- package/js/tables/common-cells/push-button-table-cell.js +133 -0
- package/js/tables/common-cells/simple-table-cell.js +37 -0
- package/js/tables/common-tables/common-tables.js +5 -0
- package/js/tables/common-tables/page-table.js +55 -0
- package/js/tables/table-cell.js +198 -0
- package/js/tables/table-row.js +126 -0
- package/js/tables/table.js +492 -0
- package/js/tables/tables.js +36 -0
- package/js/theme.js +304 -0
- package/js/utils/ajax.js +126 -0
- package/js/utils/array.js +194 -0
- package/js/utils/colors.js +445 -0
- package/js/utils/cookies.js +65 -0
- package/js/utils/crypto.js +439 -0
- package/js/utils/css.js +234 -0
- package/js/utils/date.js +300 -0
- package/js/utils/files.js +27 -0
- package/js/utils/gestures.js +165 -0
- package/js/utils/html.js +76 -0
- package/js/utils/misc.js +81 -0
- package/js/utils/object.js +324 -0
- package/js/utils/promise.js +49 -0
- package/js/utils/string.js +192 -0
- package/js/utils/url.js +187 -0
- package/js/utils/utils.js +3 -0
- package/js/utils/visibility-manager.js +211 -0
- package/js/views/common-views/common-views.js +7 -0
- package/js/views/common-views/icon-label-view.js +210 -0
- package/js/views/common-views/progress-view.js +89 -0
- package/js/views/common-views/structured-view.js +368 -0
- package/js/views/view.js +467 -0
- package/js/views/views.js +3 -0
- package/js/widgets/base-widget.js +23 -0
- package/js/widgets/common-widgets/check-button.js +109 -0
- package/js/widgets/common-widgets/choice-buttons.js +322 -0
- package/js/widgets/common-widgets/color-combo.js +104 -0
- package/js/widgets/common-widgets/combo.js +645 -0
- package/js/widgets/common-widgets/common-widgets.js +17 -0
- package/js/widgets/common-widgets/email-input.js +7 -0
- package/js/widgets/common-widgets/file-picker.js +133 -0
- package/js/widgets/common-widgets/labels.js +132 -0
- package/js/widgets/common-widgets/numeric-input.js +49 -0
- package/js/widgets/common-widgets/password-input.js +91 -0
- package/js/widgets/common-widgets/phone-input.js +7 -0
- package/js/widgets/common-widgets/progress-disk.js +174 -0
- package/js/widgets/common-widgets/push-button.js +155 -0
- package/js/widgets/common-widgets/slider.js +455 -0
- package/js/widgets/common-widgets/text-area.js +52 -0
- package/js/widgets/common-widgets/text-input.js +174 -0
- package/js/widgets/common-widgets/up-down.js +351 -0
- package/js/widgets/widgets.js +57 -0
- package/js/window.js +557 -0
- package/jsdoc.conf.json +20 -0
- package/less/base.less +123 -0
- package/less/forms/common-fields.less +101 -0
- package/less/forms/common-forms.less +5 -0
- package/less/forms/form-button.less +21 -0
- package/less/forms/form-field.less +266 -0
- package/less/forms/form.less +131 -0
- package/less/global-glass.less +64 -0
- package/less/icon-label-view.less +82 -0
- package/less/icons.less +144 -0
- package/less/lists.less +105 -0
- package/less/main-ui.less +328 -0
- package/less/messages.less +189 -0
- package/less/no-effects.less +24 -0
- package/less/pages/breadcrumbs.less +98 -0
- package/less/pages/common-pages.less +36 -0
- package/less/pages/page.less +70 -0
- package/less/progress-view.less +51 -0
- package/less/stock-icons.less +43 -0
- package/less/structured-view.less +245 -0
- package/less/tables.less +84 -0
- package/less/theme-dark.less +133 -0
- package/less/theme-light.less +132 -0
- package/less/theme.less +419 -0
- package/less/visibility-manager.less +11 -0
- package/less/widgets/check-button.less +96 -0
- package/less/widgets/choice-buttons.less +160 -0
- package/less/widgets/color-combo.less +33 -0
- package/less/widgets/combo.less +230 -0
- package/less/widgets/common-buttons.less +120 -0
- package/less/widgets/common.less +24 -0
- package/less/widgets/input.less +258 -0
- package/less/widgets/labels.less +81 -0
- package/less/widgets/progress-disk.less +70 -0
- package/less/widgets/slider.less +199 -0
- package/less/widgets/updown.less +115 -0
- package/less/widgets/various.less +36 -0
- package/package.json +47 -0
- package/pyproject.toml +45 -0
- package/qui/__init__.py +110 -0
- package/qui/constants.py +1 -0
- package/qui/exceptions.py +2 -0
- package/qui/j2template.py +71 -0
- package/qui/settings.py +60 -0
- package/qui/templates/manifest.json +25 -0
- package/qui/templates/qui.html +126 -0
- package/qui/templates/service-worker.js +188 -0
- package/qui/web/__init__.py +0 -0
- package/qui/web/tornado.py +220 -0
- package/scripts/postinstall.sh +10 -0
- package/webpack/webpack-adjust-css-urls-loader.js +36 -0
- package/webpack/webpack-common.js +384 -0
package/js/config.js
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration registry.
|
|
3
|
+
* @namespace qui.config
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import * as ObjectUtils from '$qui/utils/object.js'
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
const _TRUE_VALUES = ['true', 'True', 'TRUE', 'on', 'On', 'ON', 'enabled', 'Enabled', 'ENABLED', 1]
|
|
10
|
+
|
|
11
|
+
const Config = {
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Flag indicating whether app runs in debug mode or not.
|
|
15
|
+
* @memberof qui.config
|
|
16
|
+
* @type Boolean
|
|
17
|
+
*/
|
|
18
|
+
debug: false,
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Build hash used to append to static URLs to prevent caching.
|
|
22
|
+
* @memberof qui.config
|
|
23
|
+
* @type String
|
|
24
|
+
*/
|
|
25
|
+
buildHash: '',
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Flag indicating whether navigation uses URL fragment or regular path.
|
|
29
|
+
* @memberof qui.config
|
|
30
|
+
* @type Boolean
|
|
31
|
+
*/
|
|
32
|
+
navigationUsesFragment: false,
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Common prefix used for all QUI paths.
|
|
36
|
+
* @memberof qui.config
|
|
37
|
+
* @type String
|
|
38
|
+
*/
|
|
39
|
+
navigationBasePrefix: '',
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Application name.
|
|
43
|
+
* @memberof qui.config
|
|
44
|
+
* @type String
|
|
45
|
+
*/
|
|
46
|
+
appName: '',
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Application display name.
|
|
50
|
+
* @memberof qui.config
|
|
51
|
+
* @type String
|
|
52
|
+
*/
|
|
53
|
+
appDisplayName: '',
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Latest application version, indicated by the server.
|
|
57
|
+
* @memberof qui.config
|
|
58
|
+
* @type String
|
|
59
|
+
*/
|
|
60
|
+
appLatestVersion: '',
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Current application version, indicated by the frontend.
|
|
64
|
+
* @memberof qui.config
|
|
65
|
+
* @type String
|
|
66
|
+
*/
|
|
67
|
+
appCurrentVersion: 'unknown-version',
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* QUI static base URL.
|
|
71
|
+
* @memberof qui.config
|
|
72
|
+
* @type String
|
|
73
|
+
*/
|
|
74
|
+
quiStaticURL: '',
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* App's static base URL; should be identical to {@link qui.config.quiStaticURL} in production mode.
|
|
78
|
+
* @memberof qui.config
|
|
79
|
+
* @type String
|
|
80
|
+
*/
|
|
81
|
+
appStaticURL: '',
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* The name of the main QUI script.
|
|
85
|
+
* @memberof qui.config
|
|
86
|
+
* @type String
|
|
87
|
+
*/
|
|
88
|
+
quiIndexName: '',
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* The name of the main app script.
|
|
92
|
+
* @memberof qui.config
|
|
93
|
+
* @type String
|
|
94
|
+
*/
|
|
95
|
+
appIndexName: '',
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* The theme to be initially loaded, by default.
|
|
99
|
+
* @memberof qui.config
|
|
100
|
+
* @type String
|
|
101
|
+
*/
|
|
102
|
+
defaultTheme: 'dark',
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* The list of comma-separated available themes.
|
|
106
|
+
* @memberof qui.config
|
|
107
|
+
* @type String
|
|
108
|
+
*/
|
|
109
|
+
themes: 'dark,light',
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Flag that indicates whether effects are enabled or disabled by default when app is loaded.
|
|
113
|
+
* @memberof qui.config
|
|
114
|
+
* @type Boolean
|
|
115
|
+
*/
|
|
116
|
+
defaultEffectsDisabled: false,
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Default small screen threshold to use when app is loaded.
|
|
120
|
+
* @memberof qui.config
|
|
121
|
+
* @type Number
|
|
122
|
+
*/
|
|
123
|
+
defaultSmallScreenThreshold: 700,
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Default scaling factor to use when app is loaded.
|
|
127
|
+
* @memberof qui.config
|
|
128
|
+
* @type Number
|
|
129
|
+
*/
|
|
130
|
+
defaultScalingFactor: 1,
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Return a configuration item value.
|
|
134
|
+
* @memberof qui.config
|
|
135
|
+
* @param {String} name configuration item name
|
|
136
|
+
* @param {*} [def = null] optional default value returned if missing
|
|
137
|
+
*/
|
|
138
|
+
get: function (name, def = null) {
|
|
139
|
+
let nameLower = name.toLowerCase()
|
|
140
|
+
let value = ObjectUtils.findValue(this, k => k.toLowerCase() === nameLower)
|
|
141
|
+
if (value === undefined) {
|
|
142
|
+
value = def
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return value
|
|
146
|
+
},
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Set a configuration item value.
|
|
150
|
+
* @memberof qui.config
|
|
151
|
+
* @param {String} name configuration item name
|
|
152
|
+
* @param {*} value new configuration item value
|
|
153
|
+
*/
|
|
154
|
+
set: function (name, value) {
|
|
155
|
+
let nameLower = name.toLowerCase()
|
|
156
|
+
let existingName = Object.keys(this).find(k => k.toLowerCase() === nameLower)
|
|
157
|
+
|
|
158
|
+
if (existingName) {
|
|
159
|
+
let existingValue = this[existingName]
|
|
160
|
+
|
|
161
|
+
/* Try to coerce the given type to existing type */
|
|
162
|
+
if (typeof existingValue !== typeof value) {
|
|
163
|
+
if (typeof existingValue === 'boolean') {
|
|
164
|
+
value = _TRUE_VALUES.some(v => v === value)
|
|
165
|
+
}
|
|
166
|
+
else if (typeof existingValue === 'number') {
|
|
167
|
+
value = parseFloat(value)
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
this[existingName || name] = value
|
|
173
|
+
},
|
|
174
|
+
|
|
175
|
+
dump: function () {
|
|
176
|
+
return ObjectUtils.filter(this, function (key, value) {
|
|
177
|
+
return (typeof value !== 'function')
|
|
178
|
+
})
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
export default Config
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
|
|
2
|
+
import * as ObjectUtils from '$qui/utils/object.js'
|
|
3
|
+
|
|
4
|
+
import JQueryUIField from './jquery-ui-field.js'
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* A check box field. The value data type is `Boolean`.
|
|
9
|
+
* @alias qui.forms.commonfields.CheckField
|
|
10
|
+
* @extends qui.forms.commonfields.JQueryUIField
|
|
11
|
+
*/
|
|
12
|
+
class CheckField extends JQueryUIField {
|
|
13
|
+
|
|
14
|
+
static WIDGET_CLASS = 'checkbutton'
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @constructs
|
|
19
|
+
* @param {String} [onClass] the CSS class to add to the check button in *on* state (defaults to `on`)
|
|
20
|
+
* @param {...*} args parent class parameters
|
|
21
|
+
*/
|
|
22
|
+
constructor({onClass = 'on', ...args}) {
|
|
23
|
+
/* We always prefer having the check box on the same line with its label */
|
|
24
|
+
ObjectUtils.setDefault(args, 'forceOneLine', true)
|
|
25
|
+
|
|
26
|
+
super({widgetAttrs: {onClass: onClass}, ...args})
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
setForm(form) {
|
|
30
|
+
super.setForm(form)
|
|
31
|
+
|
|
32
|
+
/* On compact forms, reduce the value width when showing on the same line with label, so that label can take as
|
|
33
|
+
* much space as needed */
|
|
34
|
+
if (form.isCompact() && this.isForceOneLine() && this.getValueWidth() == null) {
|
|
35
|
+
this.setValueWidth(0)
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
export default CheckField
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
|
|
2
|
+
import JQueryUIField from './jquery-ui-field.js'
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* A field backed by choice buttons. The value data type can be anything.
|
|
7
|
+
* @alias qui.forms.commonfields.ChoiceButtonsField
|
|
8
|
+
* @extends qui.forms.commonfields.JQueryUIField
|
|
9
|
+
*/
|
|
10
|
+
class ChoiceButtonsField extends JQueryUIField {
|
|
11
|
+
|
|
12
|
+
static WIDGET_CLASS = 'choicebuttons'
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @constructs
|
|
17
|
+
* @param {Object[]|Object[][]} choices choices or groups of choices (pairs/arrays of pairs of `label` and `value`)
|
|
18
|
+
* @param {String} [onClass] the CSS class to add to buttons in *on* state (defaults to `on`)
|
|
19
|
+
* @param {...*} args parent class parameters
|
|
20
|
+
*/
|
|
21
|
+
constructor({choices, onClass = 'on', ...args}) {
|
|
22
|
+
super({widgetAttrs: {choices: choices, onClass: onClass}, ...args})
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// TODO add setters and getters for choices
|
|
26
|
+
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
export default ChoiceButtonsField
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
|
|
2
|
+
import * as Colors from '$qui/utils/colors.js'
|
|
3
|
+
|
|
4
|
+
import JQueryUIField from './jquery-ui-field.js'
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* A color combo field based on preconfigured combo choices. The value data type is `String`.
|
|
9
|
+
* @alias qui.forms.commonfields.ColorComboField
|
|
10
|
+
* @extends qui.forms.commonfields.JQueryUIField
|
|
11
|
+
*/
|
|
12
|
+
class ColorComboField extends JQueryUIField {
|
|
13
|
+
|
|
14
|
+
static WIDGET_CLASS = 'colorcombo'
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @constructs
|
|
19
|
+
* @param {Boolean} [filterEnabled] set to `true` to enable filter input box
|
|
20
|
+
* @param {...*} args parent class parameters
|
|
21
|
+
*/
|
|
22
|
+
constructor({filterEnabled = false, ...args}) {
|
|
23
|
+
super({widgetAttrs: {filterEnabled: filterEnabled}, ...args})
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
valueToWidget(value) {
|
|
27
|
+
if (value && typeof value === 'string' && !value.startsWith('@')) {
|
|
28
|
+
value = Colors.normalize(value)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
super.valueToWidget(value)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
export default ColorComboField
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
|
|
2
|
+
import JQueryUIField from './jquery-ui-field.js'
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* A combo box field. The value data type can be anything.
|
|
7
|
+
* @alias qui.forms.commonfields.ComboField
|
|
8
|
+
* @extends qui.forms.commonfields.JQueryUIField
|
|
9
|
+
*/
|
|
10
|
+
class ComboField extends JQueryUIField {
|
|
11
|
+
|
|
12
|
+
static WIDGET_CLASS = 'combo'
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
// TODO add setters and getters for widget properties
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @constructs
|
|
19
|
+
* @param {Object[]} [choices] choices (pairs of `label` and `value`)
|
|
20
|
+
* @param {Function} [makeChoices] a function that generates choices (see
|
|
21
|
+
* {@link qui.forms.commonfields.ComboField#makeChoices}))
|
|
22
|
+
* @param {Number} [fastFactor] determines how fast the page-up/page-down actions work (defaults to `5`)
|
|
23
|
+
* @param {Boolean} [filterEnabled] set to `true` to enable filter input box
|
|
24
|
+
* @param {Function} [filterFunc] custom filtering function (see
|
|
25
|
+
* {@link qui.forms.commonfields.ComboField#makeChoices})
|
|
26
|
+
* @param {...*} args parent class parameters
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
constructor({
|
|
30
|
+
choices = [],
|
|
31
|
+
makeChoices = null,
|
|
32
|
+
fastFactor = null,
|
|
33
|
+
filterEnabled = false,
|
|
34
|
+
filterFunc = null,
|
|
35
|
+
...args
|
|
36
|
+
}) {
|
|
37
|
+
super({
|
|
38
|
+
widgetAttrs: {
|
|
39
|
+
choices: choices,
|
|
40
|
+
fastFactor: fastFactor,
|
|
41
|
+
filterEnabled: filterEnabled,
|
|
42
|
+
makeChoices: function () {
|
|
43
|
+
return that.makeChoices()
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
...args
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
/* "that" needs to be assigned here because we can't refer to "this" before super() */
|
|
50
|
+
let that = this
|
|
51
|
+
|
|
52
|
+
this._filterFunc = filterFunc
|
|
53
|
+
this._makeChoices = makeChoices
|
|
54
|
+
|
|
55
|
+
if (filterFunc || (this.filterFunc !== ComboField.prototype.filterFunc)) {
|
|
56
|
+
this._widgetCall('option', {filterFunc: this.filterFunc.bind(this)})
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Set the list of choices.
|
|
62
|
+
* @param {Object[]} choices choices (pairs of `label` and `value`)
|
|
63
|
+
*/
|
|
64
|
+
setChoices(choices) {
|
|
65
|
+
this._widgetCall({choices: choices})
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Create choices.
|
|
70
|
+
* @returns {Object[]} choices (pairs of `label` and `value`)
|
|
71
|
+
*/
|
|
72
|
+
makeChoices() {
|
|
73
|
+
if (this._makeChoices) {
|
|
74
|
+
return this._makeChoices()
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return []
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Tell if a choice matches a search text or not.
|
|
82
|
+
* @param {Object} choice
|
|
83
|
+
* @param {String} searchText
|
|
84
|
+
* @returns {Boolean}
|
|
85
|
+
*/
|
|
86
|
+
filterFunc(choice, searchText) {
|
|
87
|
+
if (this._filterFunc) {
|
|
88
|
+
return this._filterFunc(choice, searchText)
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return true
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Update the list of choices, calling makeChoices.
|
|
96
|
+
*/
|
|
97
|
+
updateChoices() {
|
|
98
|
+
let value = this._widgetCall('getValue')
|
|
99
|
+
this._widgetCall('updateChoices')
|
|
100
|
+
if (value != null) {
|
|
101
|
+
this._widgetCall('setValue', value)
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
export default ComboField
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @namespace qui.forms.commonfields
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export {default as CheckField} from './check-field.js'
|
|
6
|
+
export {default as ChoiceButtonsField} from './choice-buttons-field.js'
|
|
7
|
+
export {default as ColorComboField} from './color-combo-field.js'
|
|
8
|
+
export {default as ComboField} from './combo-field.js'
|
|
9
|
+
export {default as CompositeField} from './composite-field.js'
|
|
10
|
+
export {default as CustomHTMLField} from './custom-html-field.js'
|
|
11
|
+
export {default as EmailField} from './email-field.js'
|
|
12
|
+
export {default as FilePickerField} from './file-picker-field.js'
|
|
13
|
+
export {default as JQueryUIField} from './jquery-ui-field.js'
|
|
14
|
+
export {default as LabelsField} from './labels-field.js'
|
|
15
|
+
export {default as NumericField} from './numeric-field.js'
|
|
16
|
+
export {default as PasswordField} from './password-field.js'
|
|
17
|
+
export {default as PhoneField} from './phone-field.js'
|
|
18
|
+
export {default as ProgressDiskField} from './progress-disk-field.js'
|
|
19
|
+
export {default as PushButtonField} from './push-button-field.js'
|
|
20
|
+
export {default as SliderField} from './slider-field.js'
|
|
21
|
+
export {default as TextAreaField} from './text-area-field.js'
|
|
22
|
+
export {default as TextField} from './text-field.js'
|
|
23
|
+
export {default as UpDownField} from './up-down-field.js'
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
|
|
2
|
+
import $ from '$qui/lib/jquery.module.js'
|
|
3
|
+
|
|
4
|
+
import FormField from '../form-field.js'
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* A form field composed by multiple subfields.
|
|
9
|
+
* @alias qui.forms.commonfields.CompositeField
|
|
10
|
+
* @extends qui.forms.FormField
|
|
11
|
+
*/
|
|
12
|
+
class CompositeField extends FormField {
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @constructs
|
|
16
|
+
* @param {qui.forms.FormField[]} fields the list of subfields
|
|
17
|
+
* @param {String} [flow] arrange subfield widgets vertically (`"vertical"`) or horizontally (`"horizontal"`,
|
|
18
|
+
* default)
|
|
19
|
+
* @param {Number} [columns] number of columns (unlimited by default, when `flow` is `"horizontal"`, otherwise
|
|
20
|
+
* defaults to `1`)
|
|
21
|
+
* @param {Number} [rows] number of rows (unlimited by default, when `flow` is `"vertical"`, otherwise defaults to
|
|
22
|
+
* `1`)
|
|
23
|
+
* @param {Boolean} [equalSize] set to `true` to make all cells of equal width/height (defaults to `false`)
|
|
24
|
+
* @param {...*} args parent class parameters
|
|
25
|
+
*/
|
|
26
|
+
constructor({fields, flow = 'horizontal', columns = null, rows = null, equalSize = false, ...args}) {
|
|
27
|
+
super(args)
|
|
28
|
+
|
|
29
|
+
this._fields = fields.map(this._preprocessField)
|
|
30
|
+
this._flow = flow
|
|
31
|
+
this._columns = columns
|
|
32
|
+
this._rows = rows
|
|
33
|
+
this._equalSize = equalSize
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
focus() {
|
|
37
|
+
/* Focus the first field */
|
|
38
|
+
this._fields.some(f => f.focus(), true)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
makeWidget() {
|
|
42
|
+
let div = $('<div></div>', {class: 'qui-composite-field-container'})
|
|
43
|
+
let sizeSpec = this._equalSize ? '1fr' : 'auto'
|
|
44
|
+
if (this._flow === 'horizontal') {
|
|
45
|
+
if (this._columns) {
|
|
46
|
+
div.css('grid-template-columns', `repeat(${this._columns}, ${sizeSpec})`)
|
|
47
|
+
div.css('grid-auto-flow', 'row')
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
div.css('grid-auto-flow', 'column')
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
if (this._rows) {
|
|
55
|
+
div.css('grid-template-rows', `repeat(${this._rows}, ${sizeSpec})`)
|
|
56
|
+
div.css('grid-auto-flow', 'column')
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
div.css('grid-auto-flow', 'row')
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
this._fields.forEach(function (field) {
|
|
64
|
+
div.append(field.getHTML())
|
|
65
|
+
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
return div
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
validateWidget(value) {
|
|
72
|
+
/* Return the first validation error among fields */
|
|
73
|
+
|
|
74
|
+
let error = null
|
|
75
|
+
this._fields.some(function (field) {
|
|
76
|
+
let e = field.validateWidget(value[field.getName()])
|
|
77
|
+
if (e != null) {
|
|
78
|
+
error = e
|
|
79
|
+
return true
|
|
80
|
+
}
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
return error
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
valueToWidget(value) {
|
|
87
|
+
this._fields.forEach(f => f.valueToWidget(value[f.getName()]))
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
widgetToValue() {
|
|
91
|
+
return Object.fromEntries(this._fields.map(f => [f.getName(), f.widgetToValue()]))
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
setWidgetReadonly(readonly) {
|
|
95
|
+
this._fields.forEach(f => f.setWidgetReadonly(readonly))
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
enableWidget() {
|
|
99
|
+
this._fields.forEach(f => f.enableWidget())
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
disableWidget() {
|
|
103
|
+
this._fields.forEach(f => f.disableWidget())
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
setForm(form) {
|
|
107
|
+
super.setForm(form)
|
|
108
|
+
|
|
109
|
+
this._fields.forEach(f => f.setForm(form))
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Return the subfield with a given name. If no such field is found, `null` is returned.
|
|
114
|
+
* @param {String} name the name of the subfield
|
|
115
|
+
* @returns {?qui.forms.FormField}
|
|
116
|
+
*/
|
|
117
|
+
getField(name) {
|
|
118
|
+
return this._fields.find(f => f.getName() === name) || null
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
_preprocessField(field) {
|
|
122
|
+
field.setLabel('') /* Subfields of composite field can't have label */
|
|
123
|
+
field.setValueWidth(100) /* The value always occupies the entire space */
|
|
124
|
+
field._forceOneLine = true // TODO: this should be a field setter
|
|
125
|
+
|
|
126
|
+
return field
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
export default CompositeField
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
|
|
2
|
+
import $ from '$qui/lib/jquery.module.js'
|
|
3
|
+
|
|
4
|
+
import FormField from '../form-field.js'
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* A form field whose widget's HTML content is supplied by user.
|
|
9
|
+
* @alias qui.forms.commonfields.CustomHTMLField
|
|
10
|
+
* @extends qui.forms.FormField
|
|
11
|
+
*/
|
|
12
|
+
class CustomHTMLField extends FormField {
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @constructs
|
|
16
|
+
* @param {String|jQuery} content the HTML content
|
|
17
|
+
* @param {...*} args parent class parameters
|
|
18
|
+
*/
|
|
19
|
+
constructor({content, ...args}) {
|
|
20
|
+
super(args)
|
|
21
|
+
|
|
22
|
+
if (typeof content === 'string') {
|
|
23
|
+
content = $(content)
|
|
24
|
+
}
|
|
25
|
+
this._content = content
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
makeWidget() {
|
|
29
|
+
return this._content
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
valueToWidget(value) {
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
widgetToValue() {
|
|
36
|
+
return null
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
setWidgetReadonly(readonly) {
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
enableWidget() {
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
disableWidget() {
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
export default CustomHTMLField
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
|
|
2
|
+
import TextField from './text-field.js'
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* An email text field. The value data type is `String`.
|
|
7
|
+
* @alias qui.forms.commonfields.EmailField
|
|
8
|
+
* @extends qui.forms.commonfields.TextField
|
|
9
|
+
*/
|
|
10
|
+
class EmailField extends TextField {
|
|
11
|
+
|
|
12
|
+
static WIDGET_CLASS = 'emailinput'
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @constructs
|
|
17
|
+
* @param {...*} args parent class parameters
|
|
18
|
+
*/
|
|
19
|
+
constructor({...args}) {
|
|
20
|
+
super(args)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
validateWidget(value) {
|
|
24
|
+
return null // TODO implement me
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
export default EmailField
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
|
|
2
|
+
import JQueryUIField from './jquery-ui-field.js'
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* A file picker field. The value data type is `File[]`.
|
|
7
|
+
* @alias qui.forms.commonfields.FilePickerField
|
|
8
|
+
* @extends qui.forms.commonfields.JQueryUIField
|
|
9
|
+
*/
|
|
10
|
+
class FilePickerField extends JQueryUIField {
|
|
11
|
+
|
|
12
|
+
static WIDGET_CLASS = 'filepicker'
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @constructs
|
|
17
|
+
* @param {?String} [placeholder] an empty-selection placeholder
|
|
18
|
+
* @param {?String[]} [accept] an optional list of file types to accept
|
|
19
|
+
* @param {Boolean} [multiple] enable or disable multiple file selection (disabled by default)
|
|
20
|
+
* @param {Object} [widgetAttrs] extra attributes to pass to underlying JQueryUI widget
|
|
21
|
+
* @param {...*} args parent class parameters
|
|
22
|
+
*/
|
|
23
|
+
constructor({
|
|
24
|
+
placeholder = null,
|
|
25
|
+
accept = null,
|
|
26
|
+
multiple = false,
|
|
27
|
+
widgetAttrs = {},
|
|
28
|
+
...args
|
|
29
|
+
}) {
|
|
30
|
+
Object.assign(widgetAttrs, {
|
|
31
|
+
placeholder: placeholder,
|
|
32
|
+
accept: accept,
|
|
33
|
+
multiple: multiple
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
super({widgetAttrs: widgetAttrs, ...args})
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
getFocusableElement() {
|
|
40
|
+
return this.getWidget().children('input')
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
export default FilePickerField
|