Edit selected One2Many rows at once

Closes #14997
This commit is contained in:
Cédric Krier
2026-08-06 14:53:51 +02:00
parent bc1de342d1
commit ef58bc6b82
6 changed files with 48 additions and 13 deletions
+1
View File
@@ -1,3 +1,4 @@
* Edit the selected One2Many rows sequentially
* Support filename extension for Binary field
* Use record name as fallback for filename of Binary field
* Support filters attribute for binary and image widgets
+20 -7
View File
@@ -4010,16 +4010,29 @@ function eval_pyson(value){
return;
}
return this.validate().then(() => {
var record = this.screen.current_record;
if (record) {
let records = Array.from(this.screen.selected_records);
let size = records.length;
if (size) {
if (this._popup) {
return;
} else {
this._popup = true;
}
new Sao.Window.Form(this.screen, () => {
this._popup = false;
});
let edit_next_record = () => {
if (records.length) {
this.screen.current_record = records.shift();
this._popup = true;
new Sao.Window.Form(this.screen, (result) => {
this._popup = false;
if (!result) {
records.length = 0;
}
}, {
title: (size > 1 ?
`(${size - records.length}/${size})` : ''),
on_destroy: edit_next_record,
});
}
};
edit_next_record();
}
});
},
+4
View File
@@ -124,6 +124,7 @@
this.domain = kwargs.domain || null;
this.context = kwargs.context || null;
this.save_current = kwargs.save_current;
this.on_destroy = kwargs.on_destroy;
var title_prm = jQuery.when(kwargs.title || '').then(
title => {
if (screen.breadcrumb.length) {
@@ -683,6 +684,9 @@
this.screen.switch_view(this.prev_view.view_type);
}
this.el.modal('hide');
if (this.on_destroy) {
this.el.on('hidden.bs.modal', () => this.on_destroy());
}
}
});
+1
View File
@@ -1,3 +1,4 @@
* Edit the selected One2Many rows sequentially
* Support filename extension for Binary field
* Use record name as fallback for filename of Binary field
* Support filters attribute for binary and image widgets
@@ -464,16 +464,28 @@ class One2Many(Widget):
return
if not self._validate():
return
record = self.screen.current_record
if record:
records = list(self.screen.selected_records)
size = len(records)
if records:
if self._popup:
return
else:
self._popup = True
def callback(result):
self._popup = False
WinForm(self.screen, callback, prev_view=self.screen.current_view)
if not result:
records.clear()
def edit_next_record():
if records:
self.screen.current_record = records.pop(0)
self._popup = True
WinForm(
self.screen, callback,
title=('(%s/%s)' % (size - len(records), size)
if size > 1 else ''),
prev_view=self.screen.current_view,
on_destroy=edit_next_record)
edit_next_record()
def _sig_next(self, widget):
if not self._validate():
+5 -1
View File
@@ -24,7 +24,8 @@ class WinForm(NoModal, InfoBar):
def __init__(self, screen, callback=None, view_type='form',
new=False, many=0, domain=None, context=None,
save_current=False, title='', defaults=None, prev_view=SENTINEL):
save_current=False, title='', defaults=None, prev_view=SENTINEL,
on_destroy=None):
tooltips = common.Tooltips()
NoModal.__init__(self)
@@ -37,6 +38,7 @@ class WinForm(NoModal, InfoBar):
self.domain = domain
self.context = context
self.save_current = save_current
self.on_destroy = on_destroy
if screen.breadcrumb:
breadcrumb = list(screen.breadcrumb)
if title:
@@ -528,6 +530,8 @@ class WinForm(NoModal, InfoBar):
if getattr(self, 'win', None):
self.win.destroy()
NoModal.destroy(self)
if self.on_destroy:
self.on_destroy()
def show(self):
self.win.show()