master
Harald Wolff 2019-05-14 15:23:14 +02:00
parent 29523c6f07
commit 5f45ea1220
10 changed files with 547 additions and 114 deletions

26
README.md 100644
View File

@ -0,0 +1,26 @@
# Type Definition Prototype
{
name: "string",
render: function(v){ return v; }
editor: function(){
// return a sky.editor
}
}
# Object Descriptor
{
fields: [
{ name: "abc", type: null, label: "Feld ABC" },
{ name: "def", type: "int", label: "Feld DEF" }
],
}

View File

@ -5,14 +5,15 @@
<title>Sky.JS</title>
<link href="style.css" rel="stylesheet" />
<link href="sky.base.css" rel="stylesheet" />
<link href="sky.tables.css" rel="stylesheet" />
<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript" src="sky.base.js"></script>
<script type="text/javascript" src="sky.tables.js"></script>
<script type="text/javascript" src="sky.controls.js"></script>
<script type="text/javascript" src="sky.types.js"></script>
<script type="text/javascript" src="sky.form.js"></script>
<script type="text/javascript" src="sky.dhcp.js"></script>
<script type="text/javascript" src="sky.tables.js"></script>
</head>
<body>
<script type="text/javascript">
@ -27,6 +28,9 @@
</div>
<div id="page">
<div id="content">
<h1>Types</h1>
<div id="Types"></div>
<h1>Table Demo</h1>
<table id="tableDemo" style="width: 95%;"></table>
</div>
@ -41,6 +45,15 @@
</div>
<script type="text/javascript">
var demoDescriptor = {
fields: [
{ name: "Name", type: null },
{ name: "Age", type: "int", label: "Alter" },
{ name: "Comment", type: null, label: "Anmerkungen" },
{ name: "IP", type: "ipv4" },
]
}
var demoObjects = [
{
Name: "First Demo Item",
@ -62,15 +75,23 @@
},
];
SKY
.form(demoDescriptor, demoObjects[0])
.appendTo( $("#Types"));
$("#tableDemo").skyTable( {
rows: demoObjects,
select: "multi",
columns: [
{ key: "Name", label: "Name", type: "string" },
{ key: "Age", label: "Alter", type: "int" },
{ key: "Comment", label: "Bemerkungen", type: "string" },
{ key: "IP", label: "IP", type: "IPv4" },
],
})
.on("dblclick", function(e){
alert("Editor may open for " + JSON.stringify(e.row));
});

24
sky.base.css 100644
View File

@ -0,0 +1,24 @@
input.changed {
background-color: #9cdaf5;
}
input:invalid {
border-color: red;
background-color: #E0C0C0;
}
fieldset {
display: inline-grid;
grid-template-columns: auto auto;
}
fieldset > * {
align-self: center;
margin-left: 6px;
margin-right: 6px;
margin-top: 4px;
margin-bottom: 2px;
}

View File

