forked from verdnatura/hedera-web
Vn.Model v1
This commit is contained in:
parent
4d8bd4ad95
commit
fe68eb5ce0
|
@ -15,8 +15,8 @@ Hedera.Contact = new Class
|
|||
,refreshCaptcha: function ()
|
||||
{
|
||||
params = {
|
||||
'srv': 'rest:core/captcha',
|
||||
'stamp': new Date ().getTime ()
|
||||
srv: 'rest:core/captcha',
|
||||
stamp: new Date ().getTime ()
|
||||
};
|
||||
this.$.captchaImg.src = '?'+ Vn.Url.makeUri (params);
|
||||
}
|
||||
|
|
|
@ -123,8 +123,12 @@ Connection.implement
|
|||
{
|
||||
var data = json[i].data;
|
||||
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;
|
||||
|
||||
|
@ -136,17 +140,32 @@ Connection.implement
|
|||
castFunc = this.valueToDate;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (castFunc !== null)
|
||||
{
|
||||
castFuncs[j] = castFunc;
|
||||
|
||||
if (columns[j].def != null)
|
||||
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)
|
||||
|
|
711
js/db/model.js
711
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 ();
|
||||
|
||||
if (row instanceof Array && row.length > 0)
|
||||
if (row instanceof Object && row.length > 0)
|
||||
return row[0];
|
||||
|
||||
return null;
|
||||
|
|
|
@ -29,13 +29,12 @@ module.exports = new Class
|
|||
/**
|
||||
* Gets a value from de result.
|
||||
*
|
||||
* @param {string} columnName The column name
|
||||
* @param {String} columnName The column name
|
||||
* @return {Object} The cell value
|
||||
*/
|
||||
,get: function (columnName)
|
||||
{
|
||||
var columnIndex = this.columnMap[columnName];
|
||||
return this.data[this.row][columnIndex];
|
||||
return this.data[this.row][columnName];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -48,7 +47,7 @@ module.exports = new Class
|
|||
if (!this.next ())
|
||||
return null;
|
||||
|
||||
return this.getObject (this.row);
|
||||
return this.data[this.row];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -59,14 +58,7 @@ module.exports = new Class
|
|||
*/
|
||||
,getObject: function (rowIndex)
|
||||
{
|
||||
var row = 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;
|
||||
return this.data[rowIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -231,6 +231,7 @@ textarea,
|
|||
.input
|
||||
{
|
||||
padding: 0 .2em;
|
||||
padding-bottom: 1px;
|
||||
}
|
||||
input[type=text],
|
||||
input[type=password],
|
||||
|
@ -253,7 +254,9 @@ input[type=number]:focus,
|
|||
textarea:focus,
|
||||
.input:focus
|
||||
{
|
||||
border-color: #333;
|
||||
border-color: #666;
|
||||
border-bottom-width: 2px;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
input[type=checkbox],
|
||||
input[type=radio]
|
||||
|
|
|
@ -96,10 +96,10 @@ module.exports = new Class
|
|||
return td;
|
||||
}
|
||||
|
||||
,updateColumnIndex: function (model)
|
||||
,updateColumnName: function (model)
|
||||
{
|
||||
if (this.column)
|
||||
this.columnIndex = model.getColumnIndex (this.column);
|
||||
if (this.columnIndex != -1)
|
||||
this.column = model.getColumnName (this.columnIndex);
|
||||
}
|
||||
|
||||
,changed: function (tr, newValue)
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
|
||||
var slide = require ('vn/transitions').slide;
|
||||
|
||||
module.exports = new Class
|
||||
({
|
||||
Extends: Htk.Field
|
||||
|
@ -31,47 +33,44 @@ module.exports = new Class
|
|||
var node = this.createRoot ('div');
|
||||
node.className = 'htk-calendar';
|
||||
|
||||
var table = this.createElement ('table');
|
||||
this.node.appendChild (table);
|
||||
var div = this.createElement ('div');
|
||||
div.className = 'month';
|
||||
node.appendChild (div);
|
||||
|
||||
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');
|
||||
table.appendChild (thead);
|
||||
|
||||
var tr = this.createElement ('tr');
|
||||
thead.appendChild (tr);
|
||||
|
||||
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 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');
|
||||
th.appendChild (monthNode);
|
||||
div.appendChild (monthNode);
|
||||
|
||||
var space = this.createTextNode (' ');
|
||||
th.appendChild (space);
|
||||
div.appendChild (space);
|
||||
|
||||
var yearNode = this.createElement ('span');
|
||||
th.appendChild (yearNode);
|
||||
div.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 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');
|
||||
wrapper.appendChild (table);
|
||||
this.table = table;
|
||||
|
||||
var thead = this.createElement ('thead');
|
||||
table.appendChild (thead);
|
||||
|
||||
var tr = this.createElement ('tr');
|
||||
tr.className = 'wdays';
|
||||
thead.appendChild (tr);
|
||||
|
||||
for (var i = 1; i <= len; i++)
|
||||
|
@ -255,8 +254,8 @@ module.exports = new Class
|
|||
this.month = 11;
|
||||
this.year--;
|
||||
}
|
||||
|
||||
this.refresh ();
|
||||
|
||||
this.refreshSlide ('right');
|
||||
}
|
||||
|
||||
,nextMonthClicked: function ()
|
||||
|
@ -269,6 +268,12 @@ module.exports = new Class
|
|||
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 ();
|
||||
}
|
||||
|
||||
,onRowInsert: function (model, row)
|
||||
,onRowInsert: function ()
|
||||
{
|
||||
this.buildRow (1);
|
||||
}
|
||||
|
||||
,renderCell: function (row, column, tr)
|
||||
{
|
||||
if (column.columnIndex != -1)
|
||||
column.value = this._model.data[row][column.columnIndex];
|
||||
if (column.column != null)
|
||||
column.value = this._model.data[row][column.column];
|
||||
|
||||
if (column.renderer)
|
||||
{
|
||||
|
@ -131,7 +131,7 @@ module.exports = new Class
|
|||
var tr = this.tbody.childNodes[row];
|
||||
|
||||
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);
|
||||
tr.replaceChild (cell, tr.childNodes[i]);
|
||||
|
@ -203,7 +203,7 @@ module.exports = new Class
|
|||
case Db.Model.Status.READY:
|
||||
{
|
||||
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.showNoRecordsFound ();
|
||||
|
@ -223,7 +223,7 @@ module.exports = new Class
|
|||
this._node.appendChild (this.tbody);
|
||||
}
|
||||
|
||||
,showNoRecordsFound: function (count)
|
||||
,showNoRecordsFound: function ()
|
||||
{
|
||||
if (this._model.numRows == 0)
|
||||
this.showMessage (_('EmptyList'), 'clean');
|
||||
|
@ -277,28 +277,30 @@ module.exports = new Class
|
|||
|
||||
,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
|
||||
&& this.sortWay === Db.Model.SortWay.ASC)
|
||||
this.sortWay = Db.Model.SortWay.DESC;
|
||||
else
|
||||
this.sortWay = Db.Model.SortWay.ASC;
|
||||
var SortWay = Db.Model.SortWay;
|
||||
|
||||
this.sortColumn = columnIndex;
|
||||
if (this.sortColumn === columnName
|
||||
&& this.sortWay === SortWay.ASC)
|
||||
this.sortWay = SortWay.DESC;
|
||||
else
|
||||
this.sortWay = SortWay.ASC;
|
||||
|
||||
this.sortColumn = columnName;
|
||||
|
||||
this._model.sort (columnIndex, this.sortWay);
|
||||
this._model.sort (columnName, this.sortWay);
|
||||
}
|
||||
}
|
||||
|
||||
,columnChanged: function (column, row, newValue)
|
||||
{
|
||||
var columnIndex = column.columnIndex;
|
||||
var columnName = column.column;
|
||||
|
||||
if (columnIndex != -1)
|
||||
this._model.setByIndex (row, columnIndex, newValue);
|
||||
if (columnName != -1)
|
||||
this._model.set (row, columnName, newValue);
|
||||
}
|
||||
|
||||
,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;
|
||||
background-color: white;
|
||||
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
|
||||
{
|
||||
border-collapse: collapse;
|
||||
}
|
||||
.htk-calendar thead tr,
|
||||
.htk-calendar tfoot tr
|
||||
.htk-calendar thead th
|
||||
{
|
||||
background-color: #009688;
|
||||
color: white;
|
||||
color: #666;
|
||||
font-weight: normal;
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
height: 3em;
|
||||
}
|
||||
.htk-calendar thead span
|
||||
{
|
||||
color: white;
|
||||
}
|
||||
.htk-calendar thead tr
|
||||
{
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
height: 3em;
|
||||
border-bottom: none;
|
||||
}
|
||||
.htk-calendar tfoot tr
|
||||
.htk-calendar .wdays > th
|
||||
{
|
||||
border-top: none;
|
||||
font-weight: normal;
|
||||
}
|
||||
.htk-calendar th.button:hover
|
||||
{
|
||||
cursor: pointer;
|
||||
background-color: rgba(1, 1, 1, 0.2);
|
||||
}
|
||||
.htk-calendar col
|
||||
{
|
||||
width: 14.2%;
|
||||
}
|
||||
.htk-calendar tr
|
||||
.htk-calendar tbody tr
|
||||
{
|
||||
height: 2em;
|
||||
}
|
||||
|
@ -249,30 +269,29 @@ td.cell-image .htk-image
|
|||
}
|
||||
.htk-calendar tbody td > div
|
||||
{
|
||||
height: 2em;
|
||||
width: 2em;
|
||||
line-height: 2em;
|
||||
height: 1.8em;
|
||||
width: 1.8em;
|
||||
line-height: 1.8em;
|
||||
text-align: center;
|
||||
border-radius: 2em;
|
||||
padding: 0.3em;
|
||||
margin: 0 auto;
|
||||
color: #555;
|
||||
}
|
||||
.htk-calendar div.disabled
|
||||
.htk-calendar tbody .disabled
|
||||
{
|
||||
color: #999;
|
||||
}
|
||||
.htk-calendar div.today
|
||||
.htk-calendar tbody .today
|
||||
{
|
||||
font-weight: bold;
|
||||
color: black;
|
||||
}
|
||||
.htk-calendar div.selected
|
||||
.htk-calendar tbody .selected
|
||||
{
|
||||
color: white;
|
||||
background-color: #009688;
|
||||
}
|
||||
.htk-calendar div.enabled:hover
|
||||
.htk-calendar tbody .enabled:hover
|
||||
{
|
||||
cursor: pointer;
|
||||
background-color: #008678;
|
||||
|
@ -632,6 +651,25 @@ td.cell-image .htk-image
|
|||
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 */
|
||||
|
||||
@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
|
||||
({
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
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
|
||||
|
@ -51,13 +51,13 @@ module.exports = new Class
|
|||
|
||||
if (match.length > 1)
|
||||
{
|
||||
lotId = match[0];
|
||||
name = match[1];
|
||||
lotId = match[0].trim ();
|
||||
name = match[1].trim ();
|
||||
}
|
||||
else
|
||||
{
|
||||
lotId = null;
|
||||
name = match[0];
|
||||
name = match[0].trim ();
|
||||
}
|
||||
|
||||
params.push ({
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
var Compiler = require ('./compiler');
|
||||
|
||||
/**
|
||||
* Compiles a @HTML.TextNode from text node.
|
||||
* Compiles a @Text from text node.
|
||||
*/
|
||||
module.exports = new Class
|
||||
({
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
,"April": "April"
|
||||
,"May": "May"
|
||||
,"June": "June"
|
||||
,"July": "June"
|
||||
,"July": "July"
|
||||
,"August": "August"
|
||||
,"September": "September"
|
||||
,"October": "October"
|
||||
|
|
|
@ -1,36 +1,10 @@
|
|||
|
||||
var VnObject = require ('./object');
|
||||
|
||||
/**
|
||||
* Readable data model.
|
||||
*/
|
||||
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
|
||||
module.exports = new Class
|
||||
({
|
||||
Status: Status
|
||||
,SortWay: SortWay
|
||||
});
|
||||
|
||||
Klass.implement
|
||||
({
|
||||
Extends: VnObject
|
||||
,Properties:
|
||||
Properties:
|
||||
{
|
||||
/**
|
||||
* 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