UNPKG

devextreme

Version:

HTML5 JavaScript Component Suite for Responsive Web Development

276 lines (218 loc) • 10.5 kB
"use strict"; var $ = require("../../core/renderer"), eventsEngine = require("../../events/core/events_engine"), noop = require("../../core/utils/common").noop, clickEvent = require("../../events/click"), messageLocalization = require("../../localization/message"), translator = require("../../animation/translator"), eventUtils = require("../../events/utils"), feedbackEvents = require("../../events/core/emitter.feedback"), EditDecoratorMenuHelperMixin = require("./ui.list.edit.decorator_menu_helper"), registerDecorator = require("./ui.list.edit.decorator_registry").register, SwitchableEditDecorator = require("./ui.list.edit.decorator.switchable"), fx = require("../../animation/fx"), themes = require("../themes"), ActionSheet = require("../action_sheet"); var LIST_EDIT_DECORATOR = "dxListEditDecorator", CLICK_EVENT_NAME = eventUtils.addNamespace(clickEvent.name, LIST_EDIT_DECORATOR), ACTIVE_EVENT_NAME = eventUtils.addNamespace(feedbackEvents.active, LIST_EDIT_DECORATOR), SLIDE_MENU_CLASS = "dx-list-slide-menu", SLIDE_MENU_WRAPPER_CLASS = "dx-list-slide-menu-wrapper", SLIDE_MENU_CONTENT_CLASS = "dx-list-slide-menu-content", SLIDE_MENU_BUTTONS_CONTAINER_CLASS = "dx-list-slide-menu-buttons-container", SLIDE_MENU_BUTTONS_CLASS = "dx-list-slide-menu-buttons", SLIDE_MENU_BUTTON_CLASS = "dx-list-slide-menu-button", SLIDE_MENU_BUTTON_MENU_CLASS = "dx-list-slide-menu-button-menu", SLIDE_MENU_BUTTON_DELETE_CLASS = "dx-list-slide-menu-button-delete", SLIDE_MENU_ANIMATION_DURATION = 400, SLIDE_MENU_ANIMATION_EASING = "cubic-bezier(0.075, 0.82, 0.165, 1)"; registerDecorator("menu", "slide", SwitchableEditDecorator.inherit({ _shouldHandleSwipe: true, _init: function _init() { this.callBase.apply(this, arguments); this._$buttonsContainer = $("<div>").addClass(SLIDE_MENU_BUTTONS_CONTAINER_CLASS); eventsEngine.on(this._$buttonsContainer, ACTIVE_EVENT_NAME, noop); this._$buttons = $("<div>").addClass(SLIDE_MENU_BUTTONS_CLASS).appendTo(this._$buttonsContainer); this._renderMenu(); this._renderDeleteButton(); }, _renderMenu: function _renderMenu() { if (!this._menuEnabled()) { return; } var menuItems = this._menuItems(); if (menuItems.length === 1) { var menuItem = menuItems[0]; this._renderMenuButton(menuItem.text, function (e) { e.stopPropagation(); this._fireAction(menuItem); }.bind(this)); } else { var $menu = $("<div>").addClass(SLIDE_MENU_CLASS); this._menu = this._list._createComponent($menu, ActionSheet, { showTitle: false, items: menuItems, onItemClick: function (args) { this._fireAction(args.itemData); }.bind(this), integrationOptions: {} }); $menu.appendTo(this._list.$element()); var $menuButton = this._renderMenuButton(messageLocalization.format("dxListEditDecorator-more"), function (e) { e.stopPropagation(); this._menu.show(); }.bind(this)); this._menu.option("target", $menuButton); } }, _renderMenuButton: function _renderMenuButton(text, action) { var $menuButton = $("<div>").addClass(SLIDE_MENU_BUTTON_CLASS).addClass(SLIDE_MENU_BUTTON_MENU_CLASS).text(text); this._$buttons.append($menuButton); eventsEngine.on($menuButton, CLICK_EVENT_NAME, action); return $menuButton; }, _renderDeleteButton: function _renderDeleteButton() { if (!this._deleteEnabled()) { return; } var $deleteButton = $("<div>").addClass(SLIDE_MENU_BUTTON_CLASS).addClass(SLIDE_MENU_BUTTON_DELETE_CLASS).text(themes.isMaterial() ? "" : messageLocalization.format("dxListEditDecorator-delete")); eventsEngine.on($deleteButton, CLICK_EVENT_NAME, function (e) { e.stopPropagation(); this._deleteItem(); }.bind(this)); this._$buttons.append($deleteButton); }, _fireAction: function _fireAction(menuItem) { this._fireMenuAction($(this._cachedNode), menuItem.action); this._cancelDeleteReadyItem(); }, modifyElement: function modifyElement(config) { this.callBase.apply(this, arguments); var $itemElement = config.$itemElement; $itemElement.addClass(SLIDE_MENU_WRAPPER_CLASS); var $slideMenuContent = $("<div>").addClass(SLIDE_MENU_CONTENT_CLASS); $itemElement.wrapInner($slideMenuContent); }, handleClick: function handleClick(_, e) { if ($(e.target).closest("." + SLIDE_MENU_CONTENT_CLASS).length) { return this.callBase.apply(this, arguments); } return false; }, _swipeStartHandler: function _swipeStartHandler($itemElement) { this._enablePositioning($itemElement); this._cacheItemData($itemElement); this._setPositions(this._getPositions(0)); }, _swipeUpdateHandler: function _swipeUpdateHandler($itemElement, args) { var rtl = this._isRtlEnabled(), signCorrection = rtl ? -1 : 1, isItemReadyToDelete = this._isReadyToDelete($itemElement), moveJustStarted = this._getCurrentPositions().content === this._getStartPositions().content; if (moveJustStarted && !isItemReadyToDelete && args.offset * signCorrection > 0) { args.cancel = true; return; } var offset = this._cachedItemWidth * args.offset, startOffset = isItemReadyToDelete ? -this._cachedButtonWidth * signCorrection : 0, correctedOffset = (offset + startOffset) * signCorrection, percent = correctedOffset < 0 ? Math.abs((offset + startOffset) / this._cachedButtonWidth) : 0; this._setPositions(this._getPositions(percent)); return true; }, _getStartPositions: function _getStartPositions() { var rtl = this._isRtlEnabled(), signCorrection = rtl ? -1 : 1; return { content: 0, buttonsContainer: rtl ? -this._cachedButtonWidth : this._cachedItemWidth, buttons: -this._cachedButtonWidth * signCorrection }; }, _getPositions: function _getPositions(percent) { var rtl = this._isRtlEnabled(), signCorrection = rtl ? -1 : 1, startPositions = this._getStartPositions(); return { content: startPositions.content - percent * this._cachedButtonWidth * signCorrection, buttonsContainer: startPositions.buttonsContainer - Math.min(percent, 1) * this._cachedButtonWidth * signCorrection, buttons: startPositions.buttons + Math.min(percent, 1) * this._cachedButtonWidth * signCorrection }; }, _getCurrentPositions: function _getCurrentPositions() { return { content: translator.locate(this._$cachedContent).left, buttonsContainer: translator.locate(this._$buttonsContainer).left, buttons: translator.locate(this._$buttons).left }; }, _setPositions: function _setPositions(positions) { translator.move(this._$cachedContent, { left: positions.content }); translator.move(this._$buttonsContainer, { left: positions.buttonsContainer }); translator.move(this._$buttons, { left: positions.buttons }); }, _cacheItemData: function _cacheItemData($itemElement) { if ($itemElement[0] === this._cachedNode) { return; } this._$cachedContent = $itemElement.find("." + SLIDE_MENU_CONTENT_CLASS); this._cachedItemWidth = $itemElement.outerWidth(); this._cachedButtonWidth = this._cachedButtonWidth || this._$buttons.outerWidth(); this._$buttonsContainer.width(this._cachedButtonWidth); if (this._$cachedContent.length) { this._cachedNode = $itemElement[0]; } }, _minButtonContainerLeftOffset: function _minButtonContainerLeftOffset() { return this._cachedItemWidth - this._cachedButtonWidth; }, _swipeEndHandler: function _swipeEndHandler($itemElement, args) { this._cacheItemData($itemElement); var signCorrection = this._isRtlEnabled() ? 1 : -1, offset = this._cachedItemWidth * args.offset, endedAtReadyToDelete = !this._isReadyToDelete($itemElement) && offset * signCorrection > this._cachedButtonWidth * 0.2, readyToDelete = args.targetOffset === signCorrection && endedAtReadyToDelete; this._toggleDeleteReady($itemElement, readyToDelete); return true; }, _enablePositioning: function _enablePositioning($itemElement) { fx.stop(this._$cachedContent, true); this.callBase.apply(this, arguments); this._$buttonsContainer.appendTo($itemElement); }, _disablePositioning: function _disablePositioning() { this.callBase.apply(this, arguments); this._$buttonsContainer.detach(); }, _animatePrepareDeleteReady: function _animatePrepareDeleteReady() { return this._animateToPositions(this._getPositions(1)); }, _animateForgetDeleteReady: function _animateForgetDeleteReady($itemElement) { this._cacheItemData($itemElement); return this._animateToPositions(this._getPositions(0)); }, _animateToPositions: function _animateToPositions(positions) { var that = this, currentPosition = this._getCurrentPositions(), durationTimePart = Math.min(Math.abs(currentPosition.content - positions.content) / this._cachedButtonWidth, 1); return fx.animate(this._$cachedContent, { from: currentPosition, to: positions, easing: SLIDE_MENU_ANIMATION_EASING, duration: SLIDE_MENU_ANIMATION_DURATION * durationTimePart, strategy: "frame", draw: function draw(positions) { that._setPositions(positions); } }); }, dispose: function dispose() { if (this._menu) { this._menu.$element().remove(); } if (this._$buttonsContainer) { this._$buttonsContainer.remove(); } this.callBase.apply(this, arguments); } }).include(EditDecoratorMenuHelperMixin));