123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
'use strict';
modulum('SliderWidget', ['FieldWidgetBase', 'WidgetFactory'],
function(context, cls) {
cls.SliderWidget = context.oo.Class(cls.FieldWidgetBase, function($super) {
return {
__name: 'SliderWidget',
__dataContentPlaceholderSelector: cls.WidgetBase.selfDataContent,
_orientation: null,
_afterLayoutFlag: null,
constructor: function(opts) {
$super.constructor.call(this, opts);
this.setFocusable(true);
},
_initLayout: function() {
if (!this._ignoreLayout) {
this._layoutInformation = new cls.LayoutInformation(this);
this._layoutEngine = new cls.SliderLayoutEngine(this);
this._layoutInformation.getSizePolicyConfig().initial = cls.SizePolicy.Dynamic();
this._layoutInformation.getSizePolicyConfig().fixed = cls.SizePolicy.Dynamic();
this._layoutInformation._forceFixedWidthMeasure = true;
}
},
_initElement: function() {
$super._initElement.call(this);
this._inputElement = this._element.getElementsByTagName('input')[0];
var onSlideEnd = this._onSlide.bind(this);
this._inputElement.on('touchend.SliderWidget', onSlideEnd);
this._inputElement.on('mouseup.SliderWidget', onSlideEnd);
this._inputElement.on('touchstart.SliderWidget', function() {
this._preventContainerScrolling(true);
}.bind(this));
},
destroy: function() {
this._inputElement.off('touchend.SliderWidget');
this._inputElement.off('mouseup.SliderWidget');
this._inputElement.off('touchstart.SliderWidget');
$super.destroy.call(this);
},
manageMouseClick: function(domEvent) {
this._onRequestFocus(domEvent);
return true;
},
manageKeyDown: function(keyString, domKeyEvent, repeat) {
var keyProcessed = false;
if (this.isEnabled() && !this.isReadOnly()) {
keyProcessed = true;
switch (keyString) {
case "down":
case "pagedown":
case this.getStart():
this.setEditing(true);
this._decrease();
this.emit(context.constants.widgetEvents.change, false);
break;
case "up":
case "pageup":
case this.getEnd():
this.setEditing(true);
this._increase();
this.emit(context.constants.widgetEvents.change, false);
break;
default:
keyProcessed = false;
}
}
if (keyProcessed) {
return true;
} else {
return $super.manageKeyDown.call(this, keyString, domKeyEvent, repeat);
}
},
_onSlide: function(evt) {
if (!this.hasFocus()) {
this._onRequestFocus(evt);
}
if (this.isEnabled() && !this.isReadOnly()) {
var total;
var clickPos = 0;
var inputRect = this._inputElement.getBoundingClientRect();
if (evt.offsetX) {
clickPos = evt.offsetX;
} else if (window.isTouchDevice() && evt.changedTouches[0]) {
if (this.getOrientation() === 'horizontal') {
clickPos = evt.changedTouches[0].pageX - inputRect.left;
} else {
clickPos = inputRect.bottom - evt.changedTouches[0].pageY;
}
}
if (this.getOrientation() === 'horizontal') {
total = inputRect.width;
} else {
total = inputRect.height;
}
var expectedTotal = this.getMax() - this.getMin();
var expectedVal = expectedTotal * (clickPos / total);
var step = this.getStep();
var value = this.getMin() + Math.floor(expectedVal / step) * step;
if ((expectedVal % step) > (step / 2)) {
value += step;
}
this.setEditing(true);
this._inputElement.value = value;
}
this._preventContainerScrolling(false);
this.emit(context.constants.widgetEvents.change, false);
},
_increase: function() {
this.setValue((this.getValue() || 0) + this.getStep());
},
_decrease: function() {
this.setValue((this.getValue() || 0) - this.getStep());
},
getValue: function() {
return parseInt(this._inputElement.value, 10);
},
setValue: function(value, fromVM) {
$super.setValue.call(this, value, fromVM);
value = +value;
this._inputElement.value = Object.isNumber(value) && !Number.isNaN(value) ? value : 0;
this.setAriaAttribute("valuenow", value);
},
getMin: function() {
return this._inputElement.getIntAttribute('min');
},
setMin: function(value) {
if (Object.isNumber(value)) {
this._inputElement.setAttribute('min', value);
} else {
this._inputElement.removeAttribute('min');
}
this.setAriaAttribute("valuemin", value);
},
getMax: function() {
return this._inputElement.getIntAttribute('max');
},
setMax: function(value) {
if (Object.isNumber(value)) {
this._inputElement.setAttribute('max', value);
} else {
this._inputElement.removeAttribute('max');
}
this.setAriaAttribute("valuemax", value);
},
getStep: function() {
return this._inputElement.getIntAttribute('step');
},
setStep: function(step) {
this._inputElement.setAttribute('step', Object.isNumber(step) && step > 0 ? step : 1);
},
setTitle: function(title) {
this._inputElement.setAttribute('title', title);
},
getTitle: function() {
return this._inputElement.getAttribute('title');
},
setOrientation: function(orientation, afterLayout) {
if (this._orientation !== orientation || this._afterLayoutFlag !== afterLayout) {
this._orientation = orientation;
this._afterLayoutFlag = afterLayout;
var newStyle = {};
if (orientation === 'vertical' && afterLayout) {
this.setStyle({
'transform': 'rotate(-90deg)'
});
} else {
newStyle = {
'-webkit-appearance': null,
'writing-mode': null
};
if (this._inputElement) {
this._inputElement.removeAttribute('orient');
}
}
this.setStyle('>input[type=range]', newStyle);
this.setAriaAttribute("orientation", orientation);
}
},
getOrientation: function() {
return this._orientation ? this._orientation : 'horizontal';
},
setFocus: function(fromMouse) {
this._inputElement.domFocus();
$super.setFocus.call(this, fromMouse);
},
setReadOnly: function(readonly) {
$super.setReadOnly.call(this, readonly);
this._setInputReadOnly(readonly);
},
_setInputReadOnly: function(readonly) {
if (readonly) {
this._inputElement.setAttribute('readonly', 'readonly');
} else {
this._inputElement.removeAttribute('readonly');
}
},
_preventContainerScrolling: function(prevent) {
var form = this.getFormWidget();
if (form) {
form.getContainerElement().toggleClass("prevent-touch-scroll", prevent);
}
}
};
});
cls.WidgetFactory.registerBuilder('Slider', cls.SliderWidget);
});