Skip to content

Commit 451cd4f

Browse files
committed
Updated to v21
1 parent 54b309c commit 451cd4f

File tree

12 files changed

+407
-89
lines changed

12 files changed

+407
-89
lines changed

js/button.js

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,32 @@ import View from './view';
55
// ////////////////////////////////////////////////////////////////////////////
66
// CONSTANTS
77

8-
const EVENT_ROOT = 'mvc.button';
9-
const EVENT_CLICK = `${EVENT_ROOT}.click`;
8+
const EVENT_ROOT = 'button';
9+
10+
/**
11+
* Button click event
12+
*
13+
* @event Button#button:click
14+
* @arg {Button} sender - The view that emitted the event.
15+
* @arg {Node} target - The node for the button.
16+
*/
17+
const EVENT_CLICK = `${EVENT_ROOT}:click`;
1018

1119
// ////////////////////////////////////////////////////////////////////////////
1220
// BUTTON
1321

22+
/**
23+
* @class Button
24+
* @implements {View}
25+
* @classdesc This class is constructed with a DOM element and
26+
* controls an existing
27+
* [Bootstrap Button]{@link https://getbootstrap.com/docs/5.0/components/buttons/}.
28+
*
29+
* @arg {Node} node - The node to attach the view to. Throws an error if the node
30+
* is not provided.
31+
*
32+
* @throws Error
33+
*/
1434
export default class Button extends View {
1535
constructor(node) {
1636
super(node);

js/error.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
1-
// Error class
2-
1+
/**
2+
* Error represents an error message.
3+
* @class
4+
* @classdesc Errors are emitted by several components. The Error class is used
5+
* to encapsulate an error and numerical code for the error.
6+
*
7+
* @arg {string} reason - The error description
8+
* @arg {number} code - The numerical code for the error
9+
*
10+
* @property {string} $reason - Returns the error reason
11+
* @property {number} $code - Return the error code
12+
*/
313
export default class Error {
414
constructor(reason, code) {
515
this.$reason = reason;

js/form.js

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,52 @@ import Error from './error';
77
// ////////////////////////////////////////////////////////////////////////////
88
// CONSTANTS
99

10-
const EVENT_ROOT = 'mvc.form';
11-
const EVENT_SUBMIT = `${EVENT_ROOT}.submit`;
12-
const EVENT_CHANGE = `${EVENT_ROOT}.change`;
10+
const EVENT_ROOT = 'form';
11+
12+
/**
13+
* Form submit event, which is emitted whenever submission occurs on the
14+
* form (with a button or other method). The event is only fired if the
15+
* form validation checks passed.
16+
*
17+
* @event Form#form:submit
18+
* @arg {Form} sender - The form that emitted the event.
19+
* @arg {Node} target - The input control or button that submitted the form.
20+
*/
21+
const EVENT_SUBMIT = `${EVENT_ROOT}:submit`;
22+
23+
/**
24+
* Form change event, which is emitted whenever an input control on the
25+
* form is changed.
26+
*
27+
* @event Form#form:change
28+
* @arg {Form} sender - The form that emitted the event.
29+
* @arg {Node} target - The input control that changed.
30+
*/
31+
const EVENT_CHANGE = `${EVENT_ROOT}:change`;
1332

1433
// ////////////////////////////////////////////////////////////////////////////
15-
// FORM
1634

35+
/**
36+
* Form represents a HTML form, which can contain values entered by the user.
37+
* @class
38+
* @implements {View}
39+
* @classdesc A list is a view which uses a 'row' template to added and remove
40+
* rows from a view.
41+
* @classdesc This class is constructed with a DOM element and
42+
* controls an existing
43+
* [Bootstrap Form]{@link https://getbootstrap.com/docs/5.0/forms/overview/}
44+
* and is generally used for validating, submitting and tracking form input. The form
45+
* can be wrapped in a [Bootstrap Modal]{@link https://getbootstrap.com/docs/5.0/components/modal/}
46+
* so that the show and hide methods can be used to set visibility.
47+
*
48+
* @arg {Node} node - The node to attach the view to. Throws an error if the node
49+
* is not provided.
50+
*
51+
* @property {FormData} formdata - Returns a form data object representing the form values
52+
* @property {Object<string,string>} values - Get and set the form values
53+
*
54+
* @throws Error
55+
*/
1756
export default class Form extends View {
1857
constructor(node) {
1958
super(node);
@@ -44,6 +83,13 @@ export default class Form extends View {
4483
this.dispatchEvent(EVENT_CHANGE, this, evt.target);
4584
}
4685

86+
/**
87+
* Sets the default values for the form and if the form is modal, the modal
88+
* is show.
89+
* @param {Object<string,string>} defaults - The values for the form controls.
90+
* @fires Form#form:submit
91+
* @fires Form#form:change
92+
*/
4793
show(defaults) {
4894
this.$form.classList.remove('was-validated');
4995
if (defaults) {
@@ -52,6 +98,9 @@ export default class Form extends View {
5298
this.$modal.show();
5399
}
54100

101+
/**
102+
* If the form is modal, the modal is hidden.
103+
*/
55104
hide() {
56105
this.$modal.hide();
57106
}

js/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,6 @@ import 'bootstrap-icons/font/fonts/bootstrap-icons.woff2';
2626
import '../css/style.css';
2727

2828
// Exports
29-
export {
29+
export default {
3030
Model, View, Controller, Provider, Error, Emitter, List, Nav, Toast, Button, Form,
3131
};

js/list.js

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,33 @@ import Error from './error';
66
// ////////////////////////////////////////////////////////////////////////////
77
// CONSTANTS
88

9-
const EVENT_ROOT = 'mvc.list';
10-
const EVENT_CLICK = `${EVENT_ROOT}.click`;
9+
const EVENT_ROOT = 'list';
10+
11+
/**
12+
* List row click event
13+
*
14+
* @event List#list:click
15+
* @arg {Nav} sender - The provider that emitted the event.
16+
* @arg {Node} target - The target element clicked.
17+
*/
18+
const EVENT_CLICK = `${EVENT_ROOT}:click`;
1119

1220
// ////////////////////////////////////////////////////////////////////////////
13-
// LISTVIEW
1421

22+
/**
23+
* List provides a way to dynamically create an ordered list of elements in a
24+
* view.
25+
* @class
26+
* @implements {View}
27+
* @classdesc A list is a view which uses a 'row' template to added and remove
28+
* rows from a view.
29+
*
30+
* @arg {Node} node - The node to attach the view to. Throws an error if the node
31+
* is not provided.
32+
* @arg {string} classTemplate - class name of the template within the view which is
33+
* cloned for each row.
34+
* @throws Error
35+
*/
1536
export default class List extends View {
1637
constructor(node, classTemplate) {
1738
super(node);
@@ -29,6 +50,14 @@ export default class List extends View {
2950
this.$prototype.classList.remove(this.$className);
3051
}
3152

53+
/**
54+
* Add or update an existing row. When adding a row, it is cloned from the template
55+
* and added to the end of the view element.
56+
* @param {Model} obj - The object which should be represented in the view.
57+
* @param {string} key - A unique identifier for the row.
58+
* @returns View - The view added or to be updated in the list
59+
* @fires List#list:click
60+
*/
3261
set(obj, key) {
3362
let row = this.getForKey(key);
3463

@@ -53,17 +82,33 @@ export default class List extends View {
5382
return new View(row);
5483
}
5584

85+
/**
86+
* Return a Node representing a row.
87+
* @param {string} key - A unique identifier for the row.
88+
* @returns Node - The view representing the row
89+
*/
5690
getForKey(key) {
91+
// TODO return a view object?
5792
return key ? this.query(`#${key}`) : undefined;
5893
}
5994

95+
/**
96+
* Remove a row from the view.
97+
* @param {string} key - A unique identifier for the row.
98+
*/
6099
deleteForKey(key) {
61100
const row = this.getForKey(key);
62101
if (row) {
63102
row.remove();
64103
}
65104
}
66105

106+
/**
107+
* Update the list by adding a class name to a row identified by key,
108+
* and remove the class name from all other rows.
109+
* @param {string} key - A unique identifier for the row.
110+
* @param {string} className - The class name to use.
111+
*/
67112
setClassForKey(key, className) {
68113
super.queryAll(`.${className}`).forEach((node) => {
69114
node.classList.remove(className);
@@ -75,6 +120,10 @@ export default class List extends View {
75120
return selectedNode;
76121
}
77122

123+
/**
124+
* Sort rows in order according the the keys provided.
125+
* @param {string[]} keys - The ordered array of keys.
126+
*/
78127
sortForKeys(keys) {
79128
for (let i = keys.length - 1; i >= 0; i -= 1) {
80129
const row = this.getForKey(keys[i]);

js/model.js

Lines changed: 68 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Model class to be subclassed by an actual model
1+
/* eslint-disable func-names */
22

33
import Error from './error';
44

@@ -14,8 +14,21 @@ const REGEXP_ALIASED = /^([A-Za-z0-9-_]*)\s+(\{\}|\[\])?(\w+)$/i;
1414
const REGEXP_NOTALIASED = /^()(\{\}|\[\])?(\w+)$/i;
1515

1616
// ////////////////////////////////////////////////////////////////////////////
17-
// MODEL CLASS
1817

18+
/**
19+
* Model manages data transfer between provider, form and internal representation.
20+
* @class
21+
* @classdesc This class is used as a base class to a model. You should extend
22+
* this class and call the define method to describe the data model properties. When constructing
23+
* a model, you can then access your properties as you would any other object.
24+
*
25+
* @arg {Object} data - The data which is parsed and used to construct the model instance.
26+
*
27+
* @property {string} $json - Returns JSON representation of the model values.
28+
* @property {string} $className - Returns the class name of the model.
29+
*
30+
* @throws Error
31+
*/
1932
export default class Model {
2033
constructor(data) {
2134
// Get prototype
@@ -32,6 +45,22 @@ export default class Model {
3245
this.$setall(data);
3346
}
3447

48+
/**
49+
* Define the object model. The model supports string, number, boolean and date
50+
* as native values, and map, object and array as collections. You can define
51+
* the model as an array of properties, each property is a string with an optional
52+
* alias (the data key of the external representation) and the internal representation.
53+
* For example, to define a string use "string" as the property, or for example "id string"
54+
* if the external representation uses 'id' as the key. To define an object as a
55+
* model member, use the name of the model (ie, 'User'). For a map, use '{}' before the
56+
* type and for an array use '[]' before the type.
57+
*
58+
* @arg {function} classConstructor - The constructor for the model
59+
* @arg {Object.<string,string>} classProps - The definition of the model properties
60+
* @arg {string=} className - The name of the class referred to in class properties.
61+
* Uses constructor name if not given.
62+
* @throws Error
63+
*/
3564
static define(classConstructor, classProps, className) {
3665
if (typeof classConstructor !== 'function') {
3766
throw new Error('Called define without a class constructor');
@@ -48,6 +77,42 @@ export default class Model {
4877
Model.models[classKey] = proto;
4978
}
5079

80+
/**
81+
* @method Model#$get
82+
* @arg {string} key - The key of the property
83+
* @returns {string|number|boolean|Date|Map|Array|Model|undefined}
84+
* @desc Return a property value or undefined
85+
*/
86+
/**
87+
* @method Model#$set
88+
* @arg {string} key - The key of the property
89+
* @arg {string|number|boolean|Date|Map|Array|Model|undefined} value - The value
90+
* for the property
91+
* @returns {string|number|boolean|Date|Map|Array|Model|undefined}
92+
* @desc Set a property value for a key
93+
*/
94+
/**
95+
* @method Model#$getall
96+
* @returns {Object}
97+
* @desc Get all property values that can be transmitted stored in external representation.
98+
* Does not include values which are undefined.
99+
*/
100+
/**
101+
* @method Model#$setall
102+
* @desc Set all property values from external representation. Replaces all existing
103+
* property values.
104+
* @returns {Object}
105+
*/
106+
/**
107+
* @method Model#toString
108+
* @desc Return object in string form, for debugging.
109+
* @returns {string}
110+
*/
111+
/**
112+
* @method Model#$equals
113+
* @desc Checks for equality between this object and another model.
114+
* @returns {boolean}
115+
*/
51116
static $newproto(classKey, classProps, className) {
52117
const proto = {};
53118

@@ -99,21 +164,16 @@ export default class Model {
99164
});
100165
});
101166

102-
// $get function
103-
// eslint-disable-next-line func-names
104167
proto.$get = function (key) {
105168
return this.$data[key];
106169
};
107170

108-
// $set function
109-
// eslint-disable-next-line func-names
110171
proto.$set = function (key, value) {
111172
const v = this.$type.get(key);
112173
this.$data[key] = Model.$cast(value, v.collection, v.primitive, v.model);
174+
return this.$data[key];
113175
};
114176

115-
// $getall function
116-
// eslint-disable-next-line func-names
117177
proto.$getall = function () {
118178
const obj = {};
119179
this.$type.forEach((v, k) => {
@@ -125,8 +185,6 @@ export default class Model {
125185
return obj;
126186
};
127187

128-
// $setall function
129-
// eslint-disable-next-line func-names
130188
proto.$setall = function (data) {
131189
if (typeof data !== 'object') {
132190
throw new Error(`Constructor requires object for ${this.constructor.name}`);
@@ -137,8 +195,6 @@ export default class Model {
137195
});
138196
};
139197

140-
// toString function
141-
// eslint-disable-next-line func-names
142198
proto.toString = function () {
143199
let str = `<${this.$className}`;
144200
this.$type.forEach((_, k) => {
@@ -148,8 +204,6 @@ export default class Model {
148204
return `${str}>`;
149205
};
150206

151-
// $equals function
152-
// eslint-disable-next-line func-names
153207
proto.$equals = function (other) {
154208
if (!other) {
155209
return false;

0 commit comments

Comments
 (0)