mirror of
https://github.com/jupyter/notebook.git
synced 2025-01-06 11:35:24 +08:00
streamline tree-selector menu using checkboxes
streamlines the menu from #7667 with - Shorter text, with icons. - Main checkbox no longer opens the dropdown. Instead it just selects all/none. - Fewer menu items but more actions possible by adding checkboxes in the menu - Menu stays open until clicking outside. This obviously needs CSS tweaking
This commit is contained in:
parent
2aac3e913a
commit
3578e8f1e5
@ -122,12 +122,9 @@ define([
|
|||||||
$('.delete-button').click($.proxy(this.delete_selected, this));
|
$('.delete-button').click($.proxy(this.delete_selected, this));
|
||||||
|
|
||||||
// Bind events for selection menu buttons.
|
// Bind events for selection menu buttons.
|
||||||
$('#tree-selector .select-all').click($.proxy(this.select_all, this));
|
$('.tree-selector').change(function(){that.select($(this).attr('id'),$(this).is(':checked'))});
|
||||||
$('#tree-selector .select-notebooks').click($.proxy(this.select_notebooks, this));
|
// Do not propagate click for the menu to prevent the menu from closing
|
||||||
$('#tree-selector .select-running-notebooks').click($.proxy(this.select_running_notebooks, this));
|
$('#tree-selector-menu').click(function(event){event.stopPropagation();})
|
||||||
$('#tree-selector .select-files').click($.proxy(this.select_files, this));
|
|
||||||
$('#tree-selector .select-directories').click($.proxy(this.select_directories, this));
|
|
||||||
$('#tree-selector .deselect-all').click($.proxy(this.deselect_all, this));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -382,113 +379,84 @@ define([
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Select all of the items in the tree.
|
* Select items in the tree of specified kind.
|
||||||
|
* checkbox_id : string among "select-all, "select-folders", "select-notebooks", "select-running-notebooks", "select-files"
|
||||||
|
* state : boolean, true to select and false to deselect
|
||||||
*/
|
*/
|
||||||
NotebookList.prototype.select_all = function() {
|
NotebookList.prototype.select = function(checkbox_id,state) {
|
||||||
$('.list_item input[type=checkbox]').each(function(index, item) {
|
|
||||||
$(item).prop('checked', true);
|
|
||||||
});
|
|
||||||
this._selection_changed();
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Select all of the notebooks in the tree.
|
|
||||||
*/
|
|
||||||
NotebookList.prototype.select_notebooks = function() {
|
|
||||||
this.deselect_all();
|
|
||||||
$('.list_item').each(function(index, item) {
|
|
||||||
if ($(item).data('type') === 'notebook') {
|
|
||||||
$(item).find('input[type=checkbox]').prop('checked', true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this._selection_changed();
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Select all of the running notebooks in the tree.
|
|
||||||
*/
|
|
||||||
NotebookList.prototype.select_running_notebooks = function() {
|
|
||||||
this.deselect_all();
|
|
||||||
var that = this;
|
var that = this;
|
||||||
$('.list_item').each(function(index, item) {
|
$('.list_item').each(function(index, item) {
|
||||||
if ($(item).data('type') === 'notebook' && that.sessions[$(item).data('path')] !== undefined) {
|
// For each item, determine if the state should be set, depending on the checkbox_id that triggered select
|
||||||
$(item).find('input[type=checkbox]').prop('checked', true);
|
var set_state = (checkbox_id === "select-all");
|
||||||
|
set_state = set_state || (checkbox_id === "select-folders" && $(item).data('type') === 'directory');
|
||||||
|
set_state = set_state || (checkbox_id === "select-notebooks" && $(item).data('type') === 'notebook');
|
||||||
|
set_state = set_state || (checkbox_id === "select-running-notebooks" && $(item).data('type') === 'notebook' && that.sessions[$(item).data('path')] !== undefined);
|
||||||
|
set_state = set_state || (checkbox_id === "select-files" && $(item).data('type') === 'file');
|
||||||
|
if (set_state) {
|
||||||
|
$(item).find('input[type=checkbox]').prop('checked', state);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this._selection_changed();
|
this._selection_changed();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Select all of the files in the tree.
|
|
||||||
*/
|
|
||||||
NotebookList.prototype.select_files = function() {
|
|
||||||
this.deselect_all();
|
|
||||||
$('.list_item').each(function(index, item) {
|
|
||||||
if ($(item).data('type') === 'file') {
|
|
||||||
$(item).find('input[type=checkbox]').prop('checked', true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this._selection_changed();
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Select all of the directories in the tree.
|
|
||||||
*/
|
|
||||||
NotebookList.prototype.select_directories = function() {
|
|
||||||
this.deselect_all();
|
|
||||||
$('.list_item').each(function(index, item) {
|
|
||||||
if ($(item).data('type') === 'directory') {
|
|
||||||
$(item).find('input[type=checkbox]').prop('checked', true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this._selection_changed();
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unselect everything selected in the tree.
|
|
||||||
*/
|
|
||||||
NotebookList.prototype.deselect_all = function() {
|
|
||||||
$('.list_item input[type=checkbox]').each(function(index, item) {
|
|
||||||
$(item).prop('checked', false);
|
|
||||||
});
|
|
||||||
this._selection_changed();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles when any row selector checkbox is toggled.
|
* Handles when any row selector checkbox is toggled.
|
||||||
*/
|
*/
|
||||||
NotebookList.prototype._selection_changed = function() {
|
NotebookList.prototype._selection_changed = function() {
|
||||||
// Use a JQuery selector to find each row with a checked checkbox. If
|
// Use a JQuery selector to find each row with a checkbox. If
|
||||||
// we decide to add more checkboxes in the future, this code will need
|
// we decide to add more checkboxes in the future, this code will need
|
||||||
// to be changed to distinguish which checkbox is the row selector.
|
// to be changed to distinguish which checkbox is the row selector.
|
||||||
var selected = [];
|
var selected = [];
|
||||||
var has_running_notebook = false;
|
var num_sel_notebook = 0;
|
||||||
var has_directory = false;
|
var num_sel_running_notebook = 0;
|
||||||
var has_file = false;
|
var num_sel_directory = 0;
|
||||||
|
var num_sel_file = 0;
|
||||||
|
var num_notebook = 0;
|
||||||
|
var num_running_notebook = 0;
|
||||||
|
var num_directory = 0;
|
||||||
|
var num_file = 0;
|
||||||
var that = this;
|
var that = this;
|
||||||
var checked = 0;
|
$('.list_item input[type=checkbox]').each(function(index, item) {
|
||||||
$('.list_item :checked').each(function(index, item) {
|
|
||||||
var parent = $(item).parent().parent();
|
var parent = $(item).parent().parent();
|
||||||
|
|
||||||
// If the item doesn't have an upload button and it's not the
|
// If the item doesn't have an upload button and it's not the
|
||||||
// breadcrumbs, it can be selected. Breadcrumbs path == ''.
|
// breadcrumbs, it can be selected. Breadcrumbs path == ''.
|
||||||
if (parent.find('.upload_button').length === 0 && parent.data('path') !== '') {
|
if (parent.find('.upload_button').length === 0 && parent.data('path') !== '') {
|
||||||
checked++;
|
if (parent.data('type') == 'notebook') {
|
||||||
selected.push({
|
num_notebook++;
|
||||||
|
if (that.sessions[parent.data('path')] !== undefined) {
|
||||||
|
num_running_notebook++;
|
||||||
|
}
|
||||||
|
} else if (parent.data('type') == 'file') {
|
||||||
|
num_file++;
|
||||||
|
} else if (parent.data('type') == 'directory') {
|
||||||
|
num_directory++;
|
||||||
|
}
|
||||||
|
if ($(item).is(':checked')) {
|
||||||
|
selected.push({
|
||||||
name: parent.data('name'),
|
name: parent.data('name'),
|
||||||
path: parent.data('path'),
|
path: parent.data('path'),
|
||||||
type: parent.data('type')
|
type: parent.data('type')
|
||||||
});
|
});
|
||||||
|
if (parent.data('type') == 'notebook') {
|
||||||
// Set flags according to what is selected. Flags are later
|
num_sel_notebook++;
|
||||||
// used to decide which action buttons are visible.
|
if (that.sessions[parent.data('path')] !== undefined) {
|
||||||
has_running_notebook = has_running_notebook ||
|
num_sel_running_notebook++;
|
||||||
(parent.data('type') == 'notebook' && that.sessions[parent.data('path')] !== undefined);
|
}
|
||||||
has_file = has_file || parent.data('type') == 'file';
|
} else if (parent.data('type') == 'file') {
|
||||||
has_directory = has_directory || parent.data('type') == 'directory';
|
num_sel_file++;
|
||||||
|
} else if (parent.data('type') == 'directory') {
|
||||||
|
num_sel_directory++;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Set flags according to what is selected. Flags are later
|
||||||
|
// used to decide which action buttons are visible.
|
||||||
|
var has_running_notebook = num_sel_running_notebook > 0;
|
||||||
|
var has_directory = num_sel_directory > 0;
|
||||||
|
var has_file = num_sel_file > 0;
|
||||||
this.selected = selected;
|
this.selected = selected;
|
||||||
|
|
||||||
// Rename is only visible when one item is selected.
|
// Rename is only visible when one item is selected.
|
||||||
@ -521,26 +489,23 @@ define([
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If all of the items are selected, show the selector as checked. If
|
// If all of the items are selected, show the selector as checked. If
|
||||||
// some of the items are selected, show it as checked. Otherwise,
|
// some of the items are selected, show it as indeterminate. Otherwise,
|
||||||
// uncheck it.
|
// uncheck it.
|
||||||
var total = 0;
|
var checkbox_ids = ['select-all','select-folders','select-notebooks','select-running-notebooks','select-files'];
|
||||||
$('.list_item input[type=checkbox]').each(function(index, item) {
|
var total_nums = [num_file+num_directory+num_notebook, num_directory, num_notebook, num_running_notebook, num_file];
|
||||||
var parent = $(item).parent().parent();
|
var selected_nums = [num_sel_file+num_sel_directory+num_sel_notebook, num_sel_directory, num_sel_notebook, num_sel_running_notebook, num_sel_file];
|
||||||
// If the item doesn't have an upload button and it's not the
|
|
||||||
// breadcrumbs, it can be selected. Breadcrumbs path == ''.
|
for (var i=0; i < 5; i++) {
|
||||||
if (parent.find('.upload_button').length === 0 && parent.data('path') !== '') {
|
if (selected_nums[i] === 0) {
|
||||||
total++;
|
$('#'+checkbox_ids[i])[0].indeterminate = false;
|
||||||
|
$('#'+checkbox_ids[i]).prop('checked', false);
|
||||||
|
} else if (selected_nums[i] === total_nums[i]) {
|
||||||
|
$('#'+checkbox_ids[i])[0].indeterminate = false;
|
||||||
|
$('#'+checkbox_ids[i]).prop('checked', true);
|
||||||
|
} else {
|
||||||
|
$('#'+checkbox_ids[i]).prop('checked', false);
|
||||||
|
$('#'+checkbox_ids[i])[0].indeterminate = true;
|
||||||
}
|
}
|
||||||
});
|
|
||||||
if (checked === 0) {
|
|
||||||
$('#tree-selector input[type=checkbox]')[0].indeterminate = false;
|
|
||||||
$('#tree-selector input[type=checkbox]').prop('checked', false);
|
|
||||||
} else if (checked === total) {
|
|
||||||
$('#tree-selector input[type=checkbox]')[0].indeterminate = false;
|
|
||||||
$('#tree-selector input[type=checkbox]').prop('checked', true);
|
|
||||||
} else {
|
|
||||||
$('#tree-selector input[type=checkbox]').prop('checked', false);
|
|
||||||
$('#tree-selector input[type=checkbox]')[0].indeterminate = true;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -76,19 +76,41 @@ data-terminals-available="{{terminals_available}}"
|
|||||||
</div>
|
</div>
|
||||||
<div id="notebook_list">
|
<div id="notebook_list">
|
||||||
<div id="notebook_list_header" class="row list_header">
|
<div id="notebook_list_header" class="row list_header">
|
||||||
<div class="dropdown" id='tree-selector'>
|
<div class="btn-group dropdown" id='tree-selector'>
|
||||||
|
<button type="button" class="btn btn-default btn-xs"><input type="checkbox" class="tree-selector" id="select-all"></input></button>
|
||||||
<button class="btn btn-default btn-xs dropdown-toggle" type="button" id="tree-selector-btn" data-toggle="dropdown" aria-expanded="true">
|
<button class="btn btn-default btn-xs dropdown-toggle" type="button" id="tree-selector-btn" data-toggle="dropdown" aria-expanded="true">
|
||||||
<input type='checkbox'></input>
|
|
||||||
<span class="caret"></span>
|
<span class="caret"></span>
|
||||||
|
<span class="sr-only">Toggle Dropdown</span>
|
||||||
</button>
|
</button>
|
||||||
<ul class="dropdown-menu" role="menu" aria-labelledby="tree-selector-btn">
|
<ul id="tree-selector-menu" class="dropdown-menu" role="menu" aria-labelledby="tree-selector-btn">
|
||||||
<li role="presentation" class="select-all"><a role="menuitem" tabindex="-1" href="#">Select all</a></li>
|
<li role="presentation">
|
||||||
<li role="presentation" class="select-notebooks"><a role="menuitem" tabindex="-1" href="#">Select notebooks</a></li>
|
<input type="checkbox" class="tree-selector" id="select-folders"></input>
|
||||||
<li role="presentation" class="select-running-notebooks"><a role="menuitem" tabindex="-1" href="#">Select running notebooks</a></li>
|
<label for="select-folders">
|
||||||
<li role="presentation" class="select-files"><a role="menuitem" tabindex="-1" href="#">Select files</a></li>
|
<i class="item_icon folder_icon icon-fixed-width"></i>
|
||||||
<li role="presentation" class="select-directories"><a role="menuitem" tabindex="-1" href="#">Select directories</a></li>
|
Folders
|
||||||
<li role="presentation" class="divider"></li>
|
</label>
|
||||||
<li role="presentation" class="deselect-all"><a role="menuitem" tabindex="-1" href="#">Deselect all</a></li>
|
</li>
|
||||||
|
<li role="presentation">
|
||||||
|
<input type="checkbox" class="tree-selector" id="select-notebooks"></input>
|
||||||
|
<label for="select-notebooks">
|
||||||
|
<i class="item_icon notebook_icon icon-fixed-width"></i>
|
||||||
|
All Notebooks
|
||||||
|
</label>
|
||||||
|
</li>
|
||||||
|
<li role="presentation">
|
||||||
|
<input type="checkbox" class="tree-selector" id="select-running-notebooks"></input>
|
||||||
|
<label for="select-running-notebooks">
|
||||||
|
<i class="item_icon running_notebook_icon icon-fixed-width"></i>
|
||||||
|
Running
|
||||||
|
</label>
|
||||||
|
</li>
|
||||||
|
<li role="presentation">
|
||||||
|
<input type="checkbox" class="tree-selector" id="select-files"></input>
|
||||||
|
<label for="select-files">
|
||||||
|
<i class="item_icon file_icon icon-fixed-width"></i>
|
||||||
|
Files
|
||||||
|
</label>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div id="project_name">
|
<div id="project_name">
|
||||||
|
Loading…
Reference in New Issue
Block a user