@ -12,13 +12,36 @@
var refreshList = [];
var refreshCounter = 0;
function SkyAPI(){
this.JQuery = {};
class SKYBase
{
on( evName, h ){
if (!self[evName])
self[evName] = [];
self[evName].push(h);
return this;
}
off( evName ){
self[evName] = []
return this;
}
fire( evName, p ){
if (self[evName])
self[evName].forEach( function(h){ h(p); } );
return this;
}
}
function SkyAPI(){
this.options = function(o){
options = Object.assign(options, o);
}
/* Refresh API */
this.refresh = function( name, interval, f){
if (!interval)
{
@ -84,6 +107,37 @@
return this;
}
/* Types API */
var types = {}
var defaultType = null;
this.type = function(name,type){
switch (arguments.length){
case 0:
return types;
case 1:
if ((name == null) || (!types[name]))
return defaultType;
return types[name];
case 2:
if (type)
if (name != null)
types[name] = type;
else
defaultType = type;
else
if (name != null)
delete types[name];
}
}
/* Final construction */
this.fn = {};
this.prototypes = {}
this.prototypes.SKYBase = SKYBase;
this.interval( 100 );
return this;

View File

@ -1,6 +1,74 @@

(function($){
(function(SKY){
class SKYControl extends SKY.prototypes.SKYBase {
constructor(typeName){
super();
this.typeName = typeName;
}
getIdentity(o){
return null;
}
render(o){
return o.toString();
}
editor(){
return null;
}
createSelector(){
return this.createEditor();
}
}
SKY.prototypes.SKYControl = SKYControl;
}(SKY));
(function(SKY){
class StringEditor extends SKY.prototypes.SKYEditor{
constructor(){
this.html(
$("<input>")
.attr("type","text")
.data("sky-editor", this)
.addClass("skyeditor skyeditor-string")
.on("change", function(e){
$(this).data("sky-editor").changed(true);
})
);
}
value(val){
if (arguments.length)
{
this.html().val( val );
this.changed(false);
return this;
}
return this.html().val();
}
}
class StringType extends SKY.prototypes.SKYControl {
constructor(){
super("string")
}
createEditor(){
return new StringEditor();
}
}
new StringType();
}(SKY));
(function($){
$.extend($, { sky: {} } );
$.extend($.sky, { controls: {} });

0
sky.dhcp.js 100755 → 100644
View File

View File

@ -1,4 +1,52 @@

(function(SKY){
SKY.form = function(descriptor, o){
return new function(){
this.appendTo = function(parent){ this.fieldset.appendTo(parent); return this; }
this.assign = function(o){
for (var n in this.descriptor.fields)
{
var fieldDesc = this.descriptor.fields[n];
var editor = this.editors[fieldDesc.name];
if (editor)
{
editor.value( o[fieldDesc.name] );
}
}
return this;
}
this.descriptor = descriptor;
this.editors = {}
this.fieldset = $("<fieldset></fieldset>");
for (var n in descriptor.fields){
var fieldDesc = descriptor.fields[n];
var skyType = SKY.type(fieldDesc.type);
var label = $("<label></label>");
var editor = skyType.editor();
label
.text( fieldDesc.label ? fieldDesc.label : fieldDesc.name )
.appendTo(this.fieldset);
editor
.id( fieldDesc.name )
.html().appendTo(this.fieldset);
this.editors[fieldDesc.name] = editor;
}
if (o)
this.assign(o);
};
}
}(SKY));
(function($){
function log(o){
console.log(o);

View File

@ -6,8 +6,147 @@
columns: [],
pagification: {
rows: 25,
}
},
select: null,
};
var defaultColumn = {
type: "string",
};
class HTML {
constructor(skyTable, table){
this.skyTable = skyTable;
this.table = table;
this.head = $("<thead></thead>").appendTo(table);
this.body = $("<tbody></tbody>").appendTo(table);
this.footer = $("<tfooter></tfooter>").appendTo(table);
this.rowCache = [];
this.usedRows = {};
}
createRow(){
var self = this;
var row = $("<tr></tr>")
.addClass("skytable skytable-row")
.on("click", function(){
self.skyTable.fireRowClick($(this));
})
.on("dblclick", function(){
self.skyTable.fireRowDblClick($(this));
});
for (var n=0;n<this.skyTable.columns.length;n++){
$("<td></td>")
.addClass("skytable skytable-cell")
.appendTo(row);
}
return row.get(0);
}
attachDataRow(iRow){
if (this.rowCache.length == 0)
this.rowCache.push(this.createRow());
var row = this.skyTable.data.rows[iRow];
var htmlRow = $(this.rowCache.pop());
htmlRow.data( "data-row", row );
htmlRow.data( "data-row-index", iRow );
var cells = $("td", htmlRow);
for (var n=0;n<this.skyTable.columns.length;n++){
$(cells[n])
.text( this.skyTable.columns[n].type.render( row[this.skyTable.columns[n].key] ) );
}
htmlRow.appendTo(this.body);
this.usedRows[iRow] = htmlRow;
}
detachDataRow(iRow){
if (this.usedRows[iRow])
{
$(this.usedRows[iRow]).detach();
this.rowCache.push(this.usedRows[iRow]);
}
}
get(iRow){
return this.usedRows[iRow];
}
empty(){
for (var iRow in this.usedRows){
var htmlRow = me.html.usedRows[iRow];
$(htmlRow).detach();
this.rowCache.push(htmlRow);
}
this.usedRows = {};
}
initializeHeader(){
this.columnHeader = $("<tr></tr>")
.addClass("skytable skytable-head")
.appendTo(this.head);
for (var n=0;n<this.skyTable.columns.length;n++){
$("<td></td>")
.text(this.skyTable.columns[n].label)
.addClass("skytable skytable-head")
.appendTo(this.columnHeader);
}
}
}
class DATA {
constructor(skyTable){
this.skyTable = skyTable;
this.rows= skyTable.options.rows;
this.firstrow = 0;
this.selectedRows = [];
}
getLastRow(){
var lastRow = this.firstrow + this.skyTable.options.pagification.rows;
if (lastRow > this.rows.length)
lastRow = this.rows.length;
return lastRow;
}
deselect(iRow){
var si = this.selectedRows.indexOf(iRow);
if (si != -1)
{
this.selectedRows.splice(si,1);
var htmlRow = this.skyTable.html.get(iRow);
if (htmlRow)
$(htmlRow).removeClass("selected");
this.skyTable.fire("deselect", { index: iRow, row: this.rows[iRow] } );
}
}
select(iRow){
if (!this.selectedRows.includes(iRow)){
this.selectedRows.push(iRow);
var htmlRow = this.skyTable.html.get(iRow);
if (htmlRow)
$(htmlRow).addClass("selected");
this.skyTable.fire("select", { index: iRow, row: this.rows[iRow] } );
}
}
toggleSelect(iRow){
if (this.skyTable.options.select == "single")
{
var doSelection = (!this.selectedRows.includes(iRow));
while (this.selectedRows.length)
this.deselect(this.selectedRows[0]);
if (doSelection)
this.select(iRow);
} else if (this.skyTable.options.select == "multi")
{
if (!this.selectedRows.includes(iRow))
this.select(iRow);
else
this.deselect(iRow);
}
}
}
$.fn.skyTable = function(opt){
if (this.length != 1)
@ -27,116 +166,63 @@
return skyTable;
}
var options = Object.assign( {}, defaultOptions, opt );
class SkyTable extends SKY.prototypes.SKYBase{
function SkyTable(t){
var me = this;
constructor(t){
super();
var me = this;
t = $(t);
t .data( "sky.skyTable", me)
.addClass("skytable");
this.options = Object.assign( {}, defaultOptions, opt );
this.columns = []
me.html = {
table: t,
head: $("<thead></thead>").appendTo(t),
body: $("<tbody></tbody>").appendTo(t),
footer: $("<tfooter></tfooter>").appendTo(t),
t = $(t);
t .data( "sky.skyTable", this)
.addClass("skytable");
rowCache: [],
usedRows: [],
this.html = new HTML(this, t);
this.data = new DATA(this);
createRow: function(){
var row = $("<tr></tr>")
.addClass("skytable skytable-row")
.on("click", function(){
$(this).toggleClass("selected");
});
for (var key in this.options.columns){
var column = this.options.columns[key];
var skyColumn = Object.assign( {}, defaultColumn, column );
skyColumn.type = SKY.controls.getControl(skyColumn.type);
this.columns.push( skyColumn );
}
for (var n=0;n<options.columns.length;n++){
$("<td></td>")
.addClass("skytable skytable-cell")
.appendTo(row);
}
return row;
},
this.html.initializeHeader();
this.refresh();
}
attachDataRow: function(dri){
if (me.html.rowCache.length == 0)
me.html.rowCache.push(me.html.createRow());
var drow = me.data.rows[dri];
var htmlRow = $(me.html.rowCache.pop());
htmlRow.data( "data-row", drow );
htmlRow.data( "data-row-index", dri );
var cells = $("td", htmlRow);
for (var n=0;n<options.columns.length;n++){
$(cells[n])
.text(drow[options.columns[n].key]);
}
htmlRow.appendTo(me.html.body);
},
initializeHeader: function(){
me.html.columnHeader = $("<tr></tr>")
.addClass("skytable skytable-head")
.appendTo(me.html.head);
for (var n=0;n<options.columns.length;n++){
$("<td></td>")
.text(options.columns[n].label)
.addClass("skytable skytable-head")
.appendTo(me.html.columnHeader);
}
},
empty: function(){
me.html.usedRows.forEach( function(htmlRow){
$(htmlRow).detach();
rowCache.push(htmlRow);
});
},
};
me.data = {
rows: options.rows,
firstrow: 0,
getLastRow: function(){
var lastRow = me.data.firstrow + options.pagification.rows;
if (lastRow > me.data.rows.length)
lastRow = me.data.rows.length;
return lastRow;
},
};
me.reset = function(){
reset(){
me.html.empty();
}
me.rows = function(rows){
rows(rows){
if (arguments.length == 0)
return me.currentRows;
me.empty();
me.reset();
}
me.refresh = function(){
me.html.empty();
refresh(){
this.html.empty();
var lastRow = me.data.getLastRow();
for (var n = me.data.firstrow;n < lastRow; n++){
me.html.attachDataRow( n );
var lastRow = this.data.getLastRow();
for (var n = this.data.firstrow;n < lastRow; n++){
this.html.attachDataRow( n );
}
return this;
}
fireRowClick(row){
if (this.options.select)
this.data.toggleSelect( row.data("data-row-index") );
else
this.fire( "click", { index: row.data("data-row-index") , row: row.data("data-row") });
}
fireRowDblClick(row){
this.fire( "dblclick", { index: row.data("data-row-index") , row: row.data("data-row") });
}
me.html.initializeHeader();
me.refresh();
}
return new SkyTable(self);

119
sky.types.js 100644
View File

@ -0,0 +1,119 @@
(function(SKY){
class SKYEditor{
constructor(placeholder,pattern){
this.html($('<input type="text">'));
if (pattern)
this._html.attr("pattern", pattern);
if (placeholder)
this._html.attr("placeholder", placeholder);
this._html.on("input", ()=>this.changed( this._html.data("value") != this._html.val() ) );
this._html.data("value", null);
}
html(html){
if (arguments.length == 1)
{
this._html = $(html);
return this;
}
return this._html;
}
id(id){
this.html().attr("id", id);
return this;
}
value(value){
if (arguments.length)
{
this._html
.val(value)
.data("value", value);
return this;
}
return this._html.val();
}
changed(changed){
if (arguments.length)
{
this._changed = (changed) ? true : false;
if (this._changed)
this.html().addClass("changed");
else
this.html().removeClass("changed");
return this;
}
return this._changed;
}
valid(){
return this._html[0].checkValidity();
}
}
SKY.prototypes.SKYEditor = SKYEditor;
class SKYIntEditor extends SKYEditor {
constructor(){
super();
this._html.attr("type","number");
}
}
class SKYIPv4Editor extends SKYEditor {
constructor(){
super("ipv4");
this.html()
.attr("placeholder", "000.000.000.000")
.attr("pattern", "^[0-9]([0-9]){0,2}\.[0-9]([0-9]){0,2}\.[0-9]([0-9]){0,2}\.[0-9]([0-9]){0,2}");
}
}
class SKYType {
constructor(name){
SKY.type(name,Object.getPrototypeOf(this));
}
editor(){
return new SKYEditor();
}
render(value){
return value;
}
}
class SKYIntType extends SKYType
{
constructor(){
super("int");
}
editor(){
return new SKYIntEditor();
}
}
class SKYIPv4Type extends SKYType
{
constructor(){
super("ipv4");
}
editor(){
return new SKYEditor("000.000.000.000","^[0-9]([0-9]){0,2}\.[0-9]([0-9]){0,2}\.[0-9]([0-9]){0,2}\.[0-9]([0-9]){0,2}");
}
}
new SKYType(null);
new SKYIntType();
new SKYIPv4Type();
}(SKY));

View File

@ -21,7 +21,6 @@ div#body {
}
/*!
div {
margin: 0px;
@ -254,19 +253,7 @@ button {
}
fieldset {
display: inline-grid;
grid-template-columns: auto auto;
}
fieldset > * {
align-self: center;
margin-left: 6px;
margin-right: 6px;
margin-top: 4px;
margin-bottom: 2px;
}
.popup {