##// END OF EJS Templates
Modifies Contents API to return Error objects...
Modifies Contents API to return Error objects Modfies the Contents class to return JavaScript Error objects instead of passing on the return values from $.ajax(). This has two advantages. First, it allows the content manager to parse errors and give more informative messages than the ajax response. Second, it makes the Contents interface more general, since other kinds of backends might generate client-side errors.

File last commit:

r18267:d4de7b72 merge
r18661:d632dcb6
Show More
widget_int.js
455 lines | 17.8 KiB | application/javascript | JavascriptLexer
Jonathan Frederic
Almost done!...
r17198 // Copyright (c) IPython Development Team.
// Distributed under the terms of the Modified BSD License.
Jonathan Frederic
Added standard IPY JS header to widget JS files.
r14366
Jonathan Frederic
Almost done!...
r17198 define([
"widgets/js/widget",
Jonathan Frederic
Fix all the tests
r17216 "jqueryui",
Gordon Ball
Require base/js/keyboard and use keycode.enter
r18079 "base/js/keyboard",
"bootstrap"
], function(widget, $, keyboard){
Jonathan Frederic
Almost done!...
r17198
var IntSliderView = widget.DOMWidgetView.extend({
Jonathan Frederic
Move js *RangeWidget code into *Widget
r14672 render : function(){
// Called when view is rendered.
this.$el
Jason Grout
Add semantic classes to top-level containers for single widgets...
r18120 .addClass('widget-hbox widget-slider');
Jonathan Frederic
Move js *RangeWidget code into *Widget
r14672 this.$label = $('<div />')
.appendTo(this.$el)
Jonathan Frederic
Cleaned up hbox and vbox widget div styles,...
r17929 .addClass('widget-label')
Jonathan Frederic
Move js *RangeWidget code into *Widget
r14672 .hide();
Brian E. Granger
Adding initial version of readout to sliders.
r14982
Jonathan Frederic
Move js *RangeWidget code into *Widget
r14672 this.$slider = $('<div />')
.slider({})
.addClass('slider');
// Put the slider in a container
this.$slider_container = $('<div />')
.addClass('widget-hslider')
Jonathan Frederic
Add latex support in widget labels,...
r16817 .append(this.$slider);
Jonathan Frederic
Move js *RangeWidget code into *Widget
r14672 this.$el.append(this.$slider_container);
Brian E. Granger
Adding initial version of readout to sliders.
r14982 this.$readout = $('<div/>')
.appendTo(this.$el)
Jonathan Frederic
Remove forgotten hreadout
r17932 .addClass('widget-readout')
Gordon Ball
Use contentEditable to allow modification via the the slider readout
r17952 .attr('contentEditable', true)
Brian E. Granger
Adding initial version of readout to sliders.
r14982 .hide();
Jonathan Frederic
Partial implementation of styles
r17723
this.model.on('change:slider_color', function(sender, value) {
this.$slider.find('a').css('background', value);
}, this);
Jonathan Frederic
Fix slidercolor on widget construction
r17948 this.$slider.find('a').css('background', this.model.get('slider_color'));
Brian E. Granger
Adding initial version of readout to sliders.
r14982
Jonathan Frederic
Move js *RangeWidget code into *Widget
r14672 // Set defaults.
this.update();
},
Jonathan Frederic
Partial implementation of styles
r17723
update_attr: function(name, value) {
// Set a css attr of the widget view.
if (name == 'color') {
this.$readout.css(name, value);
} else if (name.substring(0, 4) == 'font') {
this.$readout.css(name, value);
} else if (name.substring(0, 6) == 'border') {
this.$slider.find('a').css(name, value);
this.$slider_container.css(name, value);
} else if (name == 'width' || name == 'height' || name == 'background') {
this.$slider_container.css(name, value);
} else {
this.$slider.css(name, value);
}
},
Jonathan Frederic
Move js *RangeWidget code into *Widget
r14672
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) {
// JQuery slider option keys. These keys happen to have a
// one-to-one mapping with the corrosponding keys of the model.
Jonathan Frederic
Fix infinite loop typo
r17967 var jquery_slider_keys = ['step', 'disabled'];
Jonathan Frederic
Fixed context errors and a couple of typos to get the tests working again
r14686 var that = this;
Jonathan Frederic
Bug fixes
r17175 that.$slider.slider({});
Jonathan Frederic
Move js *RangeWidget code into *Widget
r14672 _.each(jquery_slider_keys, function(key, i) {
Jonathan Frederic
Fixed context errors and a couple of typos to get the tests working again
r14686 var model_value = that.model.get(key);
Jonathan Frederic
Move js *RangeWidget code into *Widget
r14672 if (model_value !== undefined) {
Jonathan Frederic
Fixed context errors and a couple of typos to get the tests working again
r14686 that.$slider.slider("option", key, model_value);
Jonathan Frederic
Move js *RangeWidget code into *Widget
r14672 }
});
Jonathan Frederic
Fix infinite loop typo
r17967
var max = this.model.get('max');
var min = this.model.get('min');
if (min <= max) {
if (max !== undefined) this.$slider.slider('option', 'max', max);
if (min !== undefined) this.$slider.slider('option', 'min', min);
}
Gordon Ball
Change `range` trait to `_range`
r17703 var range_value = this.model.get("_range");
if (range_value !== undefined) {
this.$slider.slider("option", "range", range_value);
}
Jonathan Frederic
Move js *RangeWidget code into *Widget
r14672
// WORKAROUND FOR JQUERY SLIDER BUG.
// The horizontal position of the slider handle
// depends on the value of the slider at the time
// of orientation change. Before applying the new
// workaround, we set the value to the minimum to
// make sure that the horizontal placement of the
// handle in the vertical slider is always
// consistent.
var orientation = this.model.get('orientation');
Tarun Gaba
Validate slider value, when limits change
r17274 var min = this.model.get('min');
var max = this.model.get('max');
Gordon Ball
Change `range` trait to `_range`
r17703 if (this.model.get('_range')) {
Gordon Ball
Merge master
r17684 this.$slider.slider('option', 'values', [min, min]);
Gordon Ball
Add initial implementation of 2-handle range sliders for integers.
r17059 } else {
Gordon Ball
Merge master
r17684 this.$slider.slider('option', 'value', min);
Gordon Ball
Add initial implementation of 2-handle range sliders for integers.
r17059 }
Jonathan Frederic
Move js *RangeWidget code into *Widget
r14672 this.$slider.slider('option', 'orientation', orientation);
Tarun Gaba
added 'var'
r17657 var value = this.model.get('value');
Gordon Ball
Change `range` trait to `_range`
r17703 if (this.model.get('_range')) {
Gordon Ball
Remove errant tabs from js
r17702 // values for the range case are validated python-side in
// _Bounded{Int,Float}RangeWidget._validate
Gordon Ball
Add initial implementation of 2-handle range sliders for integers.
r17059 this.$slider.slider('option', 'values', value);
this.$readout.text(value.join("-"));
} else {
Gordon Ball
Remove errant tabs from js
r17702 if(value > max) {
value = max;
}
else if(value < min){
value = min;
}
Gordon Ball
Add initial implementation of 2-handle range sliders for integers.
r17059 this.$slider.slider('option', 'value', value);
this.$readout.text(value);
}
Tarun Gaba
adressed @jdfrederer's concern!
r17654 if(this.model.get('value')!=value) {
this.model.set('value', value, {updated_view: this});
this.touch();
}
Jonathan Frederic
Move js *RangeWidget code into *Widget
r14672
// Use the right CSS classes for vertical & horizontal sliders
if (orientation=='vertical') {
this.$slider_container
.removeClass('widget-hslider')
.addClass('widget-vslider');
this.$el
Jonathan Frederic
Cleaned up hbox and vbox widget div styles,...
r17929 .removeClass('widget-hbox')
.addClass('widget-vbox');
Jonathan Frederic
Move js *RangeWidget code into *Widget
r14672
} else {
this.$slider_container
.removeClass('widget-vslider')
.addClass('widget-hslider');
this.$el
Jonathan Frederic
Cleaned up hbox and vbox widget div styles,...
r17929 .removeClass('widget-vbox')
.addClass('widget-hbox');
Jonathan Frederic
Move js *RangeWidget code into *Widget
r14672 }
var description = this.model.get('description');
if (description.length === 0) {
this.$label.hide();
} else {
this.$label.text(description);
Jonathan Frederic
Add latex support in widget labels,...
r16817 MathJax.Hub.Queue(["Typeset",MathJax.Hub,this.$label.get(0)]);
Jonathan Frederic
Move js *RangeWidget code into *Widget
r14672 this.$label.show();
}
Brian E. Granger
Adding initial version of readout to sliders.
r14982
var readout = this.model.get('readout');
if (readout) {
this.$readout.show();
} else {
this.$readout.hide();
}
Jonathan Frederic
Move js *RangeWidget code into *Widget
r14672 }
return IntSliderView.__super__.update.apply(this);
},
events: {
// Dictionary of events and their handlers.
Gordon Ball
Use contentEditable to allow modification via the the slider readout
r17952 "slide" : "handleSliderChange",
Gordon Ball
Add keydown listener to commit changes on <enter>
r17954 "blur [contentEditable=true]": "handleTextChange",
"keydown [contentEditable=true]": "handleKeyDown"
Jonathan Frederic
Move js *RangeWidget code into *Widget
r14672 },
Gordon Ball
Add keydown listener to commit changes on <enter>
r17954 handleKeyDown: function(e) {
Gordon Ball
Require base/js/keyboard and use keycode.enter
r18079 if (e.keyCode == keyboard.keycodes.enter) {
Gordon Ball
Add keydown listener to commit changes on <enter>
r17954 e.preventDefault();
Gordon Ball
Ignore the event object for handleTextChange
r17955 this.handleTextChange();
Gordon Ball
Add keydown listener to commit changes on <enter>
r17954 }
},
Gordon Ball
Ignore the event object for handleTextChange
r17955 handleTextChange: function() {
Gordon Ball
Add support for parsing pairs of numbers for range sliders
r17956 // this handles the entry of text into the contentEditable label
// first, the value is checked if it contains a parseable number
// (or pair of numbers, for the _range case)
// then it is clamped within the min-max range of the slider
// finally, the model is updated if the value is to be changed
//
// if any of these conditions are not met, the text is reset
//
// the step size is not enforced
Gordon Ball
Ignore the event object for handleTextChange
r17955 var text = this.$readout.text();
Gordon Ball
Add support for parsing pairs of numbers for range sliders
r17956 var vmin = this.model.get('min');
var vmax = this.model.get('max');
if (this.model.get("_range")) {
// range case
// ranges can be expressed either "val-val" or "val:val" (+spaces)
var match = this._range_regex.exec(text);
if (match) {
Gordon Ball
Change _parse_text_input to _parse_value and update float range regex
r17957 var values = [this._parse_value(match[1]),
this._parse_value(match[2])];
Gordon Ball
Add support for parsing pairs of numbers for range sliders
r17956 // reject input where NaN or lower > upper
if (isNaN(values[0]) ||
isNaN(values[1]) ||
(values[0] > values[1])) {
this.$readout.text(this.model.get('value').join('-'));
} else {
// clamp to range
values = [Math.max(Math.min(values[0], vmax), vmin),
Math.max(Math.min(values[1], vmax), vmin)];
if ((values[0] != this.model.get('value')[0]) ||
(values[1] != this.model.get('value')[1])) {
this.$readout.text(values.join('-'));
this.model.set('value', values, {updated_view: this});
this.touch();
} else {
this.$readout.text(this.model.get('value').join('-'));
}
}
} else {
this.$readout.text(this.model.get('value').join('-'));
}
Gordon Ball
Use contentEditable to allow modification via the the slider readout
r17952 } else {
Gordon Ball
Add support for parsing pairs of numbers for range sliders
r17956 // single value case
Gordon Ball
Change _parse_text_input to _parse_value and update float range regex
r17957 var value = this._parse_value(text);
Gordon Ball
Add support for parsing pairs of numbers for range sliders
r17956 if (isNaN(value)) {
this.$readout.text(this.model.get('value'));
} else {
value = Math.max(Math.min(value, vmax), vmin);
if (value != this.model.get('value')) {
this.$readout.text(value);
this.model.set('value', value, {updated_view: this});
this.touch();
} else {
this.$readout.text(this.model.get('value'));
}
}
Gordon Ball
Use contentEditable to allow modification via the the slider readout
r17952 }
},
Gordon Ball
Change _parse_text_input to _parse_value and update float range regex
r17957 _parse_value: parseInt,
Gordon Ball
Add support for parsing pairs of numbers for range sliders
r17956
_range_regex: /^\s*([+-]?\d+)\s*[-:]\s*([+-]?\d+)/,
Gordon Ball
Use contentEditable to allow modification via the the slider readout
r17952
Jonathan Frederic
Move js *RangeWidget code into *Widget
r14672 handleSliderChange: function(e, ui) {
// Called when the slider value is changed.
// Calling model.set will trigger all of the other views of the
// model to update.
Gordon Ball
Change `range` trait to `_range`
r17703 if (this.model.get("_range")) {
Gordon Ball
Add initial implementation of 2-handle range sliders for integers.
r17059 var actual_value = ui.values.map(this._validate_slide_value);
this.$readout.text(actual_value.join("-"));
} else {
var actual_value = this._validate_slide_value(ui.value);
this.$readout.text(actual_value);
}
Brian E. Granger
Adding initial version of readout to sliders.
r14982 this.model.set('value', actual_value, {updated_view: this});
Jonathan Frederic
Move js *RangeWidget code into *Widget
r14672 this.touch();
},
Jonathan Frederic
Float widget views now inherit from int counterparts
r14694
_validate_slide_value: function(x) {
// Validate the value of the slider before sending it to the back-end
// and applying it to the other views on the page.
// Double bit-wise not truncates the decimel (int cast).
return ~~x;
},
Jonathan Frederic
Move js *RangeWidget code into *Widget
r14672 });
Jonathan Frederic
Almost done!...
r17198 var IntTextView = widget.DOMWidgetView.extend({
Jonathan Frederic
Move js *RangeWidget code into *Widget
r14672 render : function(){
// Called when view is rendered.
this.$el
Jason Grout
Add semantic classes to top-level containers for single widgets...
r18120 .addClass('widget-hbox widget-text');
Jonathan Frederic
Move js *RangeWidget code into *Widget
r14672 this.$label = $('<div />')
.appendTo(this.$el)
Jonathan Frederic
Cleaned up hbox and vbox widget div styles,...
r17929 .addClass('widget-label')
Jonathan Frederic
Move js *RangeWidget code into *Widget
r14672 .hide();
this.$textbox = $('<input type="text" />')
Jonathan Frederic
Widget bootstrap3 fixes
r16952 .addClass('form-control')
Jonathan Frederic
Move js *RangeWidget code into *Widget
r14672 .addClass('widget-numeric-text')
.appendTo(this.$el);
this.update(); // Set defaults.
},
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) {
var value = this.model.get('value');
Jonathan Frederic
Float widget views now inherit from int counterparts
r14694 if (this._parse_value(this.$textbox.val()) != value) {
Jonathan Frederic
Move js *RangeWidget code into *Widget
r14672 this.$textbox.val(value);
}
if (this.model.get('disabled')) {
this.$textbox.attr('disabled','disabled');
} else {
this.$textbox.removeAttr('disabled');
}
var description = this.model.get('description');
if (description.length === 0) {
this.$label.hide();
} else {
this.$label.text(description);
Jonathan Frederic
Add latex support in widget labels,...
r16817 MathJax.Hub.Queue(["Typeset",MathJax.Hub,this.$label.get(0)]);
Jonathan Frederic
Move js *RangeWidget code into *Widget
r14672 this.$label.show();
}
}
return IntTextView.__super__.update.apply(this);
},
Jonathan Frederic
Partial implementation of styles
r17723 update_attr: function(name, value) {
// Set a css attr of the widget view.
this.$textbox.css(name, value);
},
Jonathan Frederic
Move js *RangeWidget code into *Widget
r14672 events: {
// Dictionary of events and their handlers.
"keyup input" : "handleChanging",
"paste input" : "handleChanging",
"cut input" : "handleChanging",
// Fires only when control is validated or looses focus.
"change input" : "handleChanged"
},
handleChanging: function(e) {
// Handles and validates user input.
Jonathan Frederic
Float widget views now inherit from int counterparts
r14694 // Try to parse value as a int.
Jonathan Frederic
Move js *RangeWidget code into *Widget
r14672 var numericalValue = 0;
if (e.target.value !== '') {
jon
Allow '.', '+.', '+', '-.', and '-' even though without numbers, they cannot be parsed.
r16019 var trimmed = e.target.value.trim();
if (!(['-', '-.', '.', '+.', '+'].indexOf(trimmed) >= 0)) {
numericalValue = this._parse_value(e.target.value);
}
Jonathan Frederic
Move js *RangeWidget code into *Widget
r14672 }
// If parse failed, reset value to value stored in model.
if (isNaN(numericalValue)) {
e.target.value = this.model.get('value');
} else if (!isNaN(numericalValue)) {
if (this.model.get('max') !== undefined) {
numericalValue = Math.min(this.model.get('max'), numericalValue);
}
if (this.model.get('min') !== undefined) {
numericalValue = Math.max(this.model.get('min'), numericalValue);
}
// Apply the value if it has changed.
if (numericalValue != this.model.get('value')) {
// Calling model.set will trigger all of the other views of the
// model to update.
this.model.set('value', numericalValue, {updated_view: this});
this.touch();
}
}
},
MinRK
quick review pass on javascript
r14792 handleChanged: function(e) {
Jonathan Frederic
Move js *RangeWidget code into *Widget
r14672 // Applies validated input.
if (this.model.get('value') != e.target.value) {
e.target.value = this.model.get('value');
}
Jonathan Frederic
Float widget views now inherit from int counterparts
r14694 },
Gordon Ball
Change _parse_text_input to _parse_value and update float range regex
r17957 _parse_value: parseInt
Jonathan Frederic
Move js *RangeWidget code into *Widget
r14672 });
Jonathan Frederic
Float widget views now inherit from int counterparts
r14694
Jonathan Frederic
Almost done!...
r17198 var ProgressView = widget.DOMWidgetView.extend({
Jonathan Frederic
Float widget views now inherit from int counterparts
r14694 render : function(){
// Called when view is rendered.
this.$el
Jason Grout
Add semantic classes to top-level containers for single widgets...
r18120 .addClass('widget-hbox widget-progress');
Jonathan Frederic
Float widget views now inherit from int counterparts
r14694 this.$label = $('<div />')
.appendTo(this.$el)
Jonathan Frederic
Cleaned up hbox and vbox widget div styles,...
r17929 .addClass('widget-label')
Jonathan Frederic
Float widget views now inherit from int counterparts
r14694 .hide();
this.$progress = $('<div />')
.addClass('progress')
.addClass('widget-progress')
.appendTo(this.$el);
this.$bar = $('<div />')
Jonathan Frederic
Ran jdfreder/bootstrap2to3
r16913 .addClass('progress-bar')
Jonathan Frederic
Float widget views now inherit from int counterparts
r14694 .css('width', '50%')
.appendTo(this.$progress);
this.update(); // Set defaults.
Jonathan Frederic
Added bootstrap3 progress bar classes
r17729
this.model.on('change:bar_style', function(model, value) {
this.update_bar_style();
}, this);
this.update_bar_style('');
Jonathan Frederic
Float widget views now inherit from int counterparts
r14694 },
update : function(){
// 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.
var value = this.model.get('value');
var max = this.model.get('max');
var min = this.model.get('min');
var percent = 100.0 * (value - min) / (max - min);
this.$bar.css('width', percent + '%');
var description = this.model.get('description');
if (description.length === 0) {
this.$label.hide();
} else {
this.$label.text(description);
Jonathan Frederic
Add latex support in widget labels,...
r16817 MathJax.Hub.Queue(["Typeset",MathJax.Hub,this.$label.get(0)]);
Jonathan Frederic
Float widget views now inherit from int counterparts
r14694 this.$label.show();
}
return ProgressView.__super__.update.apply(this);
},
Jonathan Frederic
Partial implementation of styles
r17723
Jonathan Frederic
Added bootstrap3 progress bar classes
r17729 update_bar_style: function(previous_trait_value) {
var class_map = {
success: ['progress-bar-success'],
info: ['progress-bar-info'],
warning: ['progress-bar-warning'],
danger: ['progress-bar-danger']
};
this.update_mapped_classes(class_map, 'bar_style', previous_trait_value, this.$bar);
},
Jonathan Frederic
Partial implementation of styles
r17723 update_attr: function(name, value) {
// Set a css attr of the widget view.
Jonathan Frederic
Added Bootstrap specific classes,...
r17728 if (name.substring(0, 6) == 'border' || name == 'width' ||
name == 'height' || name == 'background' || name == 'margin' ||
name == 'padding') {
Jonathan Frederic
Partial implementation of styles
r17723 this.$progress.css(name, value);
} else if (name == 'color') {
this.$bar.css('background', value);
} else {
this.$bar.css(name, value);
}
},
Jonathan Frederic
Float widget views now inherit from int counterparts
r14694 });
Jonathan Frederic
Almost done!...
r17198 return {
'IntSliderView': IntSliderView,
'IntTextView': IntTextView,
'ProgressView': ProgressView,
};
Jonathan Frederic
Move js *RangeWidget code into *Widget
r14672 });