0
1
Fork 0
This commit is contained in:
Juan Ferrer Toribio 2017-04-24 09:47:56 +02:00
parent adb651fe69
commit 1e43aead46
9 changed files with 241 additions and 245 deletions

View File

@ -4,14 +4,10 @@ var Model = require ('./model');
module.exports = new Class
({
Extends: Vn.Object
,Implements: Iterator
Extends: Iterator
,Tag: 'db-form'
,Properties:
{
/**
* The model associated to this form.
*/
model:
{
type: Model
@ -42,78 +38,42 @@ module.exports = new Class
return;
this._row = x;
this._rowChanged ();
this.changed ();
}
,get: function ()
{
return this._row;
}
},
/**
* The number of rows in the form.
*/
numRows:
{
type: Number
,get: function ()
{
return this._model ?
this._model.numRows : 0;
}
},
/**
* Checks if the form data is ready.
*/
ready:
{
type: Boolean
,get: function ()
{
return this._model ?
this._model.ready : false;
}
},
/**
* The current row parameters.
*/
params:
{
type: Object
,set: function (x)
{
this.assign (x);
}
,get: function ()
{
return this.getParams ();
}
}
}
,lastRow: 0
,_model: null
,_row: -1
,_ready: false
,initialize: function (props)
{
Object.assign (this, {
_lastRow: 0
,_lastReady: false
});
this.parent (props);
}
,onModelChange: function ()
{
var ready = this._model && this._model.ready;
if (ready != this._ready)
if (ready != this._lastReady)
{
if (this._row != -1)
this.lastRow = this._row;
this._lastRow = this._row;
this._ready = ready;
this._lastReady = ready;
this.emit ('status-changed');
if (this._row == -1)
this.row = this.lastRow;
this.row = this._lastRow;
if (ready)
this.emit ('ready');
this.changed ();
}
}

View File

@ -27,13 +27,6 @@ module.exports = new Class
{
type: Number
},
/**
* The current row parameters.
*/
params:
{
type: Object
},
/**
* Checks if the form data is ready.
*/
@ -42,9 +35,6 @@ module.exports = new Class
type: Boolean
}
}
,_model: null
,_row: -1
,refresh: function ()
{

View File

@ -3,17 +3,15 @@ var IteratorIface = require ('./iterator-iface');
var Model = require ('./model');
/**
* A light iterator for models.
* A light iterator for models. It assumes that its row and model properties
* are always valid.
*/
module.exports = new Class
({
Extends: Vn.Object
Extends: Vn.Lot
,Implements: IteratorIface
,Properties:
{
/**
* The model associated to this form.
*/
model:
{
type: Model
@ -26,24 +24,19 @@ module.exports = new Class
return this._model;
}
},
/**
* The row where the form positioned, has -1 if the row is unselected.
*/
row:
{
type: Number
,set: function (x)
{
this._row = x;
this.updateParams ();
}
,get: function ()
{
return this._row;
}
},
/**
* The number of rows in the form.
*/
numRows:
{
type: Number
@ -53,9 +46,6 @@ module.exports = new Class
this._model.numRows : 0;
}
},
/**
* Checks if the form data is ready.
*/
ready:
{
type: Boolean
@ -64,21 +54,26 @@ module.exports = new Class
return this._model ?
this._model.ready : false;
}
},
/**
* The current row parameters.
*/
params:
{
type: Object
,set: function (x)
{
this.assign (x);
}
,get: function ()
{
return this.getParams ();
}
}
}
,initialize: function (props)
{
Object.assign (this, {
_model: null
,_row: -1
});
this.parent (props);
}
,_paramsChanged: function (diff)
{
for (var key in diff)
this._model.set (this._row, key, diff[key]);
}
,updateParams: function ()
{
this.params = this._model.getObject (this._row);
}
});

View File

@ -7,7 +7,7 @@ require ('./gui.css');
/**
* The main screen component. It has a left menu, a navbar with configurable
* action buttons and the body where @Db.Form childs can be displayed.
* action buttons and the body where @Form childs can be displayed.
*/
module.exports = new Class
({

View File

@ -47,8 +47,8 @@ module.exports = new Class
}
}
/**
* {Function (Vn.BuilderResult, Db.Form)} Function to call after every
* box rendering.
* {Function (Vn.BuilderResult, Db.Iterator)} Function to call after
* every box rendering.
*/
,renderer:
{

View File

@ -1,19 +1,18 @@
var VnObject = require ('./object');
var VnDate = require ('./date');
var LotIface = require ('./lot-iface');
var Value = require ('./value');
var Lot = require ('./lot');
/**
* Class to handle the hash part of the URL as a key-value
* javascript object. It also handles dates and objects as
* a value.
* Class to handle the hash part of the URL as a key-value javascript object.
* It also handles dates and objects as a value.
*/
module.exports = new Class
({
Extends: VnObject
,Implements: LotIface
Extends: Lot
,Properties: {
/**
* The main window object.
*/
window:
{
type: Window
@ -27,120 +26,110 @@ module.exports = new Class
{
return this._window;
}
},
params:
{
type: Object
,set: function (x)
{
this.setAll (x);
}
,get: function ()
{
return this._hashMap;
}
}
}
,initialize: function (props)
{
this._hash = null;
this._hashMap = null;
this._window = null;
this._hashChangedHandler = this._hashChanged.bind (this);
Object.assign (this, {
_hash: null
,_hashLock: false
,_window: null
,_hashChangedHandler: this._hashChanged.bind (this)
});
this.parent (props);
}
,get: function (key)
,_paramsChanged: function ()
{
return this._hashMap[key];
}
,set: function (key, value)
{
var object = {};
object[key] = value;
this.assign (object);
}
,assign: function (object)
{
var newObject = {};
for (var key in this._hashMap)
newObject[key] = this._hashMap[key];
for (var key in object)
newObject[key] = object[key];
this.setAll (newObject);
}
/**
* Sets the hash part of the URL.
*
* @param {Object} object A key-value object
*/
,setAll: function (object)
{
if (object)
for (var key in object)
if (object[key] === null || object[key] === undefined)
delete object[key];
var newHash = this.make (object);
if (!object)
object = {};
if (!Value.equals (this._hashMap, object))
{
this._hashMap = object;
this._hash = newHash;
this._blockChanged = true;
location.hash = newHash;
this._blockChanged = false;
this.changed ();
}
this._updateHash ();
}
/**
* Creates a URL with the given hash data.
*
* @param {Object} object A key-value object
* @param {Object} params A key-value object
* @param {boolean} add %true to combine with the current params, %false otherwise
* @return {string} The URL
*/
,make: function (object, add)
,make: function (params, add)
{
if (add)
{
params = Object.assign ({}, params);
for (var key in this._params)
if (!params[key])
params[key] = this._params[key];
}
return this.renderHash (object);
}
/**
* Updates the window hash with current params.
*/
,updateHash: function ()
{
if (this._hashLock)
return;
this._hash = this.renderHash (this._params);
this._hashLock = true;
location.hash = this._hash;
this._hashLock = false;
}
/*
* Called when window hash changes.
*/
,_hashChanged: function ()
{
var newHash = location.hash;
if (this._hashLock || this._hash === newHash)
return;
this._hash = newHash;
this._hashLock = true;
this.params = this.parseHash (newHash);
this._hashLock = false;
}
/**
* Creates a URL with the given hash data.
*
* @param {Object} params The key-value object
* @return {string} The URL
*/
,renderHash: function (params)
{
var hash = '#!';
if (add && object)
for (var key in this._hashMap)
if (!object[key])
object[key] = this._hashMap[key];
for (var key in object)
for (var key in params)
if (params[key] !== undefined)
{
if (hash.length > 2)
hash += '&';
hash += encodeURIComponent (key) +'='+ this.renderValue (object[key]);
hash += encodeURIComponent (key) +'='+ this.renderValue (params[key]);
}
return hash;
}
,_hashChanged: function ()
/**
* Parses a hash string to a key-value object.
*
* @param {string} hashString The hash string
* @return {Object} The key-value object
*/
,parseHash: function (hashString)
{
var newHash = location.hash;
if (this._blockChanged || this._hash == newHash)
return;
var newMap = hashMap = {};
var kvPairs = newHash.substr(2).split ('&');
var kvPairs = hashString.substr(2).split ('&');
for (var i = 0; i < kvPairs.length; i++)
{
@ -149,17 +138,13 @@ module.exports = new Class
if (kvPair[0])
newMap[decodeURIComponent (kvPair[0])] = this.parseValue (kvPair[1]);
}
if (!Value.equals (this._hashMap, newMap))
{
this._hashMap = newMap;
this._hash = newHash;
this.changed ();
}
}
,renderValue: function (v)
{
if (v == null)
return '';
switch (typeof v)
{
case 'number':

View File

@ -1,19 +1,26 @@
/**
* Holds a plain key-value javascript object and monitorizes
* changes over it.
* Holds a plain key-value javascript object and monitorizes changes over it.
*/
module.exports = new Class
({
Properties:
{
/**
* The internal object with the params.
* The internal object with the params, this is the lot internal object
* and should be used for read-only purposes.
*/
params:
{
type: Object
}
/**
* Shortcut for params property.
*/
,$:
{
type: Object
}
}
/**
@ -22,7 +29,10 @@ module.exports = new Class
* @param {string} field The field name
* @return {*} The field value
*/
,get: function () {}
,get: function (field)
{
return this.params[field];
}
/**
* Sets a value on the set.
@ -30,7 +40,12 @@ module.exports = new Class
* @param {string} field The field name
* @param {*} value The new field value
*/
,set: function () {}
,set: function (field, value)
{
var params = {};
params[field] = value;
this.assign (param);
}
/**
* Returns an array with the set keys.
@ -54,13 +69,7 @@ module.exports = new Class
*
* @param {Object} object The source object
*/
,assign: function (object)
{
for (var key in object)
this.set (key, object[key]);
this.changed ();
}
,assign: function () {}
/**
* Copies all values from another lot.
@ -71,4 +80,12 @@ module.exports = new Class
{
this.assign (lot.params);
}
/**
* Resets all values.
*/
,reset: function ()
{
this.params = {};
}
});

View File

@ -1,6 +1,7 @@
var VnObject = require ('./object');
var LotIface = require ('./lot-iface');
var Value = require ('./value');
module.exports = new Class
({
@ -14,8 +15,19 @@ module.exports = new Class
type: Object
,set: function (x)
{
this._params = x;
this.changed ();
this._setAll (x);
}
,get: function ()
{
return this._params;
}
}
,$:
{
type: Object
,set: function (x)
{
this._setAll (x);
}
,get: function ()
{
@ -24,32 +36,15 @@ module.exports = new Class
}
}
,_attachments: null
,initialize: function (props)
{
this._params = {};
this.parent (props);
}
,get: function (paramName)
,get: function (field)
{
return this._params[paramName];
}
,set: function (paramName, value)
{
this._params[paramName] = value;
this.changed ();
}
/**
* Resets all values.
*/
,reset: function ()
{
this._params = {};
this.changed ();
return this._params[field];
}
,keys: function ()
@ -57,11 +52,35 @@ module.exports = new Class
return Object.keys (this._params);
}
,assign: function (object)
,assign: function (params)
{
for (var key in object)
this._params[key] = object[key];
var diff = Value.partialDiff (this._params, params);
this.changed ();
if (diff)
{
Object.assign (this._params, diff);
this._paramsChanged (diff);
this.changed (diff);
}
}
,setAll: function (params)
{
var diff = Value.diff (this._params, params);
if (diff)
{
this._params = Value.kvClone (params);
this._paramsChanged (diff);
this.changed (diff);
}
}
/**
* Called when lot params changes, can be implemented by child classes to
* be notified about changes.
*
* @param {Object} diff Changed parameters and its new values
*/
,_paramsChanged: function () {}
});

View File

@ -2,8 +2,8 @@
var VnDate = require ('./date');
/**
* Checks if two values are equal, it also checks objects. Basic
* values are compared using the strict equality operator.
* Checks if two values are equal, it also checks objects. Basic values are
* compared using the strict equality operator.
*
* @param {*} a Value to compare to
* @param {*} b Value to compare with
@ -32,7 +32,7 @@ function equals (a, b)
}
/**
* Calculates differences of two key-value objects.
* Calculates differences between two key-value objects.
*
* @param {Object} orgObject Value to compare to
* @param {Object} newObject Value to compare with
@ -40,18 +40,13 @@ function equals (a, b)
*/
function diff (orgObject, newObject)
{
var key;
var diff = {};
var keys = Object.keys (orgObject);
for (var i = keys.length; --i; key = keys[i])
for (var key in orgObject)
if (!simpleEquals (orgObject[key], newObject[key]))
diff[key] = simpleClone (newObject[key]);
var keys = Object.keys (newObject);
for (var i = keys.length; --i; key = keys[i])
for (var key in newObject)
if (orgObject[key] === undefined && newObject[key] !== undefined)
diff[key] = simpleClone (newObject[key]);
@ -61,6 +56,39 @@ function diff (orgObject, newObject)
return null;
}
/**
* Calculates new differences between two key-value objects.
*
* @param {Object} orgObject Value to compare to
* @param {Object} newObject Value to compare with
* @return {Object} The differences or %null if there are no differences
*/
function partialDiff (orgObject, newObject)
{
var diff = {};
for (var key in newObject)
if (!simpleEquals (orgObject[key], newObject[key]))
diff[key] = simpleClone (newObject[key]);
if (Object.keys (diff).length > 0)
return diff;
return null;
}
function kvClone (object)
{
var key;
var copy = {};
var keys = Object.keys (object);
for (var i = keys.length; --i; key = keys[i])
copy[key] = simpleClone (object[key]);
return copy;
}
/**
* Copies a simple value.
*
@ -120,6 +148,8 @@ module.exports =
,equals: equals
,diff: diff
,partialDiff: partialDiff
,kvClone: kvClone
,simpleClone: simpleClone
,simpleEquals: simpleEquals
,sprintf: sprintf
@ -133,7 +163,7 @@ module.exports =
return false;
}
,format: function (value, format)
{
if (value === null || value === undefined)
@ -155,12 +185,12 @@ module.exports =
return value;
}
,replaceNumber: function (value, token, digits)
{
return new Number (value).toFixed (parseInt (digits));
}
,replaceString: function (value)
{
return value;