From 5dfa8bb218bdcaa241ce4c31e9e4fc79d4a1e30e Mon Sep 17 00:00:00 2001
From: vitalets <noginsk@rambler.ru>
Date: Fri, 4 Jan 2013 16:08:00 +0400
Subject: [PATCH] datefield ready, need tests
---
src/editable-form/editable-form-utils.js | 31 ++++++++-
src/editable-form/editable-form.js | 15 ++---
src/element/editable-element.js | 20 ++----
src/inputs/date/date.js | 47 +++++++------
src/inputs/date/datefield.js | 85 ++++++++++++++++++++++++
test/loader.js | 6 +-
test/unit/date.js | 5 +-
7 files changed, 155 insertions(+), 54 deletions(-)
create mode 100644 src/inputs/date/datefield.js
diff --git a/src/editable-form/editable-form-utils.js b/src/editable-form/editable-form-utils.js
index 00c6c6a..cb16236 100644
--- a/src/editable-form/editable-form-utils.js
+++ b/src/editable-form/editable-form-utils.js
@@ -146,7 +146,34 @@
/*jslint eqeq: false*/
return result;
- }
+ },
+
+ /*
+ Returns input by options: type, mode.
+ */
+ createInput: function(options) {
+ var TypeConstructor, typeOptions, input,
+ type = options.type;
+
+ if(type === 'date' && options.mode === 'inline') {
+ if($.fn.editabletypes.datefield) {
+ type = 'datefield';
+ } else if($.fn.editabletypes.dateuifield) {
+ type = 'dateuifield';
+ }
+ }
+
+ //create input of specified type. Input will be used for converting value, not in form
+ if(typeof $.fn.editabletypes[type] === 'function') {
+ TypeConstructor = $.fn.editabletypes[type];
+ typeOptions = this.sliceObj(options, this.objectKeys(TypeConstructor.defaults));
+ input = new TypeConstructor(typeOptions);
+ return input;
+ } else {
+ $.error('Unknown type: '+ type);
+ return false;
+ }
+ }
};
-}(window.jQuery));
\ No newline at end of file
+}(window.jQuery));
diff --git a/src/editable-form/editable-form.js b/src/editable-form/editable-form.js
index d7c6d02..b52e71c 100644
--- a/src/editable-form/editable-form.js
+++ b/src/editable-form/editable-form.js
@@ -21,18 +21,13 @@ Editableform is linked with one of input types, e.g. 'text', 'select' etc.
EditableForm.prototype = {
constructor: EditableForm,
initInput: function() { //called once
- var TypeConstructor, typeOptions;
-
//create input of specified type
- if(typeof $.fn.editabletypes[this.options.type] === 'function') {
- TypeConstructor = $.fn.editabletypes[this.options.type];
- typeOptions = $.fn.editableutils.sliceObj(this.options, $.fn.editableutils.objectKeys(TypeConstructor.defaults));
- this.input = new TypeConstructor(typeOptions);
- } else {
- $.error('Unknown type: '+ this.options.type);
+ this.input = $.fn.editableutils.createInput(this.options);
+ if(!this.input) {
return;
- }
-
+ }
+
+ //set initial value
this.value = this.input.str2value(this.options.value);
},
initTemplate: function() {
diff --git a/src/element/editable-element.js b/src/element/editable-element.js
index a458ba6..1faf285 100644
--- a/src/element/editable-element.js
+++ b/src/element/editable-element.js
@@ -15,27 +15,15 @@ Makes editable any HTML element on the page. Applied as jQuery method.
Editable.prototype = {
constructor: Editable,
init: function () {
- var TypeConstructor,
- isValueByText = false,
- doAutotext,
- finalize;
+ var isValueByText = false,
+ doAutotext, finalize;
- //editableContainer must be defined
- if(!$.fn.editableContainer) {
- $.error('You must define $.fn.editableContainer via including corresponding file (e.g. editable-popover.js)');
- return;
- }
-
//name
this.options.name = this.options.name || this.$element.attr('id');
//create input of specified type. Input will be used for converting value, not in form
- if(typeof $.fn.editabletypes[this.options.type] === 'function') {
- TypeConstructor = $.fn.editabletypes[this.options.type];
- this.typeOptions = $.fn.editableutils.sliceObj(this.options, $.fn.editableutils.objectKeys(TypeConstructor.defaults));
- this.input = new TypeConstructor(this.typeOptions);
- } else {
- $.error('Unknown type: '+ this.options.type);
+ this.input = $.fn.editableutils.createInput(this.options);
+ if(!this.input) {
return;
}
diff --git a/src/inputs/date/date.js b/src/inputs/date/date.js
index 06308ce..d9e0684 100644
--- a/src/inputs/date/date.js
+++ b/src/inputs/date/date.js
@@ -26,32 +26,37 @@ $(function(){
var Date = function (options) {
this.init('date', options, Date.defaults);
-
- //set popular options directly from settings or data-* attributes
- var directOptions = $.fn.editableutils.sliceObj(this.options, ['format']);
-
- //overriding datepicker config (as by default jQuery extend() is not recursive)
- this.options.datepicker = $.extend({}, Date.defaults.datepicker, directOptions, options.datepicker);
-
- //by default viewformat equals to format
- if(!this.options.viewformat) {
- this.options.viewformat = this.options.datepicker.format;
- }
-
- //language
- this.options.datepicker.language = this.options.datepicker.language || 'en';
-
- //store DPglobal
- this.dpg = $.fn.datepicker.DPGlobal;
-
- //store parsed formats
- this.parsedFormat = this.dpg.parseFormat(this.options.datepicker.format);
- this.parsedViewFormat = this.dpg.parseFormat(this.options.viewformat);
+ this.initPicker();
};
$.fn.editableutils.inherit(Date, $.fn.editabletypes.abstractinput);
$.extend(Date.prototype, {
+ initPicker: function() {
+ //'format' is set directly from settings or data-* attributes
+
+ //by default viewformat equals to format
+ if(!this.options.viewformat) {
+ this.options.viewformat = this.options.format;
+ }
+
+ //overriding datepicker config (as by default jQuery extend() is not recursive)
+ //since 1.4 datepicker internally uses viewformat instead of format. Format is for submit only
+ this.options.datepicker = $.extend({}, Date.defaults.datepicker, this.options.datepicker, {
+ format: this.options.viewformat
+ });
+
+ //language
+ this.options.datepicker.language = this.options.datepicker.language || 'en';
+
+ //store DPglobal
+ this.dpg = $.fn.datepicker.DPGlobal;
+
+ //store parsed formats
+ this.parsedFormat = this.dpg.parseFormat(this.options.format);
+ this.parsedViewFormat = this.dpg.parseFormat(this.options.viewformat);
+ },
+
render: function () {
Date.superclass.render.call(this);
this.$input.datepicker(this.options.datepicker);
diff --git a/src/inputs/date/datefield.js b/src/inputs/date/datefield.js
new file mode 100644
index 0000000..7177ffa
--- /dev/null
+++ b/src/inputs/date/datefield.js
@@ -0,0 +1,85 @@
+/**
+Bootstrap datefield input - modification for inline mode.
+Shows normal <input type="text"> and binds popup datepicker.
+Automatically shown in inline mode.
+**/
+(function ($) {
+
+ var DateField = function (options) {
+ this.init('datefield', options, DateField.defaults);
+ this.initPicker();
+ };
+
+ $.fn.editableutils.inherit(DateField, $.fn.editabletypes.date);
+
+ $.extend(DateField.prototype, {
+ render: function () {
+ this.$input = $(this.options.tpl);
+ this.$field = this.$input.find('input');
+
+ if(this.options.inputclass) {
+ this.$field.addClass(this.options.inputclass);
+ }
+
+ if (this.options.placeholder) {
+ this.$field.attr('placeholder', this.options.placeholder);
+ }
+
+ this.$input.datepicker(this.options.datepicker);
+
+ //need to disable original event handlers
+ this.$field.off('focus keyup keydown');
+
+ //shadow update value of datepicker
+ this.$field.keyup($.proxy(function(){
+ this.$input.data('datepicker').date = this.input2value();
+ }, this));
+ },
+
+ value2str: function(value) {
+ return value ? this.dpg.formatDate(value, this.parsedViewFormat, this.options.datepicker.language) : '';
+ },
+
+ value2submit: function(value) {
+ return value ? this.dpg.formatDate(value, this.parsedFormat, this.options.datepicker.language) : null;
+ },
+
+ value2input: function(value) {
+ this.$field.val(this.value2str(value));
+ this.$input.datepicker('update');
+ },
+
+ input2value: function() {
+ return this.html2value(this.$field.val());
+ },
+
+ activate: function() {
+ if(this.$field.is(':visible')) {
+ this.$field.focus();
+ $.fn.editableutils.setCursorPosition(this.$field.get(0), this.$field.val().length);
+ }
+ },
+
+ autosubmit: function() {
+ //reset autosubmit to empty
+ }
+ });
+
+ DateField.defaults = $.extend({}, $.fn.editabletypes.date.defaults, {
+ /**
+ @property tpl
+ @default <input type="text">
+ **/
+ tpl:'<div class="input-append date"><input class="input-small" type="text"/><span class="add-on"><i class="icon-th"></i></span></div>',
+ /**
+ @property inputclass
+ @default ''
+ **/
+ inputclass: '',
+ datepicker: {autoclose: true},
+ clear: false
+ });
+
+ $.fn.editabletypes.datefield = DateField;
+
+}(window.jQuery));
\ No newline at end of file
diff --git a/test/loader.js b/test/loader.js
index 327d64e..7ffb74f 100644
--- a/test/loader.js
+++ b/test/loader.js
@@ -75,6 +75,9 @@ define(function () {
loadCss(require.toUrl("./bootstrap-datepicker/css/datepicker.css"));
}
},
+
+ //datefield
+ 'inputs/date/datefield': ['inputs/date/date'],
//jqueryui
'jqueryui/js/jquery-ui-1.9.1.custom': {
@@ -128,7 +131,8 @@ define(function () {
if(f === 'bootstrap') {
//bootstrap
- shim['editable-form/editable-form'].deps.push('inputs/date/date');
+// shim['editable-form/editable-form'].deps.push('inputs/date/date');
+ shim['editable-form/editable-form'].deps.push('inputs/date/datefield');
shim['element/editable-element'].deps.push('editable-form/editable-form-bootstrap');
shim['element/editable-element'].deps.push('containers/editable-popover');
} else if(f === 'jqueryui') {
diff --git a/test/unit/date.js b/test/unit/date.js
index bb9701a..aaf5830 100644
--- a/test/unit/date.js
+++ b/test/unit/date.js
@@ -109,10 +109,7 @@ $(function () {
test("viewformat, init by value", function () {
var dview = '15/05/1984',
d = '1984-05-15',
- e = $('<a href="#" data-type="date" data-pk="1" data-weekstart="1" data-value="'+d+'"></a>').appendTo('#qunit-fixture').editable({
- format: 'yyyy-mm-dd',
- viewformat: 'dd/mm/yyyy'
- });
+ e = $('<a href="#" data-type="date" data-pk="1" data-format="yyyy-mm-dd" data-viewformat="dd/mm/yyyy" data-value="'+d+'"></a>').appendTo('#qunit-fixture').editable();
equal(frmt(e.data('editable').value, 'yyyy-mm-dd'), d, 'value correct');
equal(e.text(), dview, 'text correct');