From 0f054b57c18073b396e45dda15cb5f23da3815a3 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Wed, 18 Jul 2012 14:43:59 +0200 Subject: [PATCH] [IMP] add ability to change row using up/down key while editing list * Allow asserting state of record being edited (creating or modifying) through Editor#is_editing * Improve setup_events to also dispatch keydown events bzr revid: xmo@openerp.com-20120718124359-q0udajwbuhzpqjmi --- .../web/static/src/js/view_list_editable.js | 77 +++++++++++++++++-- doc/list-view.rst | 13 +++- 2 files changed, 82 insertions(+), 8 deletions(-) diff --git a/addons/web/static/src/js/view_list_editable.js b/addons/web/static/src/js/view_list_editable.js index baff7085e0e..d8a1e26dfa6 100644 --- a/addons/web/static/src/js/view_list_editable.js +++ b/addons/web/static/src/js/view_list_editable.js @@ -368,19 +368,19 @@ openerp.web.list_editable = function (instance) { }, setup_events: function () { var self = this; - this.editor.$element.on('keyup', function (e) { + this.editor.$element.on('keyup keydown', function (e) { + if (!self.editor.is_editing()) { return; } var key = _($.ui.keyCode).chain() .map(function (v, k) { return {name: k, code: v}; }) .find(function (o) { return o.code === e.which; }) .value(); if (!key) { return; } - var method = 'keyup_' + key.name; + var method = e.type + '_' + key.name; if (!(method in self)) { return; } self[method](e); }); }, keyup_ENTER: function () { - if (!this.editor.is_editing()) { return; } var self = this; return this.save_edition().pipe(function (saveInfo) { if (saveInfo.created) { @@ -391,8 +391,58 @@ openerp.web.list_editable = function (instance) { }); }, keyup_ESCAPE: function () { - if (!this.editor.is_editing()) { return; } return this.cancel_edition(); + }, + _text_selection_range: function (el) { + if (el.selectionStart !== undefined) { + return { + start: el.selectionStart, + end: el.selectionEnd + }; + } else if(document.body.createTextRange) { + throw new Error("Implement text range handling for MSIE"); + var sel = document.body.createTextRange(); + if (sel.parentElement() === el) { + + } + } + }, + _text_cursor: function (el) { + var selection = this._text_selection_range(el); + if (selection.start !== selection.end) { + return null; + } + return selection.start; + }, + keydown_UP: function (e) { + if (!this.editor.is_editing('edit')) { return; } + // FIXME: assumes editable widgets are input-type elements + var index = this._text_cursor(e.target); + // If selecting or not at the start of the input + if (index === null || index !== 0) { return; } + + var self = this; + e.preventDefault(); + return this.save_edition().pipe(function (saveInfo) { + // Should not happen when creating, ignore saveInfo.created + return self.start_edition( + self.records.pred(saveInfo.record, {wraparound: true})); + }); + }, + keydown_DOWN: function (e) { + if (!this.editor.is_editing('edit')) { return; } + // FIXME: assumes editable widgets are input-type elements + var index = this._text_cursor(e.target); + // If selecting or not at the end of the input + if (index === null || index !== e.target.value.length) { return; } + + var self = this; + e.preventDefault(); + return this.save_edition().pipe(function (saveInfo) { + // Should not happen when creating, ignore saveInfo.created + return self.start_edition( + self.records.succ(saveInfo.record, {wraparound: true})); + }); } }); @@ -462,8 +512,23 @@ openerp.web.list_editable = function (instance) { return edition_view; }, - is_editing: function () { - return !!this.record; + /** + * + * @param {String} [state] either ``new`` or ``edit`` + * @return {Boolean} + */ + is_editing: function (state) { + if (!this.record) { + return false; + } + switch(state) { + case null: case undefined: + return true; + case 'new': return !this.record.id; + case 'edit': return !!this.record.id; + } + throw new Error("is_editing's state filter must be either `new` or" + + " `edit` if provided"); }, edit: function (record, configureField) { // TODO: specify sequence of edit calls diff --git a/doc/list-view.rst b/doc/list-view.rst index 4030df2edd0..ebb5f0ffe4d 100644 --- a/doc/list-view.rst +++ b/doc/list-view.rst @@ -287,11 +287,20 @@ formview, delegating instead to its :type parent: :js:class:`~openerp.web.Widget` :param EditorOptions options: - .. js:function:: openerp.web.list.Editor.is_editing + .. js:function:: openerp.web.list.Editor.is_editing([record_state]) Indicates whether the editor is currently in the process of - providing edition for a field. + providing edition for a record. + Can be filtered by the state of the record being edited + (whether it's a record being *created* or a record being + *altered*), in which case it asserts both that an edition is + underway and that the record being edited respectively does + not yet exist in the database or already exists there. + + :param record_state: state of the record being edited. + Either ``"new"`` or ``"edit"``. + :type record_state: String :rtype: Boolean .. js:function:: openerp.web.list.Editor.edit(record, configureField)