diff --git a/addons/web/static/src/css/base.css b/addons/web/static/src/css/base.css
index 434ee9377ab..295f2689a6d 100644
--- a/addons/web/static/src/css/base.css
+++ b/addons/web/static/src/css/base.css
@@ -2477,6 +2477,19 @@
.openerp .oe_list_content .numeric input {
text-align: right;
}
+.openerp .oe_list_content .oe_list_field_handle {
+ width: 1em;
+}
+.openerp .oe_list_content .oe_list_field_handle .oe_list_handle {
+ font-size: 1px;
+ letter-spacing: -1px;
+ color: transparent;
+}
+.openerp .oe_list_content .oe_list_field_handle .oe_list_handle:before {
+ font: 21px "mnmliconsRegular";
+ content: "ö";
+ color: #404040;
+}
.openerp .tree_header {
background-color: #f0f0f0;
border-bottom: 1px solid #cacaca;
diff --git a/addons/web/static/src/css/base.sass b/addons/web/static/src/css/base.sass
index 949befdef77..8005449b226 100644
--- a/addons/web/static/src/css/base.sass
+++ b/addons/web/static/src/css/base.sass
@@ -1926,6 +1926,11 @@ $sheet-max-width: 860px
width: 82px
input
text-align: right
+ .oe_list_field_handle
+ width: 1em
+ .oe_list_handle
+ @include text-to-icon("ö")
+
// }}}
// Tree view {{{
.tree_header
diff --git a/addons/web/static/src/js/formats.js b/addons/web/static/src/js/formats.js
index 6ceb7090e44..6aae9677ec4 100644
--- a/addons/web/static/src/js/formats.js
+++ b/addons/web/static/src/js/formats.js
@@ -343,6 +343,8 @@ instance.web.format_cell = function (row_data, column, options) {
'', {
value: _.str.sprintf("%.0f", row_data[column.id].value || 0)
});
+ case 'handle':
+ return '
';
}
return _.escape(instance.web.format_value(
diff --git a/addons/web/static/src/js/view_list.js b/addons/web/static/src/js/view_list.js
index 4bce8d639f8..d78a732fc58 100644
--- a/addons/web/static/src/js/view_list.js
+++ b/addons/web/static/src/js/view_list.js
@@ -1468,18 +1468,31 @@ instance.web.ListView.Groups = instance.web.Class.extend( /** @lends instance.we
},
setup_resequence_rows: function (list, dataset) {
// drag and drop enabled if list is not sorted and there is a
- // "sequence" column in the view.
+ // visible column with @widget=handle or "sequence" column in the view.
if ((dataset.sort && dataset.sort())
|| !_(this.columns).any(function (column) {
- return column.name === 'sequence'; })) {
+ return column.widget === 'handle'
+ || column.name === 'sequence'; })) {
return;
}
+ var sequence_field = _(this.columns).find(function (c) {
+ return c.widget === 'handle';
+ });
+ var seqname = sequence_field ? sequence_field.name : 'sequence';
+
// ondrop, move relevant record & fix sequences
list.$current.sortable({
axis: 'y',
items: '> tr[data-id]',
- containment: 'parent',
- helper: 'clone',
+ helper: 'clone'
+ });
+ if (sequence_field) {
+ list.$current.sortable('option', 'handle', '.oe_list_field_handle');
+ }
+ list.$current.sortable('option', {
+ start: function (e, ui) {
+ ui.placeholder.height(ui.item.height());
+ },
stop: function (event, ui) {
var to_move = list.records.get(ui.item.data('id')),
target_id = ui.item.prev().data('id'),
@@ -1497,7 +1510,7 @@ instance.web.ListView.Groups = instance.web.Class.extend( /** @lends instance.we
var record, index = to,
// if drag to 1st row (to = 0), start sequencing from 0
// (exclusive lower bound)
- seq = to ? list.records.at(to - 1).get('sequence') : 0;
+ seq = to ? list.records.at(to - 1).get(seqname) : 0;
while (++seq, record = list.records.at(index++)) {
// write are independent from one another, so we can just
// launch them all at the same time and we don't really
@@ -1507,10 +1520,12 @@ instance.web.ListView.Groups = instance.web.Class.extend( /** @lends instance.we
// when synchronous (without setTimeout)
(function (dataset, id, seq) {
$.async_when().then(function () {
- dataset.write(id, {sequence: seq});
+ var attrs = {};
+ attrs[seqname] = seq;
+ dataset.write(id, attrs);
});
}(dataset, record.get('id'), seq));
- record.set('sequence', seq);
+ record.set(seqname, seq);
}
}
});