Skip to content

Commit bd6060e

Browse files
committed
Updated
1 parent 954af5f commit bd6060e

File tree

13 files changed

+2791
-136
lines changed

13 files changed

+2791
-136
lines changed

README.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,11 @@
11
# js-framework
2-
Test framework
2+
3+
This Javascript framework is a pretty traditional Model, View and Controller
4+
implementation which provides the following classes:
5+
6+
* __Controller class__: Subclass this and hook your views and provider events together;
7+
* __Provider class__: To be used to request JSON objects and arrays of objects from an external source;
8+
* __Model class__: subclass this for your JSON models, and separately define the members of your class;
9+
* __View classes__: classes are provided for form, list, button, etc.
10+
11+

config/rollup.config.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,32 @@
11
import { nodeResolve } from '@rollup/plugin-node-resolve';
22
import postcss from 'rollup-plugin-postcss';
3+
import smartAsset from 'rollup-plugin-smart-asset';
4+
import url from 'postcss-url';
35

46
export default {
57
input: 'js/index.js',
68
output: {
9+
sourcemap: true,
710
file: 'dist/js/index.js',
811
format: 'iife',
912
},
1013
plugins: [
1114
nodeResolve(),
1215
postcss({
1316
extensions: ['.css'],
17+
plugins: [
18+
url({
19+
url: 'inline',
20+
}),
21+
],
22+
}),
23+
smartAsset({
24+
url: 'copy',
25+
keepImport: true,
26+
useHash: false,
27+
keepName: true,
28+
assetsPath: '../fonts',
29+
extensions: ['.woff', '.woff2'],
1430
}),
1531
],
1632
external: [

css/style.css

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,16 @@
1010
font-size: 36px;
1111
line-height: 0;
1212
}
13+
14+
/* Copy Paste */
15+
.mvc-copypaste:before {
16+
content: "\f28b";
17+
display: inline-block;
18+
font-family: bootstrap-icons !important;
19+
font-style: normal;
20+
font-weight: normal;
21+
font-variant: normal;
22+
text-transform: none;
23+
line-height: 1;
24+
margin: 1px;
25+
}

etc/rpi4b.conf

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@ server {
1212
location / {
1313
ssi on;
1414
}
15-
1615
# Serve javascript files
1716
location /js {
1817
alias /opt/js-framework/dist/js;
1918
}
19+
location /fonts {
20+
alias /opt/js-framework/dist/fonts;
21+
}
2022
}

html/index.html

Lines changed: 63 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,22 @@
3636
</div>
3737
</nav>
3838

39+
<!-- TABLE -->
40+
<div class="container">
41+
<table class="table table-hover">
42+
<thead>
43+
<tr>
44+
<th>Project</th>
45+
</tr>
46+
</thead>
47+
<tbody id="table">
48+
<tr class="_template">
49+
<td class="_name">Project</td>
50+
</tr>
51+
</tbody>
52+
</table>
53+
</div>
54+
3955
<!-- PLUS BUTTON -->
4056
<div class="fixed-bottom d-flex flex-row-reverse">
4157
<button id="plus" class="btn btn-circle bg-danger text-white onclick-item" title="Add">+</button>
@@ -75,13 +91,13 @@ <h5 class="modal-title">Create New Project</h5>
7591
<label class="col-sm-4 col-form-label">Radio Buttons</label>
7692
<div class="col-sm-8">
7793
<div class="form-check form-check-inline">
78-
<input class="form-check-input" type="radio" name="radio"
79-
id="inlineRadio1" value="option1">
94+
<input class="form-check-input" type="radio" name="radio" id="inlineRadio1"
95+
value="option1">
8096
<label class="form-check-label" for="inlineRadio1">1</label>
8197
</div>
8298
<div class="form-check form-check-inline">
83-
<input class="form-check-input" type="radio" name="radio"
84-
id="inlineRadio2" value="option2">
99+
<input class="form-check-input" type="radio" name="radio" id="inlineRadio2"
100+
value="option2">
85101
<label class="form-check-label" for="inlineRadio2">2</label>
86102
</div>
87103
</div>
@@ -121,19 +137,33 @@ <h5 class="modal-title">Create New Project</h5>
121137
var app = mvc.Controller.New();
122138

123139
// Models
124-
class Project extends mvc.Model {};
140+
class Project extends mvc.Model {
141+
constructor(data) {
142+
super(data);
143+
console.log(data);
144+
}
145+
};
146+
mvc.Model.define(Project, {
147+
key: "_id string",
148+
name: "string",
149+
status: "string",
150+
createdDate: "created_date date",
151+
updatedDate: "updated_date date",
152+
tags: "{}string",
153+
});
125154

126155
// Add objects to the application
127156
app.Add('nav', new mvc.Nav(document.querySelector("#nav")));
128157
app.Add('toast', new mvc.Toast(document.querySelector("#toast")));
129158
app.Add('plus', new mvc.Button(document.querySelector("#plus")));
130159
app.Add('form', new mvc.Form(document.querySelector("#form")));
131-
app.Add('projects', new mvc.Provider(Project,'https://rpi4b.mutablelogic.com'));
160+
app.Add('projects', new mvc.Provider(Project, 'https://rpi4b.mutablelogic.com'));
161+
app.Add('table', new mvc.List(document.querySelector("#table"), "_template"));
132162

133163
// Show toast when button pressed
134164
app.plus.addEventListener('mvc.button.click', (sender, target) => {
135-
app.form.replace("._range",'');
136-
app.form.show({
165+
app.form.replace("._range", '');
166+
app.form.show({
137167
name: 'default',
138168
radio: 'option2',
139169
range: '0',
@@ -157,8 +187,31 @@ <h5 class="modal-title">Create New Project</h5>
157187
}
158188
});
159189

160-
// Request projects
161-
app.projects.request('/api/project/');
190+
// Set active row
191+
app.table.addEventListener('mvc.list.click', (sender, target, key) => {
192+
app.table.setClassForKey(key, 'table-active');
193+
});
194+
195+
// Projects
196+
app.projects.addEventListener('mvc.provider.error', (sender, error) => {
197+
app.toast.show(error);
198+
});
199+
app.projects.addEventListener('mvc.provider.added', (sender, project) => {
200+
app.table.set(project, project.key).replace('._name', project.$json);
201+
});
202+
app.projects.addEventListener('mvc.provider.changed', (sender, project) => {
203+
app.table.set(project, project.key).replace('._name', project.$json);
204+
});
205+
app.projects.addEventListener('mvc.provider.deleted', (sender, project) => {
206+
app.table.deleteForKey(project.key);
207+
});
208+
app.projects.addEventListener('mvc.provider.completed', (sender, changed) => {
209+
// Resort table if changed
210+
console.log("Projects loaded, changed=", changed);
211+
});
212+
213+
// Request projects every 30 secs
214+
app.projects.request('/api/project/', null, null, 30 * 1000);
162215

163216
});
164217
</script>

js/controller.js

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import { Tooltip } from 'bootstrap';
44
import View from './view';
55
import Provider from './provider';
6+
import CopyPaste from './copypaste';
67

78
export default class Controller {
89
constructor() {
@@ -14,6 +15,17 @@ export default class Controller {
1415
// eslint-disable-next-line no-new
1516
new Tooltip(node);
1617
});
18+
19+
// Set up copypaste
20+
document.querySelectorAll('.mvc-copypaste').forEach((node) => {
21+
const copypaste = new CopyPaste(node);
22+
copypaste.addEventListener('mvc.copypaste.click', (sender, target) => {
23+
copypaste.clipboard = target.innerText;
24+
});
25+
copypaste.addEventListener('mvc.copypaste.change', (sender) => {
26+
console.log('copied');
27+
});
28+
});
1729
}
1830

1931
Add(key, object) {
@@ -35,7 +47,11 @@ export default class Controller {
3547
});
3648
}
3749

38-
static New() {
39-
return new Controller();
50+
static New(constructor) {
51+
const C = constructor || Controller;
52+
if (C.prototype instanceof Controller) {
53+
return new C();
54+
}
55+
throw new Error(`Controller: Class ${C.name} is not a controller`);
4056
}
4157
}

js/index.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import Provider from './provider';
77

88
// Views
99
import View from './view';
10-
import ListView from './listview';
10+
import List from './list';
1111
import Toast from './toast';
1212
import Nav from './nav';
1313
import Button from './button';
@@ -18,11 +18,14 @@ import Error from './error';
1818
import Emitter from './events';
1919
import './string';
2020

21-
// CSS
21+
// CSS and fonts
2222
import 'bootstrap/dist/css/bootstrap.min.css';
23+
import 'bootstrap-icons/font/bootstrap-icons.css';
24+
import 'bootstrap-icons/font/fonts/bootstrap-icons.woff';
25+
import 'bootstrap-icons/font/fonts/bootstrap-icons.woff2';
2326
import '../css/style.css';
2427

2528
// Exports
2629
export {
27-
Model, View, Controller, Provider, Error, Emitter, ListView, Nav, Toast, Button, Form,
30+
Model, View, Controller, Provider, Error, Emitter, List, Nav, Toast, Button, Form,
2831
};

js/listview.js

Lines changed: 0 additions & 98 deletions
This file was deleted.

0 commit comments

Comments
 (0)