fix: MultiSelectDialog UX

- Made results area header sticky
- Added persistence.

Co-Authored-By: Shivam Mishra <scmmishra@users.noreply.github.com>
This commit is contained in:
marination 2020-01-31 11:50:16 +05:30
parent 69b76bfbbf
commit 4eb092760e
2 changed files with 38 additions and 12 deletions

View file

@ -163,6 +163,7 @@ frappe.ui.form.MultiSelectDialog = Class.extend({
},
get_checked_values: function() {
// Return name of checked value.
return this.$results.find('.list-item-container').map(function() {
if ($(this).find('.list-row-check:checkbox:checked').length > 0 ) {
return $(this).attr('data-item-name');
@ -170,6 +171,12 @@ frappe.ui.form.MultiSelectDialog = Class.extend({
}).get();
},
get_checked_items: function() {
// Return checked items with all the column values.
let checked_values = this.get_checked_values();
return this.results.filter(res => checked_values.includes(res.name));
},
make_list_row: function(result={}) {
var me = this;
// Make a head row by default (if result not passed)
@ -206,18 +213,17 @@ frappe.ui.form.MultiSelectDialog = Class.extend({
${contents}
</div>`);
head ? $row.addClass('list-item--head')
: $row = $(`<div class="list-item-container" data-item-name="${result.name}"></div>`).append($row);
return $row;
},
render_result_list: function(results, more = 0) {
render_result_list: function(results, more = 0, empty=true) {
var me = this;
var more_btn = me.dialog.fields_dict.more_btn.$wrapper;
// Make empty result set if filter is set
if (!frappe.flags.auto_scroll) {
if (!frappe.flags.auto_scroll && empty) {
this.empty_list();
}
more_btn.hide();
@ -225,9 +231,13 @@ frappe.ui.form.MultiSelectDialog = Class.extend({
if (results.length === 0) return;
if (more) more_btn.show();
results.forEach((result) => {
me.$results.append(me.make_list_row(result));
});
let checked = this.get_checked_values();
results
.filter(result => !checked.includes(result.name))
.forEach(result => {
me.$results.append(me.make_list_row(result));
});
if (frappe.flags.auto_scroll) {
this.$results.animate({scrollTop: me.$results.prop('scrollHeight')}, 500);
@ -235,7 +245,14 @@ frappe.ui.form.MultiSelectDialog = Class.extend({
},
empty_list: function() {
let checked = this.get_checked_items().map(item => {
return {
...item,
checked: true
}
});
this.$results.find('.list-item-container').remove();
this.render_result_list(checked, 0, false);
},
get_results: function() {
@ -278,7 +295,8 @@ frappe.ui.form.MultiSelectDialog = Class.extend({
no_spinner: true,
args: args,
callback: function(r) {
let results = [], more = 0;
let more = 0;
me.results = [];
if (r.values.length) {
if (r.values.length > me.page_length) {
r.values.pop();
@ -290,22 +308,22 @@ frappe.ui.form.MultiSelectDialog = Class.extend({
}
result.checked = 0;
result.parsed_date = Date.parse(result["Date"]);
results.push(result);
me.results.push(result);
});
results.map( (result) => {
me.results.map( (result) => {
result["Date"] = frappe.format(result["Date"], {"fieldtype":"Date"});
})
results.sort((a, b) => {
me.results.sort((a, b) => {
return a.parsed_date - b.parsed_date;
});
// Preselect oldest entry
if (me.start < 1 && r.values.length === 1) {
results[0].checked = 1;
me.results[0].checked = 1;
}
}
me.render_result_list(results, more);
me.render_result_list(me.results, more);
}
});
},

View file

@ -525,6 +525,14 @@ input.list-check-all, input.list-row-checkbox {
// list view
.modal-body {
.list-item--head {
position: sticky !important;
z-index: 500;
top: 0;
}
}
.list-items {
width: 100%;
}