diff --git a/src/components/orderlist/OrderList.js b/src/components/orderlist/OrderList.js index bfa828a019..eff6502d34 100644 --- a/src/components/orderlist/OrderList.js +++ b/src/components/orderlist/OrderList.js @@ -1,6 +1,7 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; -import { Button } from '../button/Button'; +import { OrderListControls } from './OrderListControls'; +import { OrderListSubList } from './OrderListSubList'; import DomHandler from '../utils/DomHandler'; import ObjectUtils from '../utils/ObjectUtils'; import classNames from 'classnames' @@ -27,7 +28,7 @@ export class OrderList extends Component { header: PropTypes.string, style: PropTypes.object, className: PropTypes.string, - liststyle: PropTypes.object, + listStyle: PropTypes.object, responsive: PropTypes.bool, dragdrop: PropTypes.func, dragdropScope: PropTypes.string, @@ -38,44 +39,42 @@ export class OrderList extends Component { constructor(props) { super(props); this.state = { - selectedItems: [] + selection: [] }; + + this.onItemClick = this.onItemClick.bind(this); + this.onReorder = this.onReorder.bind(this); this.onDragOver = this.onDragOver.bind(this); this.onDrop = this.onDrop.bind(this); this.onDragLeave = this.onDragLeave.bind(this); this.onDragStart = this.onDragStart.bind(this); this.onDragEnd = this.onDragEnd.bind(this); - this.onItemTouchEnd = this.onItemTouchEnd.bind(this); - this.onListMouseMove = this.onListMouseMove.bind(this); - this.moveUp = this.moveUp.bind(this); - this.moveTop = this.moveTop.bind(this); - this.moveDown = this.moveDown.bind(this); - this.moveBottom = this.moveBottom.bind(this); } - onItemClick(event, item) { - let metaKey = (event.metaKey || event.ctrlKey); - let selection = this.state.selectedItems; - let index = this.findIndexInList(item, selection); + onItemClick(event) { + let metaKey = (event.originalEvent.metaKey || event.originalEvent.ctrlKey); + let index = ObjectUtils.findIndexInList(event.value, this.state.selection); let selected = (index !== -1); + let selection; - if(selected && metaKey) { - selection = selection.filter((val, i) => i !== index); + if (selected) { + if (metaKey) + selection = this.state.selection.filter((val, i) => i !== index); + else + selection = [event.value]; } else { - selection = (metaKey) ? selection || [] : []; - selection.push(item); + if (metaKey) + selection = [...this.state.selection, event.value]; + else + selection = [event.value]; } - - this.setState({selectedItems: selection}); + + this.setState({selection: selection}); } - onItemTouchEnd(event) { - this.itemTouched = true; - } - isSelected(item) { - return this.findIndexInList(item, this.state.selectedItems) !== -1; + return this.findIndexInList(item, this.state.selection) !== -1; } findIndexInList(item, list) { @@ -93,131 +92,6 @@ export class OrderList extends Component { return index; } - moveUp(event) { - let selectedItems = this.state.selectedItems; - - if(selectedItems) { - let value = [...this.props.value]; - - for (let i = 0; i < selectedItems.length; i++) { - let selectedItem = selectedItems[i]; - let selectedItemIndex = this.findIndexInList(selectedItem, value); - - if(selectedItemIndex !== 0) { - let movedItem = value[selectedItemIndex]; - let temp = value[selectedItemIndex - 1]; - value[selectedItemIndex - 1] = movedItem; - value[selectedItemIndex] = temp; - } - else { - break; - } - } - - this.movedUp = true; - - if(this.props.onChange) { - this.props.onChange({ - originalEvent: event, - value: value - }) - } - } - } - - moveTop(event) { - let selectedItems = this.state.selectedItems; - - if(selectedItems) { - let value = [...this.props.value]; - - for (let i = 0; i < selectedItems.length; i++) { - let selectedItem = selectedItems[i]; - let selectedItemIndex = this.findIndexInList(selectedItem, value); - - if (selectedItemIndex !== 0) { - let movedItem = value.splice(selectedItemIndex, 1)[0]; - value.unshift(movedItem); - this.listContainer.scrollTop = 0; - } - else { - break; - } - } - - if(this.props.onChange) { - this.props.onChange({ - originalEvent: event, - value: value - }) - } - - this.listContainer.scrollTop = 0; - } - } - - moveDown(event) { - let selectedItems = this.state.selectedItems; - - if(selectedItems) { - let value = [...this.props.value]; - - for (let i = selectedItems.length - 1; i >= 0; i--) { - let selectedItem = selectedItems[i]; - let selectedItemIndex = this.findIndexInList(selectedItem, value); - - if (selectedItemIndex !== (value.length - 1)) { - let movedItem = value[selectedItemIndex]; - let temp = value[selectedItemIndex + 1]; - value[selectedItemIndex + 1] = movedItem; - value[selectedItemIndex] = temp; - } - else { - break; - } - } - - this.movedDown = true; - - if(this.props.onChange) { - this.props.onChange({ - originalEvent: event, - value: value - }) - } - } - } - - moveBottom(event) { - let selectedItems = this.state.selectedItems; - - if(selectedItems) { - let value = [...this.props.value]; - - for (let i = selectedItems.length - 1; i >= 0; i--) { - let selectedItem = selectedItems[i]; - let selectedItemIndex = this.findIndexInList(selectedItem, value); - - if (selectedItemIndex !== (value.length - 1)) { - let movedItem = value.splice(selectedItemIndex, 1)[0]; - value.push(movedItem); - } - else { - break; - } - } - - if(this.props.onChange) { - this.props.onChange({ - originalEvent: event, - value: value - }) - } - - this.listContainer.scrollTop = this.listContainer.scrollHeight; - } - } - onDragStart(event, index) { this.dragging = true; this.draggedItemIndex = index; @@ -264,31 +138,55 @@ export class OrderList extends Component { let bottomDiff = (offsetY + this.listContainer.clientHeight) - event.pageY; let topDiff = (event.pageY - offsetY); if(bottomDiff < 25 && bottomDiff > 0) - this.listContainer.scrollTop += 15; + + this.listContainer.scrollTop += 15; else if(topDiff < 25 && topDiff > 0) this.listContainer.scrollTop -= 15; } } - updateScrollView() { - if(this.movedUp||this.movedDown) { - let listItems = this.listContainer.getElementsByClassName('ui-state-highlight'); - let listItem; - - if(this.movedUp) - listItem = listItems[0]; - else - listItem = listItems[listItems.length - 1]; - - DomHandler.scrollInView(this.listContainer, listItem); - this.movedUp = false; - this.movedDown = false; + onReorder(event) { + if (this.props.onChange) { + this.props.onChange({ + event: event.originalEvent, + value: event.value + }); } + + this.reorderDirection = event.direction; } - - componentDidUpdate(prevProps, prevState) { - if(prevProps.value !== this.props.value) { - this.updateScrollView(); + + componentDidUpdate() { + if(this.reorderDirection) { + this.updateListScroll(); + this.reorderDirection = null; + } + } + + updateListScroll() { + let listItems = DomHandler.find(this.subList.listElement, '.ui-orderlist-item.ui-state-highlight'); + + if(listItems && listItems.length) { + switch(this.reorderDirection) { + case 'up': + DomHandler.scrollInView(this.subList.listElement, listItems[0]); + break; + + case 'top': + this.subList.listElement.scrollTop = 0; + break; + + case 'down': + DomHandler.scrollInView(this.subList.listElement, listItems[listItems.length - 1]); + break; + + case 'bottom': + this.subList.listElement.scrollTop = this.subList.listElement.scrollHeight; + break; + + default: + break; + } } } @@ -297,49 +195,11 @@ export class OrderList extends Component { 'ui-orderlist-responsive': this.props.responsive }); - let upButton = ; - let topButton = ; - let downButton = ; - let bottomButton = ; - let controls = ( -
- {upButton} - {topButton} - {downButton} - {bottomButton} -
- ); - - let listLength = this.props.value ? this.props.value.length: null; - let header = this.props.header &&
{this.props.header}
; - let list = ; - - let content = ( -
- {header} - {list} -
- ); - return ( -
- {controls} - {content} +
this.element = el} id={this.props.id} className={className} style={this.props.style}> + + this.subList = el} value={this.props.value} selection={this.state.selection} onItemClick={this.onItemClick} + itemTemplate={this.props.itemTemplate} header={this.props.header} listStyle={this.props.listStyle}/>
); } diff --git a/src/components/orderlist/OrderListControls.js b/src/components/orderlist/OrderListControls.js new file mode 100644 index 0000000000..11cfb437bc --- /dev/null +++ b/src/components/orderlist/OrderListControls.js @@ -0,0 +1,150 @@ +import React, { Component } from 'react' +import PropTypes from 'prop-types'; +import { Button } from '../button/Button'; +import ObjectUtils from '../utils/ObjectUtils'; + +export class OrderListControls extends Component { + + static defaultProps = { + value: null, + selection: null, + onReorder: null + } + + static propsTypes = { + value: PropTypes.array, + selection: PropTypes.array, + onReorder: PropTypes.func + } + + constructor() { + super(); + this.moveUp = this.moveUp.bind(this); + this.moveTop = this.moveTop.bind(this); + this.moveDown = this.moveDown.bind(this); + this.moveBottom = this.moveBottom.bind(this); + } + + moveUp(event) { + if(this.props.selection) { + let value = [...this.props.value]; + + for (let i = 0; i < this.props.selection.length; i++) { + let selectedItem = this.props.selection[i]; + let selectedItemIndex = ObjectUtils.findIndexInList(selectedItem, value); + + if(selectedItemIndex !== 0) { + let movedItem = value[selectedItemIndex]; + let temp = value[selectedItemIndex - 1]; + value[selectedItemIndex - 1] = movedItem; + value[selectedItemIndex] = temp; + } + else { + break; + } + } + + if(this.props.onReorder) { + this.props.onReorder({ + originalEvent: event, + value: value, + direction: 'up' + }) + } + } + } + + moveTop(event) { + if(this.props.selection) { + let value = [...this.props.value]; + + for (let i = 0; i < this.props.selection.length; i++) { + let selectedItem = this.props.selection[i]; + let selectedItemIndex = ObjectUtils.findIndexInList(selectedItem, value); + + if (selectedItemIndex !== 0) { + let movedItem = value.splice(selectedItemIndex, 1)[0]; + value.unshift(movedItem); + } + else { + break; + } + } + + if(this.props.onReorder) { + this.props.onReorder({ + originalEvent: event, + value: value, + direction: 'top' + }) + } + } + } + + moveDown(event) { + if(this.props.selection) { + let value = [...this.props.value]; + + for (let i = this.props.selection.length - 1; i >= 0; i--) { + let selectedItem = this.props.selection[i]; + let selectedItemIndex = ObjectUtils.findIndexInList(selectedItem, value); + + if (selectedItemIndex !== (value.length - 1)) { + let movedItem = value[selectedItemIndex]; + let temp = value[selectedItemIndex + 1]; + value[selectedItemIndex + 1] = movedItem; + value[selectedItemIndex] = temp; + } + else { + break; + } + } + + if(this.props.onReorder) { + this.props.onReorder({ + originalEvent: event, + value: value, + direction: 'down' + }) + } + } + } + + moveBottom(event) { + if(this.props.selection) { + let value = [...this.props.value]; + + for (let i = this.props.selection.length - 1; i >= 0; i--) { + let selectedItem = this.props.selection[i]; + let selectedItemIndex = ObjectUtils.findIndexInList(selectedItem, value); + + if (selectedItemIndex !== (value.length - 1)) { + let movedItem = value.splice(selectedItemIndex, 1)[0]; + value.push(movedItem); + } + else { + break; + } + } + + if(this.props.onReorder) { + this.props.onReorder({ + originalEvent: event, + value: value, + direction: 'bottom' + }) + } + } + } + + render() { + return ( +
+ + + + +
+ ); + } +} \ No newline at end of file diff --git a/src/components/orderlist/OrderListItem.js b/src/components/orderlist/OrderListItem.js new file mode 100644 index 0000000000..174f9bef1b --- /dev/null +++ b/src/components/orderlist/OrderListItem.js @@ -0,0 +1,48 @@ +import React, {Component} from 'react' +import PropTypes from 'prop-types'; +import classNames from 'classnames'; + +export class OrderListItem extends Component { + + static defaultProps = { + value: null, + className: null, + template: null, + selected: false, + index: null, + onClick: null + } + + static propsTypes = { + value: PropTypes.any, + className: PropTypes.string, + template: PropTypes.func, + selected: PropTypes.bool, + index: PropTypes.number, + onClick: PropTypes.func + } + + constructor() { + super(); + this.onClick = this.onClick.bind(this); + } + + onClick(event) { + if(this.props.onClick) { + this.props.onClick({ + originalEvent: event, + value: this.props.value, + index: this.props.index + }) + } + } + + render() { + let content = this.props.template ? this.props.template(this.props.value) : this.props.value; + let className = classNames('ui-orderlist-item', this.props.className, {'ui-state-highlight': this.props.selected}); + + return
  • + {content} +
  • ; + } +} \ No newline at end of file diff --git a/src/components/orderlist/OrderListSubList.js b/src/components/orderlist/OrderListSubList.js new file mode 100644 index 0000000000..854f2c8837 --- /dev/null +++ b/src/components/orderlist/OrderListSubList.js @@ -0,0 +1,55 @@ +import React, { Component } from 'react' +import PropTypes from 'prop-types'; +import classNames from 'classnames'; +import { OrderListItem } from './OrderListItem'; +import ObjectUtils from '../utils/ObjectUtils'; + +export class OrderListSubList extends Component { + + static defaultProps = { + value: null, + selection: null, + header: null, + listStyle: null, + itemTemplate: null, + onItemClick: null + } + + static propsTypes = { + value: PropTypes.array, + selection: PropTypes.array, + header: PropTypes.string, + listStyle: PropTypes.object, + itemTemplate: PropTypes.func, + onItemClick: PropTypes.func + } + + isSelected(item) { + return ObjectUtils.findIndexInList(item, this.props.selection) !== -1; + } + + render() { + let header = null; + let items = null; + let listClassName = classNames('ui-widget-content ui-orderlist-list', {'ui-corner-bottom': this.props.header, 'ui-corner-all': !this.props.header}); + + if (this.props.header) { + header =
    {this.props.header}
    + } + + if (this.props.value) { + items = this.props.value.map((item, i) => { + return + }); + } + + return ( +
    + {header} +
      this.listElement = el} className={listClassName} style={this.props.listStyle}> + {items} +
    +
    + ); + } +} \ No newline at end of file diff --git a/src/showcase/orderlist/OrderListDemo.js b/src/showcase/orderlist/OrderListDemo.js index c8be562cd7..91de5bdc17 100644 --- a/src/showcase/orderlist/OrderListDemo.js +++ b/src/showcase/orderlist/OrderListDemo.js @@ -12,12 +12,9 @@ export class OrderListDemo extends Component { this.state = { cars: null }; - this.carservice = new CarService(); - this.onCarsChange = this.onCarsChange.bind(this); - } - onCarsChange(e) { - this.setState({cars: e.value}); + this.carservice = new CarService(); + this.carTemplate = this.carTemplate.bind(this); } componentDidMount() { @@ -46,8 +43,9 @@ export class OrderListDemo extends Component {
    - + this.setState({cars: e.value})}>
    @@ -255,12 +253,9 @@ export class OrderListDemo extends Component { this.state = { cars: null }; - this.carservice = new CarService(); - this.onCarsChange = this.onCarsChange.bind(this); - } - onCarsChange(e) { - this.setState({cars: e.value}); + this.carservice = new CarService(); + this.carTemplate = this.carTemplate.bind(this); } componentDidMount() { @@ -280,20 +275,9 @@ export class OrderListDemo extends Component { render() { return ( -
    -
    -
    -

    OrderList

    -

    OrderList is used to sort a collection.

    -
    -
    - -
    - -
    - -
    + this.setState({cars: e.value})}> ); } }