diff --git a/program/js/app.js b/program/js/app.js index 8835e8e2d..dd775c4bd 100644 --- a/program/js/app.js +++ b/program/js/app.js @@ -5744,7 +5744,7 @@ function rcube_webmail() source = this.env.source ? this.env.address_sources[this.env.source] : null; // we don't have dblclick handler here, so use 50 instead of this.dblclick_time - if (this.env.contentframe && (id = list.get_single_selection())) + if (this.env.contentframe && !list.multi_selecting && (id = list.get_single_selection())) this.preview_timer = setTimeout(function(){ ref.load_contact(id, 'show'); }, 50); else if (this.env.contentframe) this.show_contentframe(false); diff --git a/program/js/list.js b/program/js/list.js index 20e85d413..a52cc9ed6 100644 --- a/program/js/list.js +++ b/program/js/list.js @@ -62,6 +62,7 @@ function rcube_list_widget(list, p) this.toggleselect = false; this.aria_listbox = false; this.parent_focus = true; + this.checkbox_selection = false; this.drag_active = false; this.col_drag_active = false; @@ -189,7 +190,7 @@ init_row: function(row) $(row) .attr('role', 'option') .attr('aria-labelledby', lbl_id) - .find(this.col_tagname()).eq(this.subject_col).attr('id', lbl_id); + .find(this.col_tagname()).eq(this.subject_column()).attr('id', lbl_id); } if (document.all) @@ -380,6 +381,27 @@ insert_row: function(row, before) row = domrow; } + if (this.checkbox_selection) { + var cell = document.createElement(this.col_tagname()), + chbox = document.createElement('input'); + + chbox.type = 'checkbox'; + chbox.onchange = function(e) { + self.select_row(row.uid, CONTROL_KEY, true); + e.stopPropagation(); + }; + cell.className = 'selection'; + cell.onclick = function(e) { + // this event handler fixes checkbox selection on touch devices + if (e.target.nodeName != 'INPUT') + chbox.click(); + e.stopPropagation(); + }; + cell.appendChild(chbox); + + row.insertBefore(cell, row.firstChild); + } + if (before && tbody.childNodes.length) tbody.insertBefore(row, (typeof before == 'object' && before.parentNode == tbody) ? before : tbody.firstChild); else @@ -437,7 +459,7 @@ focus: function(e) var focus_elem = null; if (this.last_selected && this.rows[this.last_selected]) { - focus_elem = $(this.rows[this.last_selected].obj).find(this.col_tagname()).eq(this.subject_col).attr('tabindex', '0'); + focus_elem = $(this.rows[this.last_selected].obj).find(this.col_tagname()).eq(this.subject_column()).attr('tabindex', '0'); } // Un-focus already focused elements (#1487123, #1487316, #1488600, #1488620) @@ -472,7 +494,7 @@ blur: function(e) if (this.last_selected && this.rows[this.last_selected]) { $(this.rows[this.last_selected].obj) - .find(this.col_tagname()).eq(this.subject_col).removeAttr('tabindex'); + .find(this.col_tagname()).eq(this.subject_column()).removeAttr('tabindex'); } $(this.list).removeClass('focus'); @@ -971,7 +993,7 @@ select_row: function(id, mod_key, with_mouse) if (this.last_selected && this.rows[this.last_selected]) { $(this.rows[this.last_selected].obj).removeClass('focused') - .find(this.col_tagname()).eq(this.subject_col).removeAttr('tabindex'); + .find(this.col_tagname()).eq(this.subject_column()).removeAttr('tabindex'); } // unselect if toggleselect is active and the same row was clicked again @@ -987,7 +1009,7 @@ select_row: function(id, mod_key, with_mouse) $(this.rows[id].obj).addClass('focused'); // set cursor focus to link inside selected row if (this.focused) - this.focus_noscroll($(this.rows[id].obj).find(this.col_tagname()).eq(this.subject_col).attr('tabindex', '0')); + this.focus_noscroll($(this.rows[id].obj).find(this.col_tagname()).eq(this.subject_column()).attr('tabindex', '0')); } if (!this.selection.length) @@ -1199,6 +1221,9 @@ clear_selection: function(id, no_event) this.selection = []; } + if (this.checkbox_selection) + $(this.row_tagname() + ':not(.selected) > .selection > input:checked', this.list).prop('checked', false); + if (num_select && !this.selection.length && !no_event) { this.triggerEvent('select'); this.last_selected = null; @@ -1257,6 +1282,9 @@ highlight_row: function(id, multiple, norecur) this.clear_selection(null, true); this.selection[0] = id; $(this.rows[id].obj).addClass('selected').attr('aria-selected', 'true'); + + if (this.checkbox_selection) + $('.selection > input', this.rows[id].obj).prop('checked', true); } } else { @@ -1265,6 +1293,10 @@ highlight_row: function(id, multiple, norecur) if (p === false) { // select row this.selection.push(id); $(this.rows[id].obj).addClass('selected').attr('aria-selected', 'true'); + + if (this.checkbox_selection) + $('.selection > input', this.rows[id].obj).prop('checked', true); + if (!norecur && !this.rows[id].expanded) this.highlight_children(id, true); } @@ -1274,6 +1306,10 @@ highlight_row: function(id, multiple, norecur) this.selection = pre.concat(post); $(this.rows[id].obj).removeClass('selected').removeAttr('aria-selected'); + + if (this.checkbox_selection) + $('.selection > input', this.rows[id].obj).prop('checked', false); + if (!norecur && !this.rows[id].expanded) this.highlight_children(id, false); } @@ -1529,8 +1565,10 @@ drag_mouse_move: function(e) return false; } + var subject_col = self.subject_column(); + $('> ' + self.col_tagname(), self.rows[uid].obj).each(function(n, cell) { - if (self.subject_col < 0 || (self.subject_col >= 0 && self.subject_col == n)) { + if (subject_col < 0 || (subject_col >= 0 && subject_col == n)) { // remove elements marked with "skip-on-drag" class cell = $(cell).clone(); $(cell).find('.skip-on-drag').remove(); @@ -1824,6 +1862,11 @@ column_replace: function(from, to) this.init_header(); this.triggerEvent('column_replace'); +}, + +subject_column: function() +{ + return this.subject_col + (this.checkbox_selection ? 1 : 0); } };