##// END OF EJS Templates
handle the new status messages in IPython.parallel...
handle the new status messages in IPython.parallel avoids creating implicit tasks in the Client’s metadata and Hub’s task db when status messages arrive.

File last commit:

r17216:08b8fbc9
r17264:506c6033
Show More
widget_selectioncontainer.js
267 lines | 10.3 KiB | application/javascript | JavascriptLexer
/ IPython / html / static / widgets / js / widget_selectioncontainer.js
// Copyright (c) IPython Development Team.
// Distributed under the terms of the Modified BSD License.
define([
"widgets/js/widget",
"base/js/utils",
"jquery",
"components/bootstrap/js/bootstrap.min",
], function(widget, utils, $){
var AccordionView = widget.DOMWidgetView.extend({
render: function(){
// Called when view is rendered.
var guid = 'panel-group' + utils.uuid();
this.$el
.attr('id', guid)
.addClass('panel-group');
this.containers = [];
this.model_containers = {};
this.update_children([], this.model.get('children'));
this.model.on('change:children', function(model, value, options) {
this.update_children(model.previous('children'), value);
}, this);
this.model.on('change:selected_index', function(model, value, options) {
this.update_selected_index(model.previous('selected_index'), value, options);
}, this);
this.model.on('change:_titles', function(model, value, options) {
this.update_titles(value);
}, this);
var that = this;
this.on('displayed', function() {
this.update_titles();
// Trigger model displayed events for any models that are child to
// this model when this model is displayed.
that.is_displayed = true;
for (var property in that.child_views) {
if (that.child_views.hasOwnProperty(property)) {
that.child_views[property].trigger('displayed');
}
}
}, this);
},
update_titles: function(titles) {
// Set tab titles
if (!titles) {
titles = this.model.get('_titles');
}
var that = this;
_.each(titles, function(title, page_index) {
var accordian = that.containers[page_index];
if (accordian !== undefined) {
accordian
.find('.panel-heading')
.find('.accordion-toggle')
.text(title);
}
});
},
update_selected_index: function(old_index, new_index, options) {
// Only update the selection if the selection wasn't triggered
// by the front-end. It must be triggered by the back-end.
if (options === undefined || options.updated_view != this) {
this.containers[old_index].find('.panel-collapse').collapse('hide');
if (0 <= new_index && new_index < this.containers.length) {
this.containers[new_index].find('.panel-collapse').collapse('show');
}
}
},
update_children: function(old_list, new_list) {
// Called when the children list is modified.
this.do_diff(old_list,
new_list,
$.proxy(this.remove_child_model, this),
$.proxy(this.add_child_model, this));
},
remove_child_model: function(model) {
// Called when a child is removed from children list.
var accordion_group = this.model_containers[model.id];
this.containers.splice(accordion_group.container_index, 1);
delete this.model_containers[model.id];
accordion_group.remove();
this.pop_child_view(model);
},
add_child_model: function(model) {
// Called when a child is added to children list.
var view = this.create_child_view(model);
var index = this.containers.length;
var uuid = utils.uuid();
var accordion_group = $('<div />')
.addClass('panel panel-default')
.appendTo(this.$el);
var accordion_heading = $('<div />')
.addClass('panel-heading')
.appendTo(accordion_group);
var that = this;
var accordion_toggle = $('<a />')
.addClass('accordion-toggle')
.attr('data-toggle', 'collapse')
.attr('data-parent', '#' + this.$el.attr('id'))
.attr('href', '#' + uuid)
.click(function(evt){
// Calling model.set will trigger all of the other views of the
// model to update.
that.model.set("selected_index", index, {updated_view: that});
that.touch();
})
.text('Page ' + index)
.appendTo(accordion_heading);
var accordion_body = $('<div />', {id: uuid})
.addClass('panel-collapse collapse')
.appendTo(accordion_group);
var accordion_inner = $('<div />')
.addClass('panel-body')
.appendTo(accordion_body);
var container_index = this.containers.push(accordion_group) - 1;
accordion_group.container_index = container_index;
this.model_containers[model.id] = accordion_group;
accordion_inner.append(view.$el);
this.update();
this.update_titles();
// Trigger the displayed event if this model is displayed.
if (this.is_displayed) {
view.trigger('displayed');
}
},
});
var TabView = widget.DOMWidgetView.extend({
initialize: function() {
// Public constructor.
this.containers = [];
TabView.__super__.initialize.apply(this, arguments);
},
render: function(){
// Called when view is rendered.
var uuid = 'tabs'+utils.uuid();
var that = this;
this.$tabs = $('<div />', {id: uuid})
.addClass('nav')
.addClass('nav-tabs')
.appendTo(this.$el);
this.$tab_contents = $('<div />', {id: uuid + 'Content'})
.addClass('tab-content')
.appendTo(this.$el);
this.containers = [];
this.update_children([], this.model.get('children'));
this.model.on('change:children', function(model, value, options) {
this.update_children(model.previous('children'), value);
}, this);
// Trigger model displayed events for any models that are child to
// this model when this model is displayed.
this.on('displayed', function(){
that.is_displayed = true;
for (var property in that.child_views) {
if (that.child_views.hasOwnProperty(property)) {
that.child_views[property].trigger('displayed');
}
}
});
},
update_children: function(old_list, new_list) {
// Called when the children list is modified.
this.do_diff(old_list,
new_list,
$.proxy(this.remove_child_model, this),
$.proxy(this.add_child_model, this));
},
remove_child_model: function(model) {
// Called when a child is removed from children list.
var view = this.pop_child_view(model);
this.containers.splice(view.parent_tab.tab_text_index, 1);
view.parent_tab.remove();
view.parent_container.remove();
view.remove();
},
add_child_model: function(model) {
// Called when a child is added to children list.
var view = this.create_child_view(model);
var index = this.containers.length;
var uuid = utils.uuid();
var that = this;
var tab = $('<li />')
.css('list-style-type', 'none')
.appendTo(this.$tabs);
view.parent_tab = tab;
var tab_text = $('<a />')
.attr('href', '#' + uuid)
.attr('data-toggle', 'tab')
.text('Page ' + index)
.appendTo(tab)
.click(function (e) {
// Calling model.set will trigger all of the other views of the
// model to update.
that.model.set("selected_index", index, {updated_view: this});
that.touch();
that.select_page(index);
});
tab.tab_text_index = this.containers.push(tab_text) - 1;
var contents_div = $('<div />', {id: uuid})
.addClass('tab-pane')
.addClass('fade')
.append(view.$el)
.appendTo(this.$tab_contents);
view.parent_container = contents_div;
// Trigger the displayed event if this model is displayed.
if (this.is_displayed) {
view.trigger('displayed');
}
},
update: function(options) {
// Update the contents of this view
//
// Called when the model is changed. The model may have been
// changed by another view or by a state update from the back-end.
if (options === undefined || options.updated_view != this) {
// Set tab titles
var titles = this.model.get('_titles');
var that = this;
_.each(titles, function(title, page_index) {
var tab_text = that.containers[page_index];
if (tab_text !== undefined) {
tab_text.text(title);
}
});
var selected_index = this.model.get('selected_index');
if (0 <= selected_index && selected_index < this.containers.length) {
this.select_page(selected_index);
}
}
return TabView.__super__.update.apply(this);
},
select_page: function(index) {
// Select a page.
this.$tabs.find('li')
.removeClass('active');
this.containers[index].tab('show');
},
});
return {
'AccordionView': AccordionView,
'TabView': TabView,
};
});