Vn.Model v1
This commit is contained in:
parent
4d8bd4ad95
commit
fe68eb5ce0
|
@ -15,8 +15,8 @@ Hedera.Contact = new Class
|
||||||
,refreshCaptcha: function ()
|
,refreshCaptcha: function ()
|
||||||
{
|
{
|
||||||
params = {
|
params = {
|
||||||
'srv': 'rest:core/captcha',
|
srv: 'rest:core/captcha',
|
||||||
'stamp': new Date ().getTime ()
|
stamp: new Date ().getTime ()
|
||||||
};
|
};
|
||||||
this.$.captchaImg.src = '?'+ Vn.Url.makeUri (params);
|
this.$.captchaImg.src = '?'+ Vn.Url.makeUri (params);
|
||||||
}
|
}
|
||||||
|
|
|
@ -123,8 +123,12 @@ Connection.implement
|
||||||
{
|
{
|
||||||
var data = json[i].data;
|
var data = json[i].data;
|
||||||
var columns = json[i].columns;
|
var columns = json[i].columns;
|
||||||
|
var nCols = columns.length;
|
||||||
|
|
||||||
for (var j = 0; j < columns.length; j++)
|
var result = [];
|
||||||
|
var castFuncs = new Array (nCols);
|
||||||
|
|
||||||
|
for (var j = 0; j < nCols; j++)
|
||||||
{
|
{
|
||||||
var castFunc = null;
|
var castFunc = null;
|
||||||
|
|
||||||
|
@ -139,14 +143,29 @@ Connection.implement
|
||||||
|
|
||||||
if (castFunc !== null)
|
if (castFunc !== null)
|
||||||
{
|
{
|
||||||
|
castFuncs[j] = castFunc;
|
||||||
|
|
||||||
if (columns[j].def != null)
|
if (columns[j].def != null)
|
||||||
columns[j].def = castFunc (columns[j].def);
|
columns[j].def = castFunc (columns[j].def);
|
||||||
|
|
||||||
for (var k = 0; k < data.length; k++)
|
|
||||||
if (data[k][j] != null)
|
|
||||||
data[k][j] = castFunc (data[k][j]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (var j = 0; j < data.length; j++)
|
||||||
|
{
|
||||||
|
var row = data[j];
|
||||||
|
|
||||||
|
var object = {};
|
||||||
|
result.push (object);
|
||||||
|
|
||||||
|
for (var k = 0; k < nCols; k++)
|
||||||
|
{
|
||||||
|
var castFunc = castFuncs[k];
|
||||||
|
object[columns[k].name] =
|
||||||
|
castFunc ? castFunc (row[k]) : row[k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
json[i].data = result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (e)
|
catch (e)
|
||||||
|
|
703
js/db/model.js
703
js/db/model.js
File diff suppressed because it is too large
Load Diff
|
@ -101,7 +101,7 @@ module.exports = new Class
|
||||||
{
|
{
|
||||||
var row = this.fetchRow ();
|
var row = this.fetchRow ();
|
||||||
|
|
||||||
if (row instanceof Array && row.length > 0)
|
if (row instanceof Object && row.length > 0)
|
||||||
return row[0];
|
return row[0];
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -29,13 +29,12 @@ module.exports = new Class
|
||||||
/**
|
/**
|
||||||
* Gets a value from de result.
|
* Gets a value from de result.
|
||||||
*
|
*
|
||||||
* @param {string} columnName The column name
|
* @param {String} columnName The column name
|
||||||
* @return {Object} The cell value
|
* @return {Object} The cell value
|
||||||
*/
|
*/
|
||||||
,get: function (columnName)
|
,get: function (columnName)
|
||||||
{
|
{
|
||||||
var columnIndex = this.columnMap[columnName];
|
return this.data[this.row][columnName];
|
||||||
return this.data[this.row][columnIndex];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -48,7 +47,7 @@ module.exports = new Class
|
||||||
if (!this.next ())
|
if (!this.next ())
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
return this.getObject (this.row);
|
return this.data[this.row];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -59,14 +58,7 @@ module.exports = new Class
|
||||||
*/
|
*/
|
||||||
,getObject: function (rowIndex)
|
,getObject: function (rowIndex)
|
||||||
{
|
{
|
||||||
var row = this.data[rowIndex];
|
return this.data[rowIndex];
|
||||||
var cols = this.columns;
|
|
||||||
var object = {};
|
|
||||||
|
|
||||||
for (var i = 0; i < cols.length; i++)
|
|
||||||
object[cols[i].name] = row[i];
|
|
||||||
|
|
||||||
return object;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -231,6 +231,7 @@ textarea,
|
||||||
.input
|
.input
|
||||||
{
|
{
|
||||||
padding: 0 .2em;
|
padding: 0 .2em;
|
||||||
|
padding-bottom: 1px;
|
||||||
}
|
}
|
||||||
input[type=text],
|
input[type=text],
|
||||||
input[type=password],
|
input[type=password],
|
||||||
|
@ -253,7 +254,9 @@ input[type=number]:focus,
|
||||||
textarea:focus,
|
textarea:focus,
|
||||||
.input:focus
|
.input:focus
|
||||||
{
|
{
|
||||||
border-color: #333;
|
border-color: #666;
|
||||||
|
border-bottom-width: 2px;
|
||||||
|
padding-bottom: 0;
|
||||||
}
|
}
|
||||||
input[type=checkbox],
|
input[type=checkbox],
|
||||||
input[type=radio]
|
input[type=radio]
|
||||||
|
|
|
@ -96,10 +96,10 @@ module.exports = new Class
|
||||||
return td;
|
return td;
|
||||||
}
|
}
|
||||||
|
|
||||||
,updateColumnIndex: function (model)
|
,updateColumnName: function (model)
|
||||||
{
|
{
|
||||||
if (this.column)
|
if (this.columnIndex != -1)
|
||||||
this.columnIndex = model.getColumnIndex (this.column);
|
this.column = model.getColumnName (this.columnIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
,changed: function (tr, newValue)
|
,changed: function (tr, newValue)
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
|
|
||||||
|
var slide = require ('vn/transitions').slide;
|
||||||
|
|
||||||
module.exports = new Class
|
module.exports = new Class
|
||||||
({
|
({
|
||||||
Extends: Htk.Field
|
Extends: Htk.Field
|
||||||
|
@ -31,47 +33,44 @@ module.exports = new Class
|
||||||
var node = this.createRoot ('div');
|
var node = this.createRoot ('div');
|
||||||
node.className = 'htk-calendar';
|
node.className = 'htk-calendar';
|
||||||
|
|
||||||
|
var div = this.createElement ('div');
|
||||||
|
div.className = 'month';
|
||||||
|
node.appendChild (div);
|
||||||
|
|
||||||
|
var button = this.createElement ('div');
|
||||||
|
button.appendChild (this.createTextNode ('<'));
|
||||||
|
button.className = 'button previous';
|
||||||
|
button.addEventListener ('click', this.prevMonthClicked.bind (this));
|
||||||
|
div.appendChild (button);
|
||||||
|
|
||||||
|
var monthNode = this.createElement ('span');
|
||||||
|
div.appendChild (monthNode);
|
||||||
|
|
||||||
|
var space = this.createTextNode (' ');
|
||||||
|
div.appendChild (space);
|
||||||
|
|
||||||
|
var yearNode = this.createElement ('span');
|
||||||
|
div.appendChild (yearNode);
|
||||||
|
|
||||||
|
var button = this.createElement ('div');
|
||||||
|
button.appendChild (this.createTextNode ('>'));
|
||||||
|
button.className = 'button next';
|
||||||
|
button.addEventListener ('click', this.nextMonthClicked.bind (this));
|
||||||
|
div.appendChild (button);
|
||||||
|
|
||||||
|
var wrapper = this.createElement ('div');
|
||||||
|
wrapper.className = 'wrapper';
|
||||||
|
node.appendChild (wrapper);
|
||||||
|
|
||||||
var table = this.createElement ('table');
|
var table = this.createElement ('table');
|
||||||
this.node.appendChild (table);
|
wrapper.appendChild (table);
|
||||||
|
this.table = table;
|
||||||
var colgroup = this.createElement ('colgroup');
|
|
||||||
table.appendChild (colgroup);
|
|
||||||
|
|
||||||
for (var i = 0; i < len; i++)
|
|
||||||
colgroup.appendChild (this.createElement ('col'));
|
|
||||||
|
|
||||||
var thead = this.createElement ('thead');
|
var thead = this.createElement ('thead');
|
||||||
table.appendChild (thead);
|
table.appendChild (thead);
|
||||||
|
|
||||||
var tr = this.createElement ('tr');
|
var tr = this.createElement ('tr');
|
||||||
thead.appendChild (tr);
|
tr.className = 'wdays';
|
||||||
|
|
||||||
var th = this.createElement ('th');
|
|
||||||
th.appendChild (this.createTextNode ('<'));
|
|
||||||
th.className = 'button';
|
|
||||||
th.addEventListener ('click', this.prevMonthClicked.bind (this));
|
|
||||||
tr.appendChild (th);
|
|
||||||
|
|
||||||
var th = this.createElement ('th');
|
|
||||||
th.colSpan = 5;
|
|
||||||
tr.appendChild (th);
|
|
||||||
|
|
||||||
var monthNode = this.createElement ('span');
|
|
||||||
th.appendChild (monthNode);
|
|
||||||
|
|
||||||
var space = this.createTextNode (' ');
|
|
||||||
th.appendChild (space);
|
|
||||||
|
|
||||||
var yearNode = this.createElement ('span');
|
|
||||||
th.appendChild (yearNode);
|
|
||||||
|
|
||||||
var th = this.createElement ('th');
|
|
||||||
th.appendChild (this.createTextNode ('>'));
|
|
||||||
th.className = 'button';
|
|
||||||
th.addEventListener ('click', this.nextMonthClicked.bind (this));
|
|
||||||
tr.appendChild (th);
|
|
||||||
|
|
||||||
var tr = this.createElement ('tr');
|
|
||||||
thead.appendChild (tr);
|
thead.appendChild (tr);
|
||||||
|
|
||||||
for (var i = 1; i <= len; i++)
|
for (var i = 1; i <= len; i++)
|
||||||
|
@ -256,7 +255,7 @@ module.exports = new Class
|
||||||
this.year--;
|
this.year--;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.refresh ();
|
this.refreshSlide ('right');
|
||||||
}
|
}
|
||||||
|
|
||||||
,nextMonthClicked: function ()
|
,nextMonthClicked: function ()
|
||||||
|
@ -269,6 +268,12 @@ module.exports = new Class
|
||||||
this.year++;
|
this.year++;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.refresh ();
|
this.refreshSlide ('left');
|
||||||
|
}
|
||||||
|
|
||||||
|
,refreshSlide: function (way)
|
||||||
|
{
|
||||||
|
var cb = this.refresh.bind (this);
|
||||||
|
slide (this.table, way, cb);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -106,15 +106,15 @@ module.exports = new Class
|
||||||
this.showNoRecordsFound ();
|
this.showNoRecordsFound ();
|
||||||
}
|
}
|
||||||
|
|
||||||
,onRowInsert: function (model, row)
|
,onRowInsert: function ()
|
||||||
{
|
{
|
||||||
this.buildRow (1);
|
this.buildRow (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
,renderCell: function (row, column, tr)
|
,renderCell: function (row, column, tr)
|
||||||
{
|
{
|
||||||
if (column.columnIndex != -1)
|
if (column.column != null)
|
||||||
column.value = this._model.data[row][column.columnIndex];
|
column.value = this._model.data[row][column.column];
|
||||||
|
|
||||||
if (column.renderer)
|
if (column.renderer)
|
||||||
{
|
{
|
||||||
|
@ -131,7 +131,7 @@ module.exports = new Class
|
||||||
var tr = this.tbody.childNodes[row];
|
var tr = this.tbody.childNodes[row];
|
||||||
|
|
||||||
for (var i = 0; i < x.length; i++)
|
for (var i = 0; i < x.length; i++)
|
||||||
if (x[i].renderer || columns.indexOf (x[i].columnIndex) != -1)
|
if (x[i].renderer || columns.indexOf (x[i].column) != -1)
|
||||||
{
|
{
|
||||||
var cell = this.renderCell (row, x[i], tr);
|
var cell = this.renderCell (row, x[i], tr);
|
||||||
tr.replaceChild (cell, tr.childNodes[i]);
|
tr.replaceChild (cell, tr.childNodes[i]);
|
||||||
|
@ -203,7 +203,7 @@ module.exports = new Class
|
||||||
case Db.Model.Status.READY:
|
case Db.Model.Status.READY:
|
||||||
{
|
{
|
||||||
for (var i = 0; i < this.columns.length; i++)
|
for (var i = 0; i < this.columns.length; i++)
|
||||||
this.columns[i].updateColumnIndex (this._model);
|
this.columns[i].updateColumnName (this._model);
|
||||||
|
|
||||||
this.buildRow (this._model.numRows);
|
this.buildRow (this._model.numRows);
|
||||||
this.showNoRecordsFound ();
|
this.showNoRecordsFound ();
|
||||||
|
@ -223,7 +223,7 @@ module.exports = new Class
|
||||||
this._node.appendChild (this.tbody);
|
this._node.appendChild (this.tbody);
|
||||||
}
|
}
|
||||||
|
|
||||||
,showNoRecordsFound: function (count)
|
,showNoRecordsFound: function ()
|
||||||
{
|
{
|
||||||
if (this._model.numRows == 0)
|
if (this._model.numRows == 0)
|
||||||
this.showMessage (_('EmptyList'), 'clean');
|
this.showMessage (_('EmptyList'), 'clean');
|
||||||
|
@ -277,28 +277,30 @@ module.exports = new Class
|
||||||
|
|
||||||
,sortModel: function (column)
|
,sortModel: function (column)
|
||||||
{
|
{
|
||||||
var columnIndex = column.columnIndex;
|
var columnName = column.column;
|
||||||
|
|
||||||
if (this._model && columnIndex != -1)
|
if (this._model && columnName != -1)
|
||||||
{
|
{
|
||||||
if (this.sortColumn === columnIndex
|
var SortWay = Db.Model.SortWay;
|
||||||
&& this.sortWay === Db.Model.SortWay.ASC)
|
|
||||||
this.sortWay = Db.Model.SortWay.DESC;
|
if (this.sortColumn === columnName
|
||||||
|
&& this.sortWay === SortWay.ASC)
|
||||||
|
this.sortWay = SortWay.DESC;
|
||||||
else
|
else
|
||||||
this.sortWay = Db.Model.SortWay.ASC;
|
this.sortWay = SortWay.ASC;
|
||||||
|
|
||||||
this.sortColumn = columnIndex;
|
this.sortColumn = columnName;
|
||||||
|
|
||||||
this._model.sort (columnIndex, this.sortWay);
|
this._model.sort (columnName, this.sortWay);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
,columnChanged: function (column, row, newValue)
|
,columnChanged: function (column, row, newValue)
|
||||||
{
|
{
|
||||||
var columnIndex = column.columnIndex;
|
var columnName = column.column;
|
||||||
|
|
||||||
if (columnIndex != -1)
|
if (columnName != -1)
|
||||||
this._model.setByIndex (row, columnIndex, newValue);
|
this._model.set (row, columnName, newValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
,addColumn: function (pos, column)
|
,addColumn: function (pos, column)
|
||||||
|
|
100
js/htk/style.css
100
js/htk/style.css
|
@ -203,43 +203,63 @@ td.cell-image .htk-image
|
||||||
width: 20em;
|
width: 20em;
|
||||||
background-color: white;
|
background-color: white;
|
||||||
border: none;
|
border: none;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.htk-calendar .month
|
||||||
|
{
|
||||||
|
background-color: #009688;
|
||||||
|
color: white;
|
||||||
|
height: 2.2em;
|
||||||
|
padding: .5em;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 2.2em;
|
||||||
|
font-size: 1.4em;
|
||||||
|
}
|
||||||
|
.htk-calendar .month > .button
|
||||||
|
{
|
||||||
|
cursor: pointer;
|
||||||
|
height: 2.2em;
|
||||||
|
width: 2.2em;
|
||||||
|
text-align: center;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
.htk-calendar .month > .button:hover
|
||||||
|
{
|
||||||
|
background-color: rgba(1, 1, 1, 0.2);
|
||||||
|
}
|
||||||
|
.htk-calendar .month > .button.previous
|
||||||
|
{
|
||||||
|
float:left;
|
||||||
|
}
|
||||||
|
.htk-calendar .month > .button.next
|
||||||
|
{
|
||||||
|
float:right;
|
||||||
|
}
|
||||||
|
.htk-calendar .wrapper
|
||||||
|
{
|
||||||
|
padding: .8em;
|
||||||
}
|
}
|
||||||
.htk-calendar table
|
.htk-calendar table
|
||||||
{
|
{
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
}
|
}
|
||||||
.htk-calendar thead tr,
|
.htk-calendar thead th
|
||||||
.htk-calendar tfoot tr
|
|
||||||
{
|
{
|
||||||
background-color: #009688;
|
color: #666;
|
||||||
color: white;
|
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
vertical-align: middle;
|
|
||||||
text-align: center;
|
|
||||||
height: 3em;
|
|
||||||
}
|
|
||||||
.htk-calendar thead span
|
|
||||||
{
|
|
||||||
color: white;
|
|
||||||
}
|
}
|
||||||
.htk-calendar thead tr
|
.htk-calendar thead tr
|
||||||
{
|
{
|
||||||
|
vertical-align: middle;
|
||||||
|
text-align: center;
|
||||||
|
height: 3em;
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
}
|
}
|
||||||
.htk-calendar tfoot tr
|
.htk-calendar .wdays > th
|
||||||
{
|
{
|
||||||
border-top: none;
|
font-weight: normal;
|
||||||
}
|
}
|
||||||
.htk-calendar th.button:hover
|
.htk-calendar tbody tr
|
||||||
{
|
|
||||||
cursor: pointer;
|
|
||||||
background-color: rgba(1, 1, 1, 0.2);
|
|
||||||
}
|
|
||||||
.htk-calendar col
|
|
||||||
{
|
|
||||||
width: 14.2%;
|
|
||||||
}
|
|
||||||
.htk-calendar tr
|
|
||||||
{
|
{
|
||||||
height: 2em;
|
height: 2em;
|
||||||
}
|
}
|
||||||
|
@ -249,30 +269,29 @@ td.cell-image .htk-image
|
||||||
}
|
}
|
||||||
.htk-calendar tbody td > div
|
.htk-calendar tbody td > div
|
||||||
{
|
{
|
||||||
height: 2em;
|
height: 1.8em;
|
||||||
width: 2em;
|
width: 1.8em;
|
||||||
line-height: 2em;
|
line-height: 1.8em;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
border-radius: 2em;
|
border-radius: 2em;
|
||||||
padding: 0.3em;
|
padding: 0.3em;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
color: #555;
|
|
||||||
}
|
}
|
||||||
.htk-calendar div.disabled
|
.htk-calendar tbody .disabled
|
||||||
{
|
{
|
||||||
color: #999;
|
color: #999;
|
||||||
}
|
}
|
||||||
.htk-calendar div.today
|
.htk-calendar tbody .today
|
||||||
{
|
{
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: black;
|
color: black;
|
||||||
}
|
}
|
||||||
.htk-calendar div.selected
|
.htk-calendar tbody .selected
|
||||||
{
|
{
|
||||||
color: white;
|
color: white;
|
||||||
background-color: #009688;
|
background-color: #009688;
|
||||||
}
|
}
|
||||||
.htk-calendar div.enabled:hover
|
.htk-calendar tbody .enabled:hover
|
||||||
{
|
{
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
background-color: #008678;
|
background-color: #008678;
|
||||||
|
@ -632,6 +651,25 @@ td.cell-image .htk-image
|
||||||
border-left-color: white;
|
border-left-color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Transitions */
|
||||||
|
|
||||||
|
.slide
|
||||||
|
{
|
||||||
|
transition: transform 100ms;
|
||||||
|
}
|
||||||
|
.slide-right
|
||||||
|
{
|
||||||
|
transform: translate3d(20em, 0, 0);
|
||||||
|
}
|
||||||
|
.slide-left
|
||||||
|
{
|
||||||
|
transform: translate3d(-20em, 0, 0);
|
||||||
|
}
|
||||||
|
.slide-return
|
||||||
|
{
|
||||||
|
transform: translate3d(0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
} /*+++++++++ Screen end */
|
} /*+++++++++ Screen end */
|
||||||
|
|
||||||
@keyframes spinner
|
@keyframes spinner
|
||||||
|
|
|
@ -12,7 +12,7 @@ var objectAttrs = {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compiles a @HTML.Node from element tag.
|
* Compiles a @HTMLElement from element tag.
|
||||||
*/
|
*/
|
||||||
module.exports = new Class
|
module.exports = new Class
|
||||||
({
|
({
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
var VnObject = require ('./object');
|
var VnObject = require ('./object');
|
||||||
|
|
||||||
var regex = /{{[\w_]+(\.[\w_]+)?}}/g;
|
var regex = /{{\s*[\w_]+\s*(\.\s*[\w_]+\s*)?}}/g;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Replaces all ocurrences of {{value}} by it's corresponding value in the
|
* Replaces all ocurrences of {{value}} by it's corresponding value in the
|
||||||
|
@ -51,13 +51,13 @@ module.exports = new Class
|
||||||
|
|
||||||
if (match.length > 1)
|
if (match.length > 1)
|
||||||
{
|
{
|
||||||
lotId = match[0];
|
lotId = match[0].trim ();
|
||||||
name = match[1];
|
name = match[1].trim ();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
lotId = null;
|
lotId = null;
|
||||||
name = match[0];
|
name = match[0].trim ();
|
||||||
}
|
}
|
||||||
|
|
||||||
params.push ({
|
params.push ({
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
var Compiler = require ('./compiler');
|
var Compiler = require ('./compiler');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compiles a @HTML.TextNode from text node.
|
* Compiles a @Text from text node.
|
||||||
*/
|
*/
|
||||||
module.exports = new Class
|
module.exports = new Class
|
||||||
({
|
({
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
,"April": "April"
|
,"April": "April"
|
||||||
,"May": "May"
|
,"May": "May"
|
||||||
,"June": "June"
|
,"June": "June"
|
||||||
,"July": "June"
|
,"July": "July"
|
||||||
,"August": "August"
|
,"August": "August"
|
||||||
,"September": "September"
|
,"September": "September"
|
||||||
,"October": "October"
|
,"October": "October"
|
||||||
|
|
|
@ -1,36 +1,10 @@
|
||||||
|
|
||||||
var VnObject = require ('./object');
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Readable data model.
|
* Readable data model.
|
||||||
*/
|
*/
|
||||||
var Klass = new Class ();
|
module.exports = new Class
|
||||||
module.exports = Klass;
|
|
||||||
|
|
||||||
var Status =
|
|
||||||
{
|
|
||||||
CLEAN : 1
|
|
||||||
,LOADING : 2
|
|
||||||
,READY : 3
|
|
||||||
,ERROR : 4
|
|
||||||
};
|
|
||||||
|
|
||||||
var SortWay =
|
|
||||||
{
|
|
||||||
ASC : 1
|
|
||||||
,DESC : 2
|
|
||||||
};
|
|
||||||
|
|
||||||
Klass.extend
|
|
||||||
({
|
({
|
||||||
Status: Status
|
Properties:
|
||||||
,SortWay: SortWay
|
|
||||||
});
|
|
||||||
|
|
||||||
Klass.implement
|
|
||||||
({
|
|
||||||
Extends: VnObject
|
|
||||||
,Properties:
|
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* The number of rows in the model.
|
* The number of rows in the model.
|
||||||
|
|
|
@ -0,0 +1,412 @@
|
||||||
|
|
||||||
|
var VnObject = require ('./object');
|
||||||
|
|
||||||
|
// TODO: Remove this dependency
|
||||||
|
var Type = require ('db/connection').Type;
|
||||||
|
|
||||||
|
var Klass = new Class ();
|
||||||
|
module.exports = Klass;
|
||||||
|
|
||||||
|
var Status =
|
||||||
|
{
|
||||||
|
CLEAN : 1
|
||||||
|
,LOADING : 2
|
||||||
|
,READY : 3
|
||||||
|
,ERROR : 4
|
||||||
|
};
|
||||||
|
|
||||||
|
var SortWay =
|
||||||
|
{
|
||||||
|
ASC : 1
|
||||||
|
,DESC : 2
|
||||||
|
};
|
||||||
|
|
||||||
|
Klass.extend
|
||||||
|
({
|
||||||
|
Status: Status
|
||||||
|
,SortWay: SortWay
|
||||||
|
});
|
||||||
|
|
||||||
|
Klass.implement
|
||||||
|
({
|
||||||
|
Extends: VnObject
|
||||||
|
,Tag: 'vn-model'
|
||||||
|
,Properties:
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The model internal data.
|
||||||
|
*/
|
||||||
|
data:
|
||||||
|
{
|
||||||
|
type: Array
|
||||||
|
,get: function ()
|
||||||
|
{
|
||||||
|
return this._data;
|
||||||
|
}
|
||||||
|
,set: function (x)
|
||||||
|
{
|
||||||
|
this._setData (x);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* The number of rows in the model.
|
||||||
|
*/
|
||||||
|
numRows:
|
||||||
|
{
|
||||||
|
type: Number
|
||||||
|
,get: function ()
|
||||||
|
{
|
||||||
|
if (this._data)
|
||||||
|
return this._data.length;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* The current status of the model.
|
||||||
|
*/
|
||||||
|
status:
|
||||||
|
{
|
||||||
|
type: Number
|
||||||
|
,get: function ()
|
||||||
|
{
|
||||||
|
return this._status;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Checks if the model data is ready.
|
||||||
|
*/
|
||||||
|
ready:
|
||||||
|
{
|
||||||
|
type: Boolean
|
||||||
|
,get: function ()
|
||||||
|
{
|
||||||
|
return this._status === Status.READY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
,_data: null
|
||||||
|
,_status: Status.CLEAN
|
||||||
|
|
||||||
|
,_requestedSortName: null
|
||||||
|
,_sortColumn: null
|
||||||
|
,_sortWay: null
|
||||||
|
|
||||||
|
,_requestedIndexes: {}
|
||||||
|
,_indexes: []
|
||||||
|
|
||||||
|
//+++++++++++++++++++++++++++++ Data hadling
|
||||||
|
|
||||||
|
,_setData: function (data)
|
||||||
|
{
|
||||||
|
this._data = data;
|
||||||
|
this._refreshRowIndexes (0);
|
||||||
|
|
||||||
|
if (this._requestedSortName != null)
|
||||||
|
this._realSort (this._requestedSortName, this._sortWay);
|
||||||
|
for (column in this._requestedIndexes)
|
||||||
|
this._buildIndex (column);
|
||||||
|
|
||||||
|
this._setStatus (Status.READY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the row exists.
|
||||||
|
*
|
||||||
|
* @param {Integer} rowIndex The row index
|
||||||
|
* @return {Boolean} %true if row exists, %false otherwise
|
||||||
|
*/
|
||||||
|
,checkRowExists: function (rowIndex)
|
||||||
|
{
|
||||||
|
return this._data != null
|
||||||
|
&& rowIndex >= 0
|
||||||
|
&& rowIndex < this._data.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a value from the model.
|
||||||
|
*
|
||||||
|
* @param {Number} rowIndex The row index
|
||||||
|
* @param {Number} columnName The column name
|
||||||
|
* @return {*} The value
|
||||||
|
*/
|
||||||
|
,get: function (rowIndex, columnName)
|
||||||
|
{
|
||||||
|
if (!this.checkRowExists (rowIndex))
|
||||||
|
return undefined;
|
||||||
|
|
||||||
|
return this._data[rowIndex][columnName];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates a value on the model.
|
||||||
|
*
|
||||||
|
* @param {Number} rowIndex The row index
|
||||||
|
* @param {Number} columnName The column name
|
||||||
|
* @param {*} value The new value
|
||||||
|
*/
|
||||||
|
,set: function (rowIndex, columnName, value)
|
||||||
|
{
|
||||||
|
if (!this.checkRowExists (rowIndex))
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.emit ('row-updated-before', rowIndex);
|
||||||
|
this._data[rowIndex][columnName] = value;
|
||||||
|
this.emit ('row-updated', rowIndex, [columnName]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a row as an object using the column index.
|
||||||
|
*
|
||||||
|
* @param {Number} rowIndex The row index
|
||||||
|
* @return {Object} The row as an object
|
||||||
|
*/
|
||||||
|
,getObject: function (rowIndex)
|
||||||
|
{
|
||||||
|
return this.checkRowExists (rowIndex) ?
|
||||||
|
this._data[rowIndex] : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
,_setStatus: function (status)
|
||||||
|
{
|
||||||
|
this._status = status;
|
||||||
|
this.emit ('status-changed', status);
|
||||||
|
this.emit ('status-changed-after', status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserts a new row on the model.
|
||||||
|
*
|
||||||
|
* @return The index of the inserted row
|
||||||
|
*/
|
||||||
|
,insertRow: function (newRow)
|
||||||
|
{
|
||||||
|
var rowIndex = this._data.push (newRow) - 1;
|
||||||
|
newRow.index = rowIndex;
|
||||||
|
this.emit ('row-inserted', rowIndex);
|
||||||
|
return rowIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes a row from the model.
|
||||||
|
*
|
||||||
|
* @param {Number} rowIndex The row index
|
||||||
|
*/
|
||||||
|
,deleteRow: function (rowIndex)
|
||||||
|
{
|
||||||
|
if (!this.checkRowExists (rowIndex))
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.emit ('row-deleted-before', rowIndex);
|
||||||
|
this._data.splice (rowIndex, 1);
|
||||||
|
this.emit ('row-deleted', rowIndex);
|
||||||
|
this._refreshRowIndexes (rowIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
//+++++++++++++++++++++++++++++ Sorting
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Orders the model by the specified column name.
|
||||||
|
*
|
||||||
|
* @param {String} columnName The column name
|
||||||
|
* @param {SortWay} way The sort way
|
||||||
|
*/
|
||||||
|
,sort: function (columnName, way)
|
||||||
|
{
|
||||||
|
this._requestedSortName = columnName;
|
||||||
|
this._sort (columnName, way);
|
||||||
|
}
|
||||||
|
|
||||||
|
,_sort: function (columnName, way)
|
||||||
|
{
|
||||||
|
this._setStatus (Status.LOADING);
|
||||||
|
this._realSort (columnName, way);
|
||||||
|
this._setStatus (Status.READY);
|
||||||
|
}
|
||||||
|
|
||||||
|
,_realSort: function (columnName, way)
|
||||||
|
{
|
||||||
|
if (columnName !== this._sortColumn)
|
||||||
|
{
|
||||||
|
if (way === SortWay.DESC)
|
||||||
|
var sortFunction = this.sortFunctionDesc;
|
||||||
|
else
|
||||||
|
var sortFunction = this.sortFunctionAsc;
|
||||||
|
|
||||||
|
this._data.sort (sortFunction.bind (this, columnName));
|
||||||
|
}
|
||||||
|
else if (way !== this._sortWay)
|
||||||
|
this._data.reverse ();
|
||||||
|
|
||||||
|
this._sortColumn = columnName;
|
||||||
|
this._sortWay = way;
|
||||||
|
|
||||||
|
this._refreshRowIndexes (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
,_refreshRowIndexes: function (start)
|
||||||
|
{
|
||||||
|
var data = this._data;
|
||||||
|
|
||||||
|
for (var i = start; i < data.length; i++)
|
||||||
|
data[i].index = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Function used to sort the model ascending.
|
||||||
|
*/
|
||||||
|
,sortFunctionAsc: function (column, a, b)
|
||||||
|
{
|
||||||
|
if (a[column] < b[column])
|
||||||
|
return -1;
|
||||||
|
else if (a[column] > b[column])
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Function used to sort the model descending.
|
||||||
|
*/
|
||||||
|
,sortFunctionDesc: function (column, a, b)
|
||||||
|
{
|
||||||
|
if (a[column] > b[column])
|
||||||
|
return -1;
|
||||||
|
else if (a[column] < b[column])
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//+++++++++++++++++++++++++++++ Searching
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds an internal hash index for the specified column, this speeds
|
||||||
|
* significantly searches on that column, specially when model has a lot of
|
||||||
|
* rows.
|
||||||
|
*
|
||||||
|
* FIXME: Not fully implemented.
|
||||||
|
*
|
||||||
|
* @param {String} column The column name
|
||||||
|
*/
|
||||||
|
,indexColumn: function (column)
|
||||||
|
{
|
||||||
|
this._requestedIndexes[column] = true;
|
||||||
|
|
||||||
|
if (this._status === Status.READY)
|
||||||
|
this._buildIndex (column);
|
||||||
|
}
|
||||||
|
|
||||||
|
,getHashFunc: function (type)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case Type.TIMESTAMP:
|
||||||
|
case Type.DATE_TIME:
|
||||||
|
case Type.DATE:
|
||||||
|
return function (value) { return value.toString (); };
|
||||||
|
default:
|
||||||
|
return function (value) { return value; };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
,_buildIndex: function (columnName)
|
||||||
|
{
|
||||||
|
if (this.columnMap[columnName] === undefined)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var index = {};
|
||||||
|
var data = this._data;
|
||||||
|
var hashFunc = getHashFunc (this.columns[columnName].type);
|
||||||
|
|
||||||
|
for (var i = 0; i < data.length; i++)
|
||||||
|
index[hashFunc (data[i][columnName])] = i;
|
||||||
|
|
||||||
|
this._indexes[columnName] = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Searchs a value on the model and returns the row index of the first
|
||||||
|
* ocurrence.
|
||||||
|
* If an index have been built on that column, it will be used, for more
|
||||||
|
* information see the indexColumn() method.
|
||||||
|
*
|
||||||
|
* @param {String} columnIndex The column index
|
||||||
|
* @param {Object} value The value to search
|
||||||
|
* @return {Number} The column index
|
||||||
|
*/
|
||||||
|
,searchByIndex: function (columnIndex, value)
|
||||||
|
{
|
||||||
|
var columnName = this.columns[columnIndex].name;
|
||||||
|
return this.search (columnName, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Searchs a value on the model and returns the row index of the first
|
||||||
|
* ocurrence.
|
||||||
|
*
|
||||||
|
* @param {Number} columnName The column name
|
||||||
|
* @param {Object} value The value to search
|
||||||
|
* @return {Number} The column index
|
||||||
|
*/
|
||||||
|
,search: function (columnName, value)
|
||||||
|
{
|
||||||
|
var columnIndex = this.columnMap[columnName];
|
||||||
|
|
||||||
|
if (columnIndex === undefined)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (value)
|
||||||
|
switch (this.columns[columnIndex].type)
|
||||||
|
{
|
||||||
|
case Type.BOOLEAN:
|
||||||
|
value = !!value;
|
||||||
|
break;
|
||||||
|
case Type.INTEGER:
|
||||||
|
value = parseInt (value);
|
||||||
|
break;
|
||||||
|
case Type.DOUBLE:
|
||||||
|
value = parseFloat (value);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
value = value.toString ();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Searchs the value using an internal index.
|
||||||
|
|
||||||
|
var index = this._indexes[columnName];
|
||||||
|
|
||||||
|
if (index)
|
||||||
|
{
|
||||||
|
if (index[value] !== undefined)
|
||||||
|
return index[value];
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Searchs the value using a loop.
|
||||||
|
|
||||||
|
var data = this._data;
|
||||||
|
|
||||||
|
switch (this.columns[columnIndex].type)
|
||||||
|
{
|
||||||
|
case Type.TIMESTAMP:
|
||||||
|
case Type.DATE_TIME:
|
||||||
|
case Type.DATE:
|
||||||
|
{
|
||||||
|
for (var i = 0; i < data.length; i++)
|
||||||
|
if (value === data[i][columnName].toString ())
|
||||||
|
return i;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
for (var i = 0; i < data.length; i++)
|
||||||
|
if (value === data[i][columnName])
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
});
|
|
@ -0,0 +1,76 @@
|
||||||
|
|
||||||
|
var VnNode = require ('./node');
|
||||||
|
|
||||||
|
var transition = checkTransitions ();
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
transition: transition,
|
||||||
|
slide: slide
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks for transition support.
|
||||||
|
*
|
||||||
|
* @return {String} The transition end event name, or %null if no support
|
||||||
|
*/
|
||||||
|
function checkTransitions ()
|
||||||
|
{
|
||||||
|
var el = document.createElement ('div');
|
||||||
|
var transitionEndNames = {
|
||||||
|
transition : 'transitionend'
|
||||||
|
,OTransition : 'oTransitionEnd'
|
||||||
|
,MozTransition : 'transitionend'
|
||||||
|
,WebkitTransition : 'webkitTransitionEnd'
|
||||||
|
};
|
||||||
|
|
||||||
|
for (var name in transitionEndNames)
|
||||||
|
if (el.style[name] !== undefined)
|
||||||
|
return transitionEndNames[name];
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
checkTransitions ();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Slides an element.
|
||||||
|
*
|
||||||
|
* @param {Node} node The element to slide
|
||||||
|
* @param {String} way The slide way: 'left' or 'right'
|
||||||
|
* @param {Function} cb The callback to call when transition ends
|
||||||
|
*/
|
||||||
|
function slide (node, way, cb)
|
||||||
|
{
|
||||||
|
if (transition === null)
|
||||||
|
{
|
||||||
|
if (cb) cb();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var inverseWay = way == 'left' ? 'right' : 'left';
|
||||||
|
|
||||||
|
VnNode.addClass (node, 'slide slide-'+ way);
|
||||||
|
node.addEventListener (transition, slideStart);
|
||||||
|
|
||||||
|
function slideStart ()
|
||||||
|
{
|
||||||
|
node.removeEventListener (transition, slideStart);
|
||||||
|
VnNode.removeClass (node, 'slide');
|
||||||
|
VnNode.removeClass (node, 'slide-'+ way);
|
||||||
|
VnNode.addClass (node, 'slide-'+ inverseWay);
|
||||||
|
cb ();
|
||||||
|
setTimeout (slideReturn, 20);
|
||||||
|
}
|
||||||
|
|
||||||
|
function slideReturn ()
|
||||||
|
{
|
||||||
|
VnNode.addClass (node, 'slide');
|
||||||
|
VnNode.removeClass (node, 'slide-'+ inverseWay);
|
||||||
|
node.addEventListener (transition, slideEnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
function slideEnd ()
|
||||||
|
{
|
||||||
|
node.removeEventListener (transition, slideEnd);
|
||||||
|
VnNode.removeClass (node, 'slide');
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue