UNPKG

devextreme

Version:

HTML5 JavaScript Component Suite for Responsive Web Development

338 lines (335 loc) • 14.6 kB
/** * DevExtreme (cjs/__internal/ui/m_range_slider.js) * Version: 24.2.6 * Build date: Mon Mar 17 2025 * * Copyright (c) 2012 - 2025 Developer Express Inc. ALL RIGHTS RESERVED * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/ */ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _events_engine = _interopRequireDefault(require("../../common/core/events/core/events_engine")); var _index = require("../../common/core/events/utils/index"); var _message = _interopRequireDefault(require("../../common/core/localization/message")); var _component_registrator = _interopRequireDefault(require("../../core/component_registrator")); var _renderer = _interopRequireDefault(require("../../core/renderer")); var _common = require("../../core/utils/common"); var _size = require("../../core/utils/size"); var _m_slider = _interopRequireDefault(require("../ui/slider/m_slider")); var _m_slider_handle = _interopRequireDefault(require("./slider/m_slider_handle")); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e } } function _extends() { return _extends = Object.assign ? Object.assign.bind() : function(n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) { ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]) } } return n }, _extends.apply(null, arguments) } const RANGE_SLIDER_CLASS = "dx-rangeslider"; const RANGE_SLIDER_START_HANDLE_CLASS = "dx-rangeslider-start-handle"; const RANGE_SLIDER_END_HANDLE_CLASS = "dx-rangeslider-end-handle"; class RangeSlider extends _m_slider.default { _supportedKeys() { const { rtlEnabled: rtlEnabled } = this.option(); const that = this; const _changeHandle = function(e, capturedHandle) { if (that.option("start") === that.option("end")) { that._capturedHandle = capturedHandle; e.target = that._capturedHandle; _events_engine.default.trigger(that._capturedHandle, "focus") } }; const _setHandleValue = function(e, step, sign) { const isStart = (0, _renderer.default)(e.target).hasClass("dx-rangeslider-start-handle"); const valueOption = isStart ? "start" : "end"; let val = that.option(valueOption); step = that._valueStep(step); val += sign * (rtlEnabled ? -step : step); that.option(valueOption, val) }; const moveHandleRight = function(e, step) { _changeHandle(e, rtlEnabled ? that._$handleStart : that._$handleEnd); _setHandleValue(e, step, 1) }; const moveHandleLeft = function(e, step) { _changeHandle(e, rtlEnabled ? that._$handleEnd : that._$handleStart); _setHandleValue(e, step, -1) }; return _extends({}, super._supportedKeys(), { leftArrow(e) { this._processKeyboardEvent(e); moveHandleLeft(e, this.option("step")) }, rightArrow(e) { this._processKeyboardEvent(e); moveHandleRight(e, this.option("step")) }, pageUp(e) { this._processKeyboardEvent(e); moveHandleRight(e, this.option("step") * this.option("keyStep")) }, pageDown(e) { this._processKeyboardEvent(e); moveHandleLeft(e, this.option("step") * this.option("keyStep")) }, home(e) { this._processKeyboardEvent(e); const isStart = (0, _renderer.default)(e.target).hasClass("dx-rangeslider-start-handle"); const valueOption = isStart ? "start" : "end"; const startOption = isStart ? "min" : "start"; const val = this.option(startOption); this.option(valueOption, val) }, end(e) { this._processKeyboardEvent(e); const isStart = (0, _renderer.default)(e.target).hasClass("dx-rangeslider-start-handle"); const valueOption = isStart ? "start" : "end"; const endOption = isStart ? "end" : "max"; const val = this.option(endOption); this.option(valueOption, val) } }) } _getDefaultOptions() { return _extends({}, super._getDefaultOptions(), { start: 40, end: 60, value: [40, 60], startName: "", endName: "" }) } _renderSubmitElement() { const { startName: startName, endName: endName } = this.option(); const $element = this.$element(); this._$submitStartElement = (0, _renderer.default)("<input>").attr("type", "hidden").attr("name", startName).appendTo($element); this._$submitEndElement = (0, _renderer.default)("<input>").attr("type", "hidden").attr("name", endName).appendTo($element) } _initOptions(options) { super._initOptions(options); const initialValue = this.initialOption("value"); const { value: value = [] } = this.option(); if (value[0] === initialValue[0] && value[1] === initialValue[1]) { this.option("value", [this.option("start"), this.option("end")]) } else { this.option({ start: value[0], end: value[1] }) } } _initMarkup() { this.$element().addClass("dx-rangeslider"); super._initMarkup() } _renderContentImpl() { this._callHandlerMethod("repaint"); super._renderContentImpl() } _renderHandle() { const { start: start, end: end } = this.option(); this._$handleStart = this._renderHandleImpl(start, this._$handleStart); this._$handleStart.addClass("dx-rangeslider-start-handle"); this._$handleEnd = this._renderHandleImpl(end, this._$handleEnd); this._$handleEnd.addClass("dx-rangeslider-end-handle"); this._updateHandleAriaLabels() } _startHandler(args) { const e = args.event; const $range = this._$range; const rangeWidth = (0, _size.getWidth)($range); const eventOffsetX = (0, _index.eventData)(e).x - this._$bar.offset().left; const startHandleX = $range.position().left; const endHandleX = $range.position().left + rangeWidth; const rtlEnabled = this.option("rtlEnabled"); const startHandleIsClosest = (rtlEnabled ? -1 : 1) * ((startHandleX + endHandleX) / 2 - eventOffsetX) > 0; this._capturedHandle = startHandleIsClosest ? this._$handleStart : this._$handleEnd; super._startHandler(args) } _updateHandleAriaLabels() { this.setAria("label", _message.default.getFormatter("dxRangeSlider-ariaFrom")(this.option("dxRangeSlider-ariaFrom")), this._$handleStart); this.setAria("label", _message.default.getFormatter("dxRangeSlider-ariaTill")(this.option("dxRangeSlider-ariaTill")), this._$handleEnd) } _activeHandle() { return this._capturedHandle } _updateHandlePosition(e) { const rtlEnabled = this.option("rtlEnabled"); const offsetDirection = rtlEnabled ? -1 : 1; const max = this.option("max"); const min = this.option("min"); let newRatio = this._startOffset + offsetDirection * e.event.offset / this._swipePixelRatio(); newRatio = newRatio.toPrecision(12); const newValue = newRatio * (max - min) + min; this._updateSelectedRangePosition(newRatio, newRatio); _m_slider_handle.default.getInstance(this._activeHandle()).fitTooltipPosition; this._changeValueOnSwipe(newRatio); const [startValue, endValue] = this._getActualValue(); if (startValue === endValue) { let $nextHandle = (0, _renderer.default)(); if (newValue < startValue) { $nextHandle = this._$handleStart } else { $nextHandle = this._$handleEnd } _events_engine.default.trigger($nextHandle, "focus"); if ($nextHandle && $nextHandle !== this._capturedHandle) { const leftRatio = (startValue - min) / (max - min); const rightRatio = (endValue - min) / (max - min); this._updateSelectedRangePosition(leftRatio, rightRatio); this._toggleActiveState(this._activeHandle(), false); this._toggleActiveState($nextHandle, true); this._capturedHandle = $nextHandle } this._updateSelectedRangePosition(newRatio, newRatio); this._changeValueOnSwipe(newRatio) } } _updateSelectedRangePosition(leftRatio, rightRatio) { const { rtlEnabled: rtlEnabled } = this.option(); const moveRight = this._capturedHandle === this._$handleStart && rtlEnabled || this._capturedHandle === this._$handleEnd && !rtlEnabled; const prop = moveRight ? "right" : "left"; if (rtlEnabled ^ moveRight) { this._$range.css(prop, 100 - 100 * rightRatio + "%") } else { this._$range.css(prop, 100 * leftRatio + "%") } } _setValueOnSwipe(value) { const option = this._capturedHandle === this._$handleStart ? "start" : "end"; let [start, end] = this._getActualValue(); const { max: max, min: min } = this.option(); start = Math.min(Math.max(start, min), max); end = Math.min(Math.max(end, min), max); if ("start" === option) { start = value > end ? end : value } else { end = value < start ? start : value } const { valueChangeMode: valueChangeMode } = this.option(); if ("onHandleMove" === valueChangeMode) { this.option("value", [start, end]) } else { this._actualValue = [start, end]; this._renderValue() } } _renderValue() { let [valStart, valEnd] = this._getActualValue(); const { min: min, max: max } = this.option(); const rtlEnabled = this.option("rtlEnabled"); valStart = Math.max(min, Math.min(valStart, max)); valEnd = Math.max(valStart, Math.min(valEnd, max)); const { valueChangeMode: valueChangeMode } = this.option(); if ("onHandleMove" === valueChangeMode) { this._setOptionWithoutOptionChange("start", valStart); this._setOptionWithoutOptionChange("end", valEnd); this._setOptionWithoutOptionChange("value", [valStart, valEnd]) } this._$submitStartElement.val((0, _common.applyServerDecimalSeparator)(valStart)); this._$submitEndElement.val((0, _common.applyServerDecimalSeparator)(valEnd)); const ratio1 = max === min ? 0 : (valStart - min) / (max - min); const ratio2 = max === min ? 0 : (valEnd - min) / (max - min); const startOffset = `${parseFloat((100*ratio1).toPrecision(12))}%`; const endOffset = `${parseFloat((100*(1-ratio2)).toPrecision(12))}%`; if (!this._needPreventAnimation) { this._setRangeStyles({ right: rtlEnabled ? startOffset : endOffset, left: rtlEnabled ? endOffset : startOffset }) } _m_slider_handle.default.getInstance(this._$handleStart).option("value", valStart); _m_slider_handle.default.getInstance(this._$handleEnd).option("value", valEnd) } _callHandlerMethod(name, args) { _m_slider_handle.default.getInstance(this._$handleStart)[name](args); _m_slider_handle.default.getInstance(this._$handleEnd)[name](args) } _setValueOption() { const start = this.option("start"); const end = this.option("end"); this.option("value", [start, end]) } _rangesAreEqual(firstRange, secondRange) { return firstRange[0] === secondRange[0] && firstRange[1] === secondRange[1] } _optionChanged(args) { switch (args.name) { case "value": { if (this._rangesAreEqual(args.value, args.previousValue)) { break } this._setOptionWithoutOptionChange("start", args.value[0]); this._setOptionWithoutOptionChange("end", args.value[1]); this._renderValue(); const start = this.option("start"); const end = this.option("end"); const isDirty = !this._rangesAreEqual(this._initialValue, args.value); this.option("isDirty", isDirty); this._createActionByOption("onValueChanged", { excludeValidators: ["disabled", "readOnly"] })({ start: start, end: end, value: [start, end], event: this._valueChangeEventInstance, previousValue: args.previousValue }); this.validationRequest.fire({ value: [start, end], editor: this }); this._saveValueChangeEvent(void 0); break } case "start": case "end": this._setValueOption(); break; case "startName": this._$submitStartElement.attr("name", args.value); break; case "endName": this._$submitEndElement.attr("name", args.value); break; case "name": break; default: super._optionChanged(args) } } }(0, _component_registrator.default)("dxRangeSlider", RangeSlider); var _default = exports.default = RangeSlider;