unclean SPARC

This commit is contained in:
STEINNI
2025-08-27 07:03:09 +00:00
commit f308460931
430 changed files with 54426 additions and 0 deletions
+80
View File
@@ -0,0 +1,80 @@
<style>
.chalkboard > header { background: url('/app/assets/images/cards/chalkboard.jpg'); }
.chalkboard .toolbox {
text-align: center;
}
.chalkboard .board .dummy {
display: block;
height: 0;
}
.chalkboard canvas {
width: 100%;
height: 400px;
cursor:default;
}
.chalkboard canvas.drawing {
cursor:crosshair;
}
.chalkboard .toolbox .color-sample {
display: inline-grid;
width: 20px;
height: 20px;
border: 1px solid black !important;
margin: 1px !important;
}
.chalkboard .toolbox .pen-sample {
display: inline-grid;
width: 20px;
height: 20px;
align-content: center;
justify-content: center;
border: 1px solid black !important;
margin: 1px !important;
}
.chalkboard .toolbox span.selected {
border-color: var(--eicui-base-color-accessible-focus) !important;
box-shadow: inset 0 0 0 1px var(--eicui-base-color-accessible-focus),inset 0 0 0 2px var(--eicui-base-color-grey-5);
transition: border-color .15s ease-in-out,box-shadow .15s ease-in-out;
}
.chalkboard .board .users {
width: fit-content;
padding: 20px 0;
}
</style>
<article eiccard media class="chalkboard">
<header>
<h1>Magic Chalkboard</h1>
<h2>Collaborative artworks</h2>
</header>
<section>
<div class="cols-2 left top">
<div class="toolbox">
<input eicinput type="hidden" name="color" value="white" />
<input eicinput type="hidden" name="width" value="2" />
<div class="colors">
<span class="color-sample selected" data-id="white" data-value="rgba(255,255,255,1)" style="background:rgba(255,255,255,1)"></span>
<span class="color-sample" data-id="blue" data-value="rgba(0, 42, 255, 1)" style="background:rgba(0, 42, 255, 1)"></span>
<span class="color-sample" data-id="red" data-value="rgba(255, 0, 0, 1)" style="background:rgba(255, 0, 0, 1)"></span>
<span class="color-sample" data-id="yellow" data-value="rgba(255, 247, 6, 1)" style="background:rgba(255, 247, 6, 1)"></span>
<span class="color-sample" data-id="green" data-value="rgba(54, 255, 8, 1)" style="background:rgba(54, 255, 8, 1)"></span>
</div>
<hr/>
<div class="pens">
<span class="pen-sample icon-big-bullet selected" xxsmall data-value="2"></span>
<span class="pen-sample icon-big-bullet" xsmall data-value="4"></span>
<span class="pen-sample icon-big-bullet" small data-value="6"></span>
</div>
<hr/>
<button class="clear-board" eicbutton icon="icon-bin" xsmall danger></button>
<button class="dl-board" eicbutton icon="icon-download" xsmall info></button>
</div>
<div class="board">
<span class="dummy">*</span>
<canvas></canvas>
<div class="users"></div>
</div>
</div>
</section>
</article>
+318
View File
@@ -0,0 +1,318 @@
/**
* Magic Chalkboard demo app
*
* A simple app to share an editable canvas between bus users.
* Demonstrates :
* - subscription to a custom channel
* - burst event send/receive of custom event types
* - lightspeed response time of events broadcasting
* - accuracy and reliability of event queuing
* - implementation of app design with bus connected/disconnected.
*
* @author Michael Fallise
* @version 1.0
*/
class ChalkboardView extends EICDomContent {
options = {
background: 'rgba(0,0,0,1)',
busChannel: 'collaborative:chalkboard'
}
DOMContentLoaded() {
let components = ui.eicfy(this.el);
this.useBus = false;
this.busUsers = [];
this.toolbox = new Form(this.find('.toolbox'));
let colors = this.findAll('.color-sample');
for(let color of colors) color.addEventListener('click', this.onColorChange.bind(this));
let pens = this.findAll('.pen-sample');
for(let pen of pens) pen.addEventListener('click', this.onPenChange.bind(this));
let dl = components.find(item => item.el.classList.contains('dl-board'));
dl.addEventListener('click', this.onBoardDownload.bind(this));
let clear = components.find(item => item.el.classList.contains('clear-board'));
clear.addEventListener('click', this.onBoardClear.bind(this));
this.board = this.find('canvas');
this.board.style.background = this.options.background;
this.ctx = this.board.getContext("2d");
this.ctx.lineCap = 'round';
this.drawing = this.eraser = false;
this.mouseCurrent = { x: 0, y: 0 };
this.mousePrev = { x: 0, y: 0 };
// referencing computed event handlers
this.mouseDownHandler = this.onChalkStart.bind(this);
this.mouseMoveHandler = this.onChalkMove.bind(this);
this.mouseUpHandler = this.onChalkEnd.bind(this);
this.busDrawHandler = this.onBusDraw.bind(this);
this.busClearHandler = this.onBusClear.bind(this);
this.busPingHandler = this.onBusPing.bind(this);
this.busJoinHandler = this.onBusJoin.bind(this);
this.busLeaveHandler = this.onBusLeave.bind(this);
this.setBrush();
this.setBoardSize();
this.clear();
this.initListeners();
}
DOMContentRemoved() { this.closeListeners(); }
DOMContentResized() {
let data = this.board.toDataURL('image/png');
this.setBoardSize();
let img = new Image;
let self = this
img.onload = function() { self.ctx.drawImage(img, 0, 0); };
img.src = data;
}
setBoardSize() {
let rect = this.board.getBoundingClientRect()
this.board.width = rect.width;
this.board.height = rect.height;
}
/* Nike to Mike : As planned, made higher-level addBusListener & removeBusListener
* Changes : Includes channel filtering (important to avoid chan injections by script-kiddies)
*
* You can replace old-style :
* app.events.addEvent('MessageBus.XXX', handler, scope)
* app.events.removeEvent('MessageBus.XXX', handler, scope)
* => handler receives pure JS event, and probably uses e.detail.payload
*
* by new-style:
* app.MessageBus.addBusListener('XXX', [this.busChannel], handler, scope)
* app.MessageBus.removeBusListener('XXX', handler, scope)
* => handler receives (realChan, payload, sender)
*
*/
initListeners() {
this.board.addEventListener('mousedown', this.mouseDownHandler);
this.board.addEventListener('mousemove', this.mouseMoveHandler);
this.board.addEventListener('mouseup', this.mouseUpHandler);
// disabling context menu on canvas in order to use right button for eraser
this.board.oncontextmenu = function() { return false;}
if(app.MessageBus.connected) {
console.log("USING BUS")
app.MessageBus.subscribe([this.options.busChannel])
.then( payload => {
app.MessageBus.addBusListener('board_draw', ['collaborative:chalkboard'], this.busDrawHandler, 'chalkboard');
app.MessageBus.addBusListener('board_clear', ['collaborative:chalkboard'], this.busClearHandler, 'chalkboard');
app.MessageBus.addBusListener('board_ping', ['collaborative:chalkboard'], this.busPingHandler, 'chalkboard');
app.MessageBus.addBusListener('board_join', ['collaborative:chalkboard'], this.busJoinHandler, 'chalkboard');
app.MessageBus.addBusListener('board_leave', ['collaborative:chalkboard'], this.busLeaveHandler, 'chalkboard');
this.useBus = true;
this.pingUsers();
} );
}
}
closeListeners() {
if(this.useBus) {
app.MessageBus.removeBusListener('board_draw', this.busDrawHandler, 'chalkboard');
app.MessageBus.removeBusListener('board_clear', this.busClearHandler, 'chalkboard');
app.MessageBus.removeBusListener('board_join', this.busJoinHandler, 'chalkboard');
app.MessageBus.removeBusListener('board_ping', this.busPingHandler, 'chalkboard');
app.MessageBus.removeBusListener('board_leave', this.busLeaveHandler, 'chalkboard');
this.leaveApp();
this.useBus = false;
}
}
setBrush() { this.brush = this.toolbox.value; }
draw(brush, from, to) {
this.ctx.fillStyle = brush.color;
this.ctx.strokeStyle = brush.color;
this.ctx.lineWidth = brush.width;
this.ctx.beginPath();
this.ctx.moveTo(from.x, from.y);
this.ctx.lineTo(to.x, to.y);
this.ctx.stroke();
}
clear() {
this.ctx.fillStyle = this.options.background;
this.ctx.fillRect(0, 0, this.board.width, this.board.height);
this.ctx.fillStyle = this.brush.color;
}
onChalkStart(event) {
this.drawing = true;
this.eraser = event.button == 2,
this.mousePrev.x = this.mouseCurrent.x;
this.mousePrev.y = this.mouseCurrent.y;
this.setBrush();
}
onChalkMove(event) {
let rect = event.target.getBoundingClientRect();
this.mouseCurrent.x = event.pageX - rect.left;
this.mouseCurrent.y = event.pageY - rect.top;
if(this.drawing) {
this.board.classList.add('drawing');
let brush = this.eraser ? { color: this.options.background, width: 20 }: this.brush;
if(this.useBus) {
app.MessageBus.sendEvent(this.options.busChannel,'board_draw', {
uid: app.User.identity.uuid,
brush: brush,
from: this.mousePrev,
to: this.mouseCurrent,
});
} else {
this.draw(brush, this.mousePrev, this.mouseCurrent);
}
this.mousePrev.x = this.mouseCurrent.x;
this.mousePrev.y = this.mouseCurrent.y;
}
}
onChalkEnd(event) {
this.drawing = this.eraser = false;
this.board.classList.remove('drawing');
}
onColorChange(event) {
event.stopPropagation();
event.preventDefault();
this.find('.color-sample.selected').classList.remove('selected');
let color = event.currentTarget;
color.classList.add('selected');
this.find('input[name="color"]').value = color.dataset.value;
}
onPenChange(event) {
event.stopPropagation();
event.preventDefault();
this.find('.pen-sample.selected').classList.remove('selected');
let pen = event.currentTarget;
pen.classList.add('selected');
this.find('input[name="width"]').value = pen.dataset.value;
}
onBusPing(event) {
let payload = {
uid: app.User.identity.uuid,
name: app.User.identity.firstname + ' ' + app.User.identity.lastname
}
app.MessageBus.sendEvent(this.options.busChannel,'board_join', payload);
}
joinApp() {
let payload = {
uid: app.User.identity.uuid,
name: app.User.identity.firstname + ' ' + app.User.identity.lastname
}
app.MessageBus.sendEvent(this.options.busChannel,'board_join', payload);
}
leaveApp() { app.MessageBus.sendEvent(this.options.busChannel,'board_leave'); }
pingUsers() {
this.busUsers = [];
let container = this.find('.users');
container.innerHTML = '';
app.MessageBus.sendEvent(this.options.busChannel,'board_ping');
}
refreshUsers() {
let container = this.find('.users');
console.log('', this.busUsers)
for(let user of this.busUsers) {
if(!user.tag) {
let tag = new Chip(null, {
label: user.name,
icon: 'icon-edit',
size: 'small',
severity: 'secondary'
});
container.append(tag.el)
user.tag = tag;
}
}
}
onBusDraw(chan, payload, sender) {
/*
for(let item of this.busUsers) {
item.tag.severity = 'secondary';
}
let user = this.busUsers.find(item => item.uid == payload.uid);
user.tag.severity = 'primary';
*/
this.draw(payload.brush, payload.from, payload.to);
}
onBusClear(chan, payload, sender) { this.clear(); }
onBusJoin(chan, payload, sender) {
let user = payload;
let index = this.busUsers.findIndex(item => item.uid == user.uid);
console.log('index', index, this.busUsers)
console.log('user', user)
if(index == -1) {
this.busUsers.push(user);
this.refreshUsers();
}
}
onBusLeave(chan, payload, sender) { this.pingUsers(); }
onBoardDownload(event) {
event.stopPropagation();
event.preventDefault();
let data = this.board.toDataURL('image/png');
let link = document.createElement('a');
link.download = 'chalkboard.png';
link.href = data;
link.click();
}
onBoardClear(event) {
event.stopPropagation();
event.preventDefault();
if(this.useBus) {
app.MessageBus.sendEvent(this.options.busChannel,'board_clear', {});
} else {
this.clear();
}
}
}
app.registerClass('ChalkboardView',ChalkboardView);
@@ -0,0 +1,73 @@
<style>
.component-lab [eicstatechart] {
height: 320px;
}
.component-lab { }
.component-lab textarea {
height: 240px;
font-family: monospace;
}
.component-lab { }
</style>
<article eiccard class="component-lab">
<header>
<h1>Components Forge</h1>
<h2>Current: Relation Map</h2>
</header>
<section>
<div eicstatechart class="relation-map"></div>
<div class="cols-2">
<div>
<label xsmall>config</label>
<textarea eictextarea name="config">
{
"orientation": "linear",
"resizable": true,
"allowDrag": true,
"entity": {
"width": 180,
"height": 80,
"gap": 40
}
}
</textarea>
</div>
<div>
<label xsmall>data</label>
<textarea eictextarea name="data">
{
"entities": [
{
"title": "Entity 1",
"severity": "info"
},
{
"title": "Entity 2",
"subtitle": "has an id value of 2",
"data": {
"id": 2,
"test": "some value"
}
},
{
"title": "Entity 3",
"subtitle": "has an id value of 3",
"badge": 42,
"data": {
"id": 3,
"test": "some value"
}
}
]
}
</textarea>
</div>
</div>
<div class="cols-1 right">
<button eicbutton xsmall primary class="button-update">update</button>
</div>
</section>
</article>
+37
View File
@@ -0,0 +1,37 @@
class ComponentLabView extends EICDomContent {
DOMContentLoaded() {
this.components = ui.eicfy(this.el);
this.tConfig = this.components.find(c => c.el.name == 'config');
this.tData = this.components.find(c => c.el.name == 'data');
this.btReset = this.components.find(c => c.el.classList.contains('button-update'));
this.reset(JSON.parse(this.tConfig.value), JSON.parse(this.tData.value));
this.btReset.addEventListener('click', this.onReset.bind(this));
}
onReset(event) {
event.stopPropagation();
event.preventDefault();
this.reset(JSON.parse(this.tConfig.value), JSON.parse(this.tData.value));
}
reset(config, data) {
this.map = new StateChart(this.find('.relation-map'), config)
this.map.data = data;
this.map.click = this.testBadge.bind(this)
}
testBadge(entity) {
entity.badge = 23
}
}
app.registerClass('ComponentLabView',ComponentLabView);
+212
View File
@@ -0,0 +1,212 @@
<style>
@import url('https://fonts.googleapis.com/css2?family=Fugaz+One&display=swap');
:root {
--smp-global-background: #dcd4bc;
--smp-global-color: #503333;
}
.sampler-app > header { background: url('/app/assets/images/cards/lab-sampler.jpg'); }
.sampler-app section {
border: none;
background: var(--smp-global-background);
box-sizing: border-box;
display: flex;
flex-direction: row;
}
.sampler-app .speaker {
color: black;
height: 340px;
min-width: 340px;
width: 340px;
border: 7px solid rgb(0 0 0 / 5%);
padding: 20px;
display: grid;
margin: 0 40px 0 0;
border-radius: 18px;
}
[device="tablet"] .sampler-app .speaker,
[device="mobile"] .sampler-app .speaker {
display: none !important;
}
.sampler-app .speaker .hole {
background-color: black;
border-radius: 50%;
width: 100%;
height: 100%;
grid-column: 1;
grid-row: 1;
}
.sampler-app .speaker .stripes {
color: black;
background-image: linear-gradient(0deg, var(--smp-global-background) 60%, black 1%, black 10%, #0000003b 25%);
background-size: 1px 23px;
width: 100%;
height: 100%;
grid-column: 1;
grid-row: 1;
}
.sampler-app .pads {
display: flex;
grid-gap: var(--eicui-base-spacing-l);
flex-flow: wrap;
}
.sampler-app .pads .pad {
display: grid;
grid-template-rows: auto min-content;
grid-template-columns: min-content auto;
grid-gap: 4px;
flex: 1;
min-width: 100px;
max-width: 140px;
}
.sampler-app .pads .pad kbd {
align-self: flex-end;
justify-self: center;
color: white;
background: var(--smp-global-color);
padding: 6px 11px;
border-radius: 5px;
font-size: 0.95rem;
text-transform: uppercase;
}
.sampler-app .pads .pad button {
width: 100%;
height: 100%;
border: 2px solid black;
grid-column: 1 / 3;
border-radius: 6px;
padding: 0;
box-shadow: 1px 4px 4px #0000007d;
min-height: 40px;
}
.sampler-app .pads .pad button.assigned:hover span {
border-color: orange !important;
}
.sampler-app .pads .pad button span {
display: block;
width: 100%;
height: 100%;
background: #404040;
border: 8px solid #59402c;
box-sizing: border-box;
}
.sampler-app .pads .pad button.assigned span { border: 3px solid #b77c4c; }
.sampler-app .pads .pad button.playing span { border: 3px solid #93f795; }
.sampler-app .pads .pad label {
color: #ffffffc4;
background: var(--smp-global-color);
padding: 8px 3px 8px 10px;
margin: 3px 0 0 0;
text-transform: uppercase;
font-family: 'Fugaz One', cursive;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
font-size: 0.75rem;
align-content: center;
}
.sampler-app footer {
background-color: rgba(0, 0, 0, 0.168);
grid-area: footer;
border-top: 4px solid #ffffff61;
}
</style>
<article eiccard media class="sampler-app">
<header>
<h1>CARMELOMATIC<sup>&reg;</sup></h1>
<h2>SAMPLER 3000</h2>
</header>
<section>
<div class="speaker">
<div class="hole"></div>
<div class="stripes"></div>
</div>
<!---->
<div class="pads">
<div class="pad">
<button accesskey="e"><span></span></button>
<kbd>e</kbd><label for="button"></label>
</div>
<div class="pad">
<button accesskey="r"><span></span></button>
<kbd>r</kbd><label for="button"></label>
</div>
<div class="pad">
<button accesskey="t"><span></span></button>
<kbd>t</kbd><label for="button"></label>
</div>
<div class="pad">
<button accesskey="y"><span></span></button>
<kbd>y</kbd><label for="button"></label>
</div>
<div class="pad">
<button accesskey="d"><span></span></button>
<kbd>d</kbd><label for="button"></label>
</div>
<div class="pad">
<button accesskey="f"><span></span></button>
<kbd>f</kbd><label for="button"></label>
</div>
<div class="pad">
<button accesskey="g"><span></span></button>
<kbd>g</kbd><label for="button"></label>
</div>
<div class="pad">
<button accesskey="h"><span></span></button>
<kbd>h</kbd><label for="button"></label>
</div>
<div class="pad">
<button accesskey="c"><span></span></button>
<kbd>c</kbd><label for="button"></label>
</div>
<div class="pad">
<button accesskey="v"><span></span></button>
<kbd>v</kbd><label for="button"></label>
</div>
<div class="pad">
<button accesskey="b"><span></span></button>
<kbd>b</kbd><label for="button"></label>
</div>
<div class="pad">
<button accesskey="n"><span></span></button>
<kbd>n</kbd><label for="button"></label>
</div>
<div class="pad">
<button accesskey="u"><span></span></button>
<kbd>u</kbd><label for="button"></label>
</div>
<div class="pad">
<button accesskey="i"><span></span></button>
<kbd>i</kbd><label for="button"></label>
</div>
<div class="pad">
<button accesskey="o"><span></span></button>
<kbd>o</kbd><label for="button"></label>
</div>
<div class="pad">
<button accesskey="p"><span></span></button>
<kbd>p</kbd><label for="button"></label>
</div>
<div class="pad">
<button accesskey="j"><span></span></button>
<kbd>j</kbd><label for="button"></label>
</div>
<div class="pad">
<button accesskey="k"><span></span></button>
<kbd>k</kbd><label for="button"></label>
</div>
<div class="pad">
<button accesskey="l"><span></span></button>
<kbd>l</kbd><label for="button"></label>
</div>
<div class="pad">
<button accesskey="m"><span></span></button>
<kbd>m</kbd><label for="button"></label>
</div>
</div>
</section>
</article>
+115
View File
@@ -0,0 +1,115 @@
class SamplerView extends EICDomContent {
// all mpeg preloading not in dependency anymore,
// but here, when you're really about to use then
sounds = [
{"name": "98.mp3","path": "/app/assets/sfx/sampler/", 'label': '98'},
{"name": "quenouilles.mp3","path": "/app/assets/sfx/sampler/", 'label': 'As-tu vu?'},
{"name": "celebrate.mp3","path": "/app/assets/sfx/sampler/", 'label': 'party'},
{"name": "paillettes.mp3","path": "/app/assets/sfx/sampler/", 'label': 'paillettes'},
{"name": "manu.mp3","path": "/app/assets/sfx/sampler/", 'label': 'Manu'},
{"name": "projet.mp3","path": "/app/assets/sfx/sampler/", 'label': 'Projet'},
{"name": "judgenot.mp3","path": "/app/assets/sfx/sampler/", 'label': 'Judge not!'},
{"name": "metaphore.mp3","path": "/app/assets/sfx/sampler/", 'label': 'Metaphore'},
{"name": "gamin.mp3","path": "/app/assets/sfx/sampler/", 'label': 'Gamin!'},
{"name": "jcvd.mp3","path": "/app/assets/sfx/sampler/", 'label': '1+1=11'},
{"name": "balladur.mp3","path": "/app/assets/sfx/sampler/", 'label': 'Arretez!'},
{"name": "guingamp.mp3","path": "/app/assets/sfx/sampler/", 'label': 'En avant !'},
{"name": "phrases.mp3","path": "/app/assets/sfx/sampler/", 'label': 'Phrases...'},
{"name": "bourpif.mp3","path": "/app/assets/sfx/sampler/", 'label': 'Raoul'},
{"name": "fairplay.mp3","path": "/app/assets/sfx/sampler/", 'label': 'Fairplay'},
{"name": "neanderthal.mp3","path": "/app/assets/sfx/sampler/", 'label': 'Neanderthal'},
{"name": "hassancehef.mp3","path": "/app/assets/sfx/sampler/", 'label': 'C\'est possible !'}
];
mixer = null;
constructor() {
super();
}
DOMContentLoaded() {
this.pads = this.findAll('.pad');
this.init();
this.preloadSounds(this.sounds);
}
DOMContentRemoved() { window.removeEventListener('keyup',this.keyHandler); }
init() {
for(let i = 0; i < this.sounds.length; i++) {
let data = this.sounds[i];
this.pads[i].name = data.name;
this.pads[i].querySelector('label').innerText = data.label;
let button = this.pads[i].querySelector('button');
button.addEventListener('click', this.play.bind(this, data.name));
}
this.keyHandler = this.onKeyPressed.bind(this);
window.addEventListener('keyup', this.keyHandler);
}
preloadSounds(sndList){
for(let snd of sndList){
app.Assets.loadSound({
'id': snd.name,
'name': snd.name,
'path': snd.path
}).then(audioEl => {
audioEl.addEventListener("play", this.playBoy.bind(this));
audioEl.addEventListener("pause", this.pauseBoy.bind(this));
let pad, idx;
for([idx, pad] of this.pads.entries()){
if(pad.name==audioEl.getAttribute('aid')) {
pad.querySelector('button').classList.add('assigned');
break;
}
}
});
}
}
playBoy(event){
let aid = event.target.getAttribute('aid');
let pad, idx;
for([idx, pad] of this.pads.entries()){
if(pad.name==aid) {
pad.querySelector('button').classList.remove('assigned')
pad.querySelector('button').classList.add('playing');
break;
}
}
}
pauseBoy(event){
let aid = event.target.getAttribute('aid');
let pad, idx;
for([idx, pad] of this.pads.entries()){
if(pad.name==aid) {
pad.querySelector('button').classList.remove('playing')
pad.querySelector('button').classList.add('assigned');
break;
}
}
}
play(audioid, event) {
event.stopPropagation();
if(this.mixer) {
this.mixer.pause();
this.mixer.currentTime = 0;
}
this.mixer = app.Assets.Store.sfx[audioid];
this.mixer.play();
}
stop() {}
onKeyPressed(event) {
let btn = document.querySelector('button[accessKey="'+event.key.toLowerCase()+'"]');
if(btn) btn.click();
}
}
app.registerClass('SamplerView',SamplerView);
+46
View File
@@ -0,0 +1,46 @@
<article eiccard>
<header>
<h1>Form test</h1>
</header>
<section class="form">
<input type="hidden" data-path="pathAnd" name="name" value="done" />
<input type="hidden" name="nameOnly" value="done" />
<input type="hidden" data-path="pathonly" value="done" />
<input type="hidden" data-path="ignoredField" class="ignore" value="Mutafuka! your snooping to much" />
<input type="hidden" data-path="basearray[0]" value="a" />
<input type="hidden" data-path="basearray[1]" value="b" />
<input type="hidden" data-path="arrayOfObjects[0].value" data-type="number" value="100" />
<input type="hidden" data-path="arrayOfObjects[0].label" value="aa" />
<input type="hidden" data-path="arrayOfObjects[1].value" data-type="number" value="200.45" />
<input type="hidden" data-path="arrayOfObjects[1].label" value="bb" />
<input type="hidden" data-path="arrayOfObjects[2].value" data-type="number" value="300" />
<input type="hidden" data-path="arrayOfObjects[2].label" value="cc" />
<input type="hidden" data-path="boolean" data-type="boolean" value="true" />
<textarea data-path="justification.description" eictextarea maxlen="200"
hint="No more than 200 characters please."
placeholder="Please type some words..."></textarea>
<label>pick some values</label>
<select eicselect multiple data-path="justification.programme" placeholder="Please select a programme...">
<option value=""></option>
<option value="1">PRG1</option>
<option value="2">PRG2</option>
<option value="3">PRG3</option>
</select>
<input eiccheckbox type="checkbox" data-path="justification.independentExpert" label="You confirm that you have relied on independent external experts to perform the project review" value="yes" />
<input eiccheckbox type="checkbox" class="ignore" data-path="justification.compliance" label="You confirm that you have complied with all the conditions and requirements set out for Fast Track scheme" />
</section>
<section primary>
<label>JSON output</label>
<textarea eictextarea class="output"></textarea>
</section>
<footer>
<div class="cols-2 right">
<div></div>
<button eicbutton primary class="generate">output form</button>
</div>
</footer>
</article>
+15
View File
@@ -0,0 +1,15 @@
class TestView extends EICDomContent {
constructor() { super(); }
DOMContentLoaded() {
ui.eicfy(this.el)
let form = new Form(this.find('.form'));
let output = this.find('.output')
this.find('.generate').addEventListener('click', event => { output.value = JSON.stringify(form.value) });
}
}
app.registerClass('TestView',TestView);