diff --git a/CHANGELOG.txt b/CHANGELOG.txt index d73078a..e8adc39 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -3,6 +3,7 @@ X-editable changelog Version 1.4.5 wip ---------------------------- +[bug] fix datefield (datetimefield) to return null for incorrect dates (vitalets) [bug #224] do not close popup when it is saving value (vitalets) [enh] added `submitValue` to `save` event params (vitalets) [enh #259] allow `getValue` method to return value itself, not object (vitalets) diff --git a/src/inputs/date/date.js b/src/inputs/date/date.js index e1db352..0960f1b 100644 --- a/src/inputs/date/date.js +++ b/src/inputs/date/date.js @@ -78,55 +78,55 @@ $(function(){ }, value2html: function(value, element) { - var text = value ? this.dpg.formatDate(value, this.parsedViewFormat, this.options.datepicker.language) : ''; + var text = value ? this.dpg.formatDate(value, this.parsedViewFormat, this.options.datepicker.language) : ''; Date.superclass.value2html(text, element); }, - html2value: function(html) { - return html ? this.dpg.parseDate(html, this.parsedViewFormat, this.options.datepicker.language) : null; - }, - - value2str: function(value) { - return value ? this.dpg.formatDate(value, this.parsedFormat, this.options.datepicker.language) : ''; - }, - - str2value: function(str) { - return str ? this.dpg.parseDate(str, this.parsedFormat, this.options.datepicker.language) : null; - }, - - value2submit: function(value) { - return this.value2str(value); - }, + html2value: function(html) { + return this.parseDate(html, this.parsedViewFormat); + }, - value2input: function(value) { - this.$input.bdatepicker('update', value); - }, - - input2value: function() { - return this.$input.data('datepicker').date; - }, - - activate: function() { - }, - - clear: function() { - this.$input.data('datepicker').date = null; - this.$input.find('.active').removeClass('active'); - if(!this.options.showbuttons) { - this.$input.closest('form').submit(); - } - }, - - autosubmit: function() { - this.$input.on('mouseup', '.day', function(e){ - if($(e.currentTarget).is('.old') || $(e.currentTarget).is('.new')) { - return; - } - var $form = $(this).closest('form'); - setTimeout(function() { - $form.submit(); - }, 200); - }); + value2str: function(value) { + return value ? this.dpg.formatDate(value, this.parsedFormat, this.options.datepicker.language) : ''; + }, + + str2value: function(str) { + return this.parseDate(str, this.parsedFormat); + }, + + value2submit: function(value) { + return this.value2str(value); + }, + + value2input: function(value) { + this.$input.bdatepicker('update', value); + }, + + input2value: function() { + return this.$input.data('datepicker').date; + }, + + activate: function() { + }, + + clear: function() { + this.$input.data('datepicker').date = null; + this.$input.find('.active').removeClass('active'); + if(!this.options.showbuttons) { + this.$input.closest('form').submit(); + } + }, + + autosubmit: function() { + this.$input.on('mouseup', '.day', function(e){ + if($(e.currentTarget).is('.old') || $(e.currentTarget).is('.new')) { + return; + } + var $form = $(this).closest('form'); + setTimeout(function() { + $form.submit(); + }, 200); + }); //changedate is not suitable as it triggered when showing datepicker. see #149 /* this.$input.on('changeDate', function(e){ @@ -136,7 +136,26 @@ $(function(){ }, 200); }); */ - } + }, + + /* + For incorrect date bootstrap-datepicker returns current date that is not suitable + for datefield. + This function returns null for incorrect date. + */ + parseDate: function(str, format) { + var date = null, formattedBack; + if(str) { + date = this.dpg.parseDate(str, format, this.options.datepicker.language); + if(typeof str === 'string') { + formattedBack = this.dpg.formatDate(date, format, this.options.datepicker.language); + if(str !== formattedBack) { + date = null; + } + } + } + return date; + } }); diff --git a/src/inputs/datetime/datetime.js b/src/inputs/datetime/datetime.js index 991ba50..03e2494 100644 --- a/src/inputs/datetime/datetime.js +++ b/src/inputs/datetime/datetime.js @@ -101,7 +101,7 @@ $(function(){ html2value: function(html) { //parseDate return utc date! - var value = html ? this.dpg.parseDate(html, this.parsedViewFormat, this.options.datetimepicker.language, this.options.formatType) : null; + var value = this.parseDate(html, this.parsedViewFormat); return value ? this.fromUTC(value) : null; }, @@ -112,7 +112,7 @@ $(function(){ str2value: function(str) { //parseDate return utc date! - var value = str ? this.dpg.parseDate(str, this.parsedFormat, this.options.datetimepicker.language, this.options.formatType) : null; + var value = this.parseDate(str, this.parsedFormat); return value ? this.fromUTC(value) : null; }, @@ -160,7 +160,26 @@ $(function(){ //convert date from utc to local fromUTC: function(value) { return value ? new Date(value.valueOf() + value.getTimezoneOffset() * 60000) : value; - } + }, + + /* + For incorrect date bootstrap-datetimepicker returns current date that is not suitable + for datetimefield. + This function returns null for incorrect date. + */ + parseDate: function(str, format) { + var date = null, formattedBack; + if(str) { + date = this.dpg.parseDate(str, format, this.options.datetimepicker.language, this.options.formatType); + if(typeof str === 'string') { + formattedBack = this.dpg.formatDate(date, format, this.options.datetimepicker.language, this.options.formatType); + if(str !== formattedBack) { + date = null; + } + } + } + return date; + } }); diff --git a/test/unit/datefield.js b/test/unit/datefield.js index 7375029..bb6635c 100644 --- a/test/unit/datefield.js +++ b/test/unit/datefield.js @@ -105,4 +105,31 @@ $(function () { equal(e.text(), dview, 'text correct'); }); + + test("incorrect date", function () { + var d = '15.05.1984', + e = $('<a href="#" data-type="date" data-pk="1">'+d+'</a>').appendTo('#qunit-fixture').editable({ + format: f, + viewformat: f + }), + nextD = '16.05.1984'; + + equal(frmt(e.data('editable').value, 'dd.mm.yyyy'), d, 'value correct'); + + e.click(); + var p = tip(e); + ok(p.find('input').is(':visible'), 'input exists'); + + equal(p.find('input').val(), d, 'date set correct'); + + //enter incorrect date + p.find('input').val('abcde'); + + //submit + p.find('form').submit(); + + ok(!p.is(':visible'), 'popover closed'); + equal(e.data('editable').value, null, 'date set to null'); + equal(e.text(), $.fn.editable.defaults.emptytext , 'emptytext shown'); + }); }); \ No newline at end of file diff --git a/test/unit/datetimefield.js b/test/unit/datetimefield.js index 9d36eb4..f7c5725 100644 --- a/test/unit/datetimefield.js +++ b/test/unit/datetimefield.js @@ -125,4 +125,24 @@ $(function () { equal(e.text(), dview, 'text correct'); }); + test("incorrect datetime", function () { + var dview = '15/05/1984 15:45', + d = '1984-05-15 15:45', + e = $('<a href="#" data-type="datetime" data-pk="1" data-format="yyyy-mm-dd hh:ii" data-viewformat="dd/mm/yyyy hh:ii" data-value="'+d+'"></a>').appendTo('#qunit-fixture').editable(); + + e.click(); + var p = tip(e); + ok(p.find('input').is(':visible'), 'input exists'); + + //enter incorrect date + p.find('input').val('abcde'); + + //submit + p.find('form').submit(); + + ok(!p.is(':visible'), 'popover closed'); + equal(e.data('editable').value, null, 'date set to null'); + equal(e.text(), $.fn.editable.defaults.emptytext , 'emptytext shown'); + }); + }); \ No newline at end of file