##// END OF EJS Templates
setting an option to null sets the default in CodeMirror...
setting an option to null sets the default in CodeMirror matching the unset behavior in config

File last commit:

r19196:51b39c31
r19311:9c060bc5
Show More
widget_int.js
482 lines | 18.1 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(){
Jonathan Frederic
Ran function comment conversion tool
r19176 /**
* Called when view is rendered.
*/
Jonathan Frederic
Move js *RangeWidget code into *Widget
r14672 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) {
Jonathan Frederic
Ran function comment conversion tool
r19176 /**
* Set a css attr of the widget view.
*/
Jonathan Frederic
Partial implementation of styles
r17723 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){
Jonathan Frederic
Ran function comment conversion tool
r19176 /**
* 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.
*/
Jonathan Frederic
Move js *RangeWidget code into *Widget
r14672 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 {
Nicholas Bollweg (Nick)
reversing order of arguments, as text may already exist
r19196 this.typeset(this.$label, description);
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() {
Jonathan Frederic
Ran function comment conversion tool
r19176 /**
* 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
Add support for parsing pairs of numbers for range sliders
r17956
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) {
Jonathan Frederic
Ran function comment conversion tool
r19176 /**
* 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) {
Jonathan Frederic
Ran function comment conversion tool
r19176 /**
* 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).
*/
Jonathan Frederic
Float widget views now inherit from int counterparts
r14694 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(){
Jonathan Frederic
Ran function comment conversion tool
r19176 /**
* Called when view is rendered.
*/
Jonathan Frederic
Move js *RangeWidget code into *Widget
r14672 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){
Jonathan Frederic
Ran function comment conversion tool
r19176 /**
* 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.
*/
Jonathan Frederic
Move js *RangeWidget code into *Widget
r14672 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 {
Nicholas Bollweg (Nick)
reversing order of arguments, as text may already exist
r19196 this.typeset(this.$label, description);
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) {
Jonathan Frederic
Ran function comment conversion tool
r19176 /**
* Set a css attr of the widget view.
*/
Jonathan Frederic
Partial implementation of styles
r17723 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) {
Jonathan Frederic
Ran function comment conversion tool
r19176 /**
* Handles and validates user input.
*
* Try to parse value as a int.
*/
Jonathan Frederic
Move js *RangeWidget code into *Widget
r14672 var numericalValue = 0;
Jonathan Frederic
Fix #6385
r18877 var trimmed = e.target.value.trim();
if (trimmed === '') {
return;
} else {
jon
Allow '.', '+.', '+', '-.', and '-' even though without numbers, they cannot be parsed.
r16019 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
Ran function comment conversion tool
r19176 /**
* Applies validated input.
*/
Jonathan Frederic
Fix #6385
r18877 if (e.target.value.trim() === '' || e.target.value !== this.model.get('value')) {
Jonathan Frederic
Move js *RangeWidget code into *Widget
r14672 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(){
Jonathan Frederic
Ran function comment conversion tool
r19176 /**
* Called when view is rendered.
*/
Jonathan Frederic
Float widget views now inherit from int counterparts
r14694 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(){
Jonathan Frederic
Ran function comment conversion tool
r19176 /**
* 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.
*/
Jonathan Frederic
Float widget views now inherit from int counterparts
r14694 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 {
Nicholas Bollweg (Nick)
reversing order of arguments, as text may already exist
r19196 this.typeset(this.$label, description);
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) {
Jonathan Frederic
Ran function comment conversion tool
r19176 /**
* 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 });