Implement datetime and time widgets

review1067002
This commit is contained in:
Cédric Krier committed 2013-10-02 12:05:14 +02:00
1 parent 0f3f7bf1af
commit e0518618bc
5 files changed
+241 -69

No files matched your search

+59 -3
View File
@@ -62,9 +62,65 @@
};
Sao.common.date_format = function() {
// TODO
// http://stackoverflow.com/questions/2678230/how-to-getting-browser-current-locale-preference-using-javascript
return '%m/%d/%Y';
var context = Sao.Session.current_session.context;
if (context.locale && context.locale.date) {
return context.locale.date
.replace('%d', 'dd')
.replace('%j', 'oo')
.replace('%a', 'D')
.replace('%A', 'DD')
.replace('%m', 'mm')
.replace('%b', 'M')
.replace('%B', 'MM')
.replace('%y', 'y')
.replace('%Y', 'yy');
}
return jQuery.datepicker.W3C;
};
Sao.common.format_time = function(format, date) {
var pad = Sao.common.pad;
return format.replace('%H', pad(date.getHours(), 2))
.replace('%M', pad(date.getMinutes(), 2))
.replace('%S', pad(date.getSeconds(), 2));
};
Sao.common.parse_time = function(format, value) {
var getNumber = function(pattern) {
var i = format.indexOf(pattern);
if (~i) {
var number = parseInt(value.slice(i, i + pattern.length), 10);
if (!isNaN(number)) {
return number;
}
}
return 0;
};
return new Sao.Time(getNumber('%H'), getNumber('%M'), getNumber('%S'));
};
Sao.common.format_datetime = function(date_format, time_format, date) {
return (jQuery.datepicker.formatDate(date_format, date) + ' ' +
Sao.common.format_time(time_format, date));
};
Sao.common.parse_datetime = function(date_format, time_format, value) {
var date = jQuery.datepicker.parseDate(date_format, value);
var time_value = value.replace(jQuery.datepicker.formatDate(
date_format + ' ', date), '');
var time = Sao.common.parse_time(time_format, time_value);
date.setHours(time.getHours());
date.setMinutes(time.getMinutes());
date.setSeconds(time.getSeconds());
return date;
};
Sao.common.pad = function(number, length) {
var str = '' + number;
while (str.length < length) {
str = '0' + str;
}
return str;
};
Sao.common.text_to_float_time = function(text, conversion, digit) {
+66 -2
View File
@@ -1120,14 +1120,78 @@
});
Sao.field.DateTime = Sao.class_(Sao.field.Field, {
_default: null
_default: null,
time_format: function(record) {
return record.expr_eval(this.description.format);
},
set_client: function(record, value, force_change) {
if (!(value instanceof Date)) {
try {
value = Sao.common.parse_datetime(
Sao.common.date_format(),
this.time_format(record),
value);
} catch (e) {
value = this._default;
}
}
Sao.field.DateTime._super.set_client.call(this, record, value,
force_change);
},
get_client: function(record) {
var value = Sao.field.Date._super.get_client.call(this, record);
if (value) {
return Sao.common.format_datetime(Sao.common.date_format(),
this.time_format(record), value);
}
return '';
}
});
Sao.field.Date = Sao.class_(Sao.field.Field, {
_default: null
_default: null,
set_client: function(record, value, force_change) {
if (!(value instanceof Date)) {
try {
value = jQuery.datepicker.parseDate(
Sao.common.date_format(), value);
} catch (e) {
value = this._default;
}
}
Sao.field.Date._super.set_client.call(this, record, value,
force_change);
},
get_client: function(record) {
var value = Sao.field.Date._super.get_client.call(this, record);
if (value) {
return jQuery.datepicker.formatDate(Sao.common.date_format(),
value);
}
return '';
}
});
Sao.field.Time = Sao.class_(Sao.field.Field, {
_default: null,
time_format: function(record) {
return record.expr_eval(this.description.format);
},
set_client: function(record, value, force_change) {
if (!(value instanceof Sao.Time)) {
value = Sao.common.parse_time(this.time_format(record), value);
}
Sao.field.Time._super.set_client.call(this, record, value,
force_change);
},
get_client: function(record) {
var value = Sao.field.Time._super.get_client.call(this, record);
if (value) {
return Sao.common.format_time(this.time_format(record),
value);
}
return '';
}
});
Sao.field.Number = Sao.class_(Sao.field.Field, {
+10 -1
View File
@@ -77,7 +77,9 @@
value.month - 1, value.day);
break;
case 'time':
throw new Error('Time support not implemented');
value = new Sao.Time(value.hour, value.minute,
value.second);
break;
case 'buffer':
// javascript's atob does not understand linefeed
// characters
@@ -138,6 +140,13 @@
if (parent) {
parent[index] = value;
}
} else if (value instanceof Sao.Time) {
value = {
'__class__': 'time',
'hour': value.getHours(),
'minute': value.getMinutes(),
'second': value.getSeconds()
};
} else if (value instanceof Sao.Decimal) {
value = {
'__class__': 'Decimal',
+24
View File
@@ -35,6 +35,30 @@ var Sao = {};
Sao.Decimal = Number;
Sao.Time = Sao.class_(Object, {
init: function(hour, minute, second) {
this.date = new Date(0, 0, 0, hour, minute, second);
},
getHours: function() {
return this.date.getHours();
},
setHours: function(hour) {
this.date.setHours(hour);
},
getMinutes: function() {
return this.date.getMinutes();
},
setMinutes: function(minute) {
this.date.setMinutes(minute);
},
getSeconds: function() {
return this.date.getSeconds();
},
setSeconds: function(second) {
this.date.setSeconds(second);
}
});
Sao.config = {};
Sao.config.limit = 1000;
Sao.config.display_size = 20;
+82 -63
View File
@@ -34,6 +34,10 @@
return Sao.View.Tree.Many2OneColumn;
case 'date':
return Sao.View.Tree.DateColumn;
case 'datetime':
return Sao.View.Tree.DateTimeColumn;
case 'time':
return Sao.View.Tree.TimeColumn;
case 'one2many':
return Sao.View.Tree.One2ManyColumn;
case 'many2many':
@@ -478,6 +482,7 @@
});
Sao.View.Tree.CharColumn = Sao.class_(Object, {
class_: 'column-char',
init: function(model, attributes) {
this.type = 'field';
this.model = model;
@@ -488,7 +493,7 @@
},
get_cell: function() {
var cell = jQuery('<span/>');
cell.addClass('column-char');
cell.addClass(this.class_);
return cell;
},
update_text: function(cell, record) {
@@ -512,33 +517,25 @@
});
Sao.View.Tree.IntegerColumn = Sao.class_(Sao.View.Tree.CharColumn, {
class_: 'column-integer',
get_cell: function() {
var cell = Sao.View.Tree.IntegerColumn._super.get_cell.call(this);
cell.css('text-align', 'right');
cell.removeClass('column-char');
cell.addClass('column-integer');
return cell;
}
});
Sao.View.Tree.FloatColumn = Sao.class_(Sao.View.Tree.IntegerColumn, {
init: function(model, attributes) {
Sao.View.Tree.FloatColumn._super.init.call(this, model, attributes);
},
get_cell: function() {
var cell = Sao.View.Tree.FloatColumn._super.get_cell.call(this);
cell.removeClass('column-integer');
cell.addClass('column-float');
return cell;
}
class_: 'column-float'
});
Sao.View.Tree.BooleanColumn = Sao.class_(Sao.View.Tree.IntegerColumn, {
class_: 'column-boolean',
get_cell: function() {
return jQuery('<input/>', {
'type': 'checkbox',
'disabled': true,
'class': 'column-boolean'
'class': this.class_
});
},
update_text: function(cell, record) {
@@ -547,15 +544,11 @@
});
Sao.View.Tree.Many2OneColumn = Sao.class_(Sao.View.Tree.CharColumn, {
get_cell: function() {
var cell = Sao.View.Tree.Many2OneColumn._super.get_cell.call(this);
cell.removeClass('column-char');
cell.addClass('column-many2one');
return cell;
}
class_: 'column-many2one'
});
Sao.View.Tree.SelectionColumn = Sao.class_(Sao.View.Tree.CharColumn, {
class_: 'column-selection',
init: function(model, attributes) {
Sao.View.Tree.SelectionColumn._super.init.call(this, model,
attributes);
@@ -569,12 +562,6 @@
Sao.common.selection_mixin.update_selection.call(this, record,
this.field, callback);
},
get_cell: function() {
var cell = Sao.View.Tree.Many2OneColumn._super.get_cell.call(this);
cell.removeClass('column-char');
cell.addClass('column-selection');
return cell;
},
update_text: function(cell, record) {
this.update_selection(record, function() {
var value = this.field.get(record);
@@ -602,39 +589,30 @@
});
Sao.View.Tree.DateColumn = Sao.class_(Sao.View.Tree.CharColumn, {
init: function(model, attributes) {
Sao.View.Tree.DateColumn._super.init.call(this, model, attributes);
this.date_format = Sao.common.date_format();
},
update_text: function(cell, record) {
var text;
var value = this.field.get_client(record);
var pad = function(txt) {
return (txt.toString().length < 2) ? '0' + txt : txt;
};
if (value) {
text = this.date_format.replace('%d', pad(value.getDate()));
text = text.replace('%m', pad(value.getMonth() + 1));
text = text.replace('%Y', value.getFullYear());
text = text.replace('%y', value.getFullYear().toString()
.substring(2, 4));
} else {
text = '';
}
cell.text(text);
}
class_: 'column-date'
});
Sao.View.Tree.DateTimeColumn = Sao.class_(Sao.View.Tree.CharColumn, {
class_: 'column-datetime'
});
Sao.View.Tree.TimeColumn = Sao.class_(Sao.View.Tree.CharColumn, {
class_: 'column-time'
});
Sao.View.Tree.One2ManyColumn = Sao.class_(Sao.View.Tree.CharColumn, {
class_: 'column-one2many',
update_text: function(cell, record) {
cell.text('( ' + this.field.get_client(record).length + ' )');
}
});
Sao.View.Tree.Many2ManyColumn = Sao.class_(Sao.View.Tree.One2ManyColumn, {
class_: 'column-many2many'
});
Sao.View.Tree.FloatTimeColumn = Sao.class_(Sao.View.Tree.CharColumn, {
class_: 'column-float_time',
init: function(model, attributes) {
Sao.View.Tree.FloatTimeColumn._super.init.call(this, model,
attributes);
@@ -1138,6 +1116,8 @@
return Sao.View.Form.Sha;
case 'date':
return Sao.View.Form.Date;
case 'datetime':
return Sao.View.Form.DateTime;
case 'integer':
case 'biginteger':
return Sao.View.Form.Integer;
@@ -1280,8 +1260,7 @@
}
},
set_value: function(record, field) {
var value = this.el.val() || '';
field.set_client(record, value);
field.set_client(record, this.el.val());
}
});
@@ -1308,33 +1287,74 @@
this.date.datepicker({
showOn: 'button'
});
this.date.change(this.focus_out.bind(this));
this._set_button();
},
_get_color_el: function() {
return this.date;
},
get_format: function(record, field) {
return Sao.common.date_format();
},
_set_button: function() {
this.date.next('button').text('').button({
icons: {
primary: 'ui-icon-calendar'
},
text: false
});
this.date.change(this.focus_out.bind(this));
},
_get_color_el: function() {
return this.date;
},
display: function(record, field) {
this.date.datepicker('option', 'dateFormat',
this.get_format(record, field));
// Button must be set after changing any option
this._set_button();
Sao.View.Form.Date._super.display.call(this, record, field);
if (record) {
var value = record.field_get_client(this.field_name);
this.date.datepicker('setDate', value);
} else {
this.date.datepicker('setDate', null);
}
this.date.val(record.field_get_client(this.field_name));
},
set_value: function(record, field) {
var value = this.date.datepicker('getDate');
field.set_client(record, value);
field.set_client(record, this.date.val());
}
});
// TODO DateTime, Time
Sao.View.Form.DateTime = Sao.class_(Sao.View.Form.Date, {
init: function(field_name, model, attributes) {
Sao.View.Form.DateTime._super.init.call(this, field_name, model,
attributes);
this.date.datepicker('option', 'beforeShow', function() {
var time = ' ' + Sao.common.format_time(
this.field().time_format(this.record()),
this._get_time());
this.date.datepicker('option', 'dateFormat',
Sao.common.date_format() + time);
// Button must be set after changing any option
this._set_button();
this.date.prop('disabled', true);
}.bind(this));
this.date.datepicker('option', 'onClose', function() {
this.date.prop('disabled', false);
}.bind(this));
// Button must be set after changing any option
this._set_button();
},
_get_time: function() {
return Sao.common.parse_datetime(Sao.common.date_format(),
this.field().time_format(this.record()), this.date.val());
},
get_format: function(record, field) {
var time = '';
if (record) {
var value = record.field_get(this.field_name);
time = ' ' + Sao.common.format_time(field.time_format(record),
value);
}
return Sao.common.date_format() + time;
}
});
Sao.View.Form.Time = Sao.class_(Sao.View.Form.Char, {
class_: 'form-time'
});
Sao.View.Form.Integer = Sao.class_(Sao.View.Form.Char, {
class_: 'form-integer',
@@ -1344,8 +1364,7 @@
this.el.css('text-align', 'right');
},
set_value: function(record, field) {
var value = Number(this.el.val());
field.set_client(record, value);
field.set_client(record, this.el.val());
}
});