Ensure consistent treeview rendering by using fixed table-layout

- always use fixed table-layout
- define col for each column with a relative width
- add title to content and header of cells in case of overflow
- remove padding when editing cell
- remove padding and margin on button in treeview

issue7245
review37111002
This commit is contained in:
Cédric Krier committed 2018-03-22 21:49:46 +01:00
1 parent 9ae0b3a4f0
commit 9fffae3358
7 files changed
+86 -72

No files matched your search

+7 -2
View File
@@ -454,8 +454,10 @@ var Sao = {};
jQuery('#menu').append(gs.el);
jQuery('#menu').append(
form.screen.screen_container.content_box.detach());
form.screen.views[0].columns.push(
new FavoriteColumn(form.screen.model.fields.favorite));
var column = new FavoriteColumn(form.screen.model.fields.favorite);
form.screen.views[0].table.find('> colgroup').append(column.col);
form.screen.views[0].table.find('> thead > tr').append(column.header);
form.screen.views[0].columns.push(column);
});
};
Sao.main_menu_screen = null;
@@ -463,6 +465,9 @@ var Sao = {};
var FavoriteColumn = Sao.class_(Object, {
init: function(favorite) {
this.field = favorite;
this.col = jQuery('<col/>', {
'class': 'favorite',
});
this.header = jQuery('<th/>');
this.footers = [];
this.attributes = jQuery.extend({}, this.field.description);
+20 -7
View File
@@ -83,12 +83,16 @@ img.icon {
& > table.tree {
width: 100%;
table-layout: fixed;
& th.selection, td.selection {
& col.selection-state, col.favorite {
width: 30px;
}
& th.selection-state, td.selection-state {
& > input {
.center-block();
}
width: 30px;
}
& > thead > tr > th {
& > label.sortable {
@@ -96,7 +100,6 @@ img.icon {
}
overflow: hidden;
text-overflow: ellipsis;
min-width: 30px;
text-align: center;
&.char, &.text, &.many2one, &.one2one, &.date, &.time, &.selection,
&.reference, &.url, &.email, &.callto, &.sip {
@@ -134,6 +137,13 @@ img.icon {
& td {
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
& td.edited {
/* We have to define an overflow:visible in order for the
completion widget to be shown */
overflow: visible;
padding: 0 0;
}
& td > .column-text {
white-space: pre;
@@ -151,6 +161,13 @@ img.icon {
& label.editable {
font-style: italic;
}
& .btn {
padding-top: 0;
padding-bottom: 0;
margin-top: -@table-condensed-cell-padding;
margin-bottom: -@table-condensed-cell-padding;
}
}
.form {
@@ -315,10 +332,6 @@ input.column-boolean {
}
@media screen and (max-width: @screen-xs-max) {
.treeview.responsive {
/* Override the width from Sao.View.resize */
width: 100% !important;
}
table.responsive,
table.responsive > thead,
table.responsive > thead > tr,
-3
View File
@@ -380,9 +380,6 @@
id: tab.id
}).html(tab.el)
.appendTo(tabcontent);
tab_link.on('shown.bs.tab', function() {
Sao.View.resize(tab.el);
});
tab_link.tab('show');
tabs.trigger('ready');
};
-25
View File
@@ -61,29 +61,4 @@
return new Sao.View.Calendar(screen, xml);
}
};
Sao.View.resize = function(el) {
// Let the browser compute the table size with the fixed layout
// then set this size to the treeview to allow scroll on overflow
// and set the table layout to auto to get the width from the content.
if (!el) {
el = jQuery(document);
}
el.find('.treeview').each(function() {
var treeview = jQuery(this);
treeview.css('width', '100%');
treeview.children('.tree').css('table-layout', 'fixed');
});
el.find('.treeview').each(function() {
var treeview = jQuery(this);
if (treeview.width()) {
treeview.css('width', treeview.width());
treeview.children('.tree').css('table-layout', 'auto');
}
});
};
jQuery(window).resize(function() {
Sao.View.resize();
});
}());
+2 -5
View File
@@ -351,7 +351,6 @@ function eval_pyson(value){
var container = this.containers[j];
container.resize();
}
Sao.View.resize(this.el);
}.bind(this));
},
set_value: function() {
@@ -769,10 +768,8 @@ function eval_pyson(value){
'href': '#' + tab_id
})
.append(img)
.append(text)
.on('shown.bs.tab', function() {
Sao.View.resize(tab);
})).appendTo(this.nav);
.append(text))
.appendTo(this.nav);
pane.html(tab).appendTo(this.panes);
if (!this.selected) {
// Can not use .tab('show')
+57 -27
View File
@@ -77,10 +77,14 @@
this.table.addClass('table-bordered');
}
this.el.append(this.table);
var colgroup = jQuery('<colgroup/>').appendTo(this.table);
var col = jQuery('<col/>', {
'class': 'selection-state',
}).appendTo(colgroup);
this.thead = jQuery('<thead/>').appendTo(this.table);
var tr = jQuery('<tr/>');
var th = jQuery('<th/>', {
'class': 'selection'
'class': 'selection-state'
});
this.selection = jQuery('<input/>', {
'type': 'checkbox',
@@ -101,11 +105,15 @@
}
this.columns.forEach(function(column) {
col = jQuery('<col/>', {
'class': column.attributes.widget,
}).appendTo(colgroup);
th = jQuery('<th/>', {
'class': column.attributes.widget,
});
var label = jQuery('<label/>')
.text(column.attributes.string);
.text(column.attributes.string)
.attr('title', column.attributes.string);
if (this.editable) {
if (column.attributes.required) {
label.addClass('required');
@@ -126,6 +134,7 @@
}
tr.append(th.append(label));
column.header = th;
column.col = col;
column.footers = [];
if (!jQuery.isEmptyObject(this.sum_widgets)) {
@@ -386,6 +395,30 @@
});
}
}
if (column.header.hasClass('invisible')) {
column.col.css('width', 0);
column.col.hide();
} else if (!column.col.hasClass('selection-state') &&
!column.col.hasClass('favorite')) {
var width = {
'integer': 6,
'biginteger': 6,
'float': 8,
'numeric': 8,
'timedelta': 10,
'date': 10,
'datetime': 10,
'time': 10,
'selection': 9,
'char': 10,
'one2many': 5,
'many2many': 5,
'boolean': 2,
'binary': 20,
}[column.attributes.widget] || 10;
column.col.css('width', width * 100 + '%');
}
}.bind(this));
this.tbody.find('tr.more-row > td').attr(
'colspan', visible_columns);
@@ -784,7 +817,7 @@
var td;
this.tree.el.uniqueId();
td = jQuery('<td/>', {
'class': 'selection',
'class': 'selection-state',
});
this.el.append(td);
this.selection = jQuery('<input/>', {
@@ -803,7 +836,6 @@
}).append(jQuery('<span/>', { // For responsive min-height
'aria-hidden': true
}));
td.css('overflow', 'hidden');
td.on('click keypress', {column: i, td: td},
Sao.common.click_press(this.select_row.bind(this),
true));
@@ -1253,16 +1285,6 @@
widget = new EditableBuilder(attributes.name,
this.tree.screen.model, attributes);
widget.view = this.tree;
// We have to define an overflow:visible in order for the
// completion widget to be shown
widget.el.on('focusin', function() {
jQuery(this).parents('.treeview td')
.css('overflow', 'visible');
});
widget.el.on('focusout', function() {
jQuery(this).parents('.treeview td')
.css('overflow', 'hidden');
});
var editable_el = this.get_editable_el();
editable_el.append(widget.el);
editable_el.data('widget', widget);
@@ -1271,7 +1293,8 @@
field = this.record.model.fields[widget.field_name];
widget.display(this.record, field);
this.get_static_el().hide();
this.get_editable_el().show();
widget.el.parents('.treeview td').addClass('edited');
editable_el.show();
widget.focus();
} else if (!selected) {
this.set_selection(true);
@@ -1303,6 +1326,7 @@
editable.empty();
editable.data('widget', null);
this.edited_column = null;
editable.parents('.treeview td').removeClass('edited');
},
get_active_td: function() {
return this._get_column_td(this.edited_column);
@@ -1534,7 +1558,8 @@
return cell;
},
update_text: function(cell, record) {
cell.text(this.field.get_client(record));
var text = this.field.get_client(record);
cell.text(text).attr('title', text);
},
render: function(record, cell) {
if (!cell) {
@@ -1568,7 +1593,8 @@
return Sao.View.Tree.IntegerColumn._super.get_cell.call(this);
},
update_text: function(cell, record) {
cell.text(this.field.get_client(record, this.factor));
var value = this.field.get_client(record, this.factor);
cell.text(value).attr('title', value);
}
});
@@ -1655,7 +1681,7 @@
prm = jQuery.when(text);
}
prm.done(function(text_value) {
cell.text(text_value);
cell.text(text_value).attr('title', text_value);
}.bind(this));
}.bind(this));
}
@@ -1679,7 +1705,7 @@
update_text: function(cell, record) {
this.update_selection(record, function() {
var value = this.field.get_client(record);
var model, name;
var model, name, text;
if (!value) {
model = '';
name = '';
@@ -1694,10 +1720,11 @@
break;
}
}
cell.text(model + ',' + name);
text = model + ',' + name;
} else {
cell.text(name);
text = name;
}
cell.text(text).attr('title', text);
}.bind(this));
}
});
@@ -1707,7 +1734,8 @@
update_text: function(cell, record) {
var value = this.field.get_client(record);
var date_format = this.field.date_format(record);
cell.text(Sao.common.format_date(date_format, value));
var text = Sao.common.format_date(date_format, value);
cell.text(text).attr('title', text);
}
});
@@ -1715,8 +1743,9 @@
class_: 'column-time',
update_text: function(cell, record) {
var value = this.field.get_client(record);
cell.text(Sao.common.format_time(
this.field.time_format(record), value));
var text = Sao.common.format_time(
this.field.time_format(record), value);
cell.text(text).attr('title', text);
}
});
@@ -1727,7 +1756,8 @@
Sao.View.Tree.One2ManyColumn = Sao.class_(Sao.View.Tree.CharColumn, {
class_: 'column-one2many',
update_text: function(cell, record) {
cell.text('( ' + this.field.get_client(record).length + ' )');
var text = '( ' + this.field.get_client(record).length + ' )';
cell.text(text).attr('title', text);
}
});
@@ -1754,7 +1784,7 @@
size = this.field.get(record).length;
}
var text = size? Sao.common.humanize(size) : '';
cell.children('span').text(text);
cell.children('span').text(text).attr('title', text);
var button = cell.children('button');
if (!button.length) {
button = jQuery('<button/>', {
@@ -1876,7 +1906,7 @@
var progressbar = cell.find('.progress-bar');
progressbar.attr('aria-valuenow', value * 100);
progressbar.css('width', value * 100 + '%');
progressbar.text(text);
progressbar.text(text).attr('title', text);
}
});
-3
View File
@@ -217,9 +217,6 @@
Sao.Wizard.Dialog._super.init.call(this);
var dialog = new Sao.Dialog(name, 'wizard-dialog', 'lg');
this.dialog = dialog.modal;
this.dialog.on('shown.bs.modal', function () {
Sao.View.resize(jQuery(this));
});
this.content = dialog.content;
this.footer = dialog.footer;
dialog.body.append(this.widget).append(this.info_bar.el);