diff --git a/sao/src/window.js b/sao/src/window.js index e7b9e3f323..a748e70931 100644 --- a/sao/src/window.js +++ b/sao/src/window.js @@ -540,11 +540,29 @@ undelete: function() { this.screen.unremove(); }, + validate: function() { + let prm = jQuery.Deferred(); + this.screen.current_view.set_value(); + var record = this.screen.current_record; + if (record) { + var fields = this.screen.current_view.get_fields(); + if (!record.validate(fields)) { + this.screen.display(true).always(() => prm.reject()); + return prm; + } + if (this.screen.pre_validate) { + return record.pre_validate().then( + prm.resolve, prm.reject); + } + } + prm.resolve(); + return prm; + }, previous: function() { - return this.screen.display_previous(); + return this.validate().then(() => this.screen.display_previous()); }, next: function() { - return this.screen.display_next(); + return this.validate().then(() => this.screen.display_next()); }, switch_: function() { return this.screen.switch_view(); diff --git a/tryton/tryton/gui/window/win_form.py b/tryton/tryton/gui/window/win_form.py index 8edf436f9f..dd70a0bc92 100644 --- a/tryton/tryton/gui/window/win_form.py +++ b/tryton/tryton/gui/window/win_form.py @@ -319,11 +319,24 @@ class WinForm(NoModal, InfoBar): self.screen.new() self.screen.current_view.widget.set_sensitive(True) + def _validate(self): + self.screen.current_view.set_value() + if record := self.screen.current_record: + fields = self.screen.current_view.get_fields() + if not record.validate(fields): + self.screen.display(set_cursor=True) + return False + if self.screen.pre_validate and not record.pre_validate(): + return False + return True + def _sig_next(self, widget): - self.screen.display_next() + if self._validate(): + self.screen.display_next() def _sig_previous(self, widget): - self.screen.display_prev() + if self._validate(): + self.screen.display_prev() def _sig_remove(self, widget, remove=False): self.screen.remove(remove=remove)