##// END OF EJS Templates
Use es6-promise polyfill
Use es6-promise polyfill

File last commit:

r18906:d566532c
r18908:e336cf4a
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
Current state with lots and lots of debugging junk
r18906 // 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
Current state with lots and lots of debugging junk
r18906 // 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
Current state with lots and lots of debugging junk
r18906 // 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 });