Skip to content

Commit

Permalink
Initiated #308
Browse files Browse the repository at this point in the history
  • Loading branch information
Çağatay Çivici authored and Çağatay Çivici committed Feb 12, 2018
1 parent abd3ea9 commit 17611b7
Show file tree
Hide file tree
Showing 5 changed files with 332 additions and 235 deletions.
278 changes: 69 additions & 209 deletions src/components/orderlist/OrderList.js
Original file line number Diff line number Diff line change
@@ -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'
Expand All @@ -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,
Expand All @@ -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) {
Expand All @@ -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;
Expand Down Expand Up @@ -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;
}
}
}

Expand All @@ -297,49 +195,11 @@ export class OrderList extends Component {
'ui-orderlist-responsive': this.props.responsive
});

let upButton = <Button type="button" icon="fa-angle-up" onClick={this.moveUp}></Button>;
let topButton = <Button type="button" icon="fa-angle-double-up" onClick={this.moveTop}></Button>;
let downButton = <Button type="button" icon="fa-angle-down" onClick={this.moveDown}></Button>;
let bottomButton = <Button type="button" icon="fa-angle-double-down" onClick={this.moveBottom}></Button>;
let controls = (
<div className="ui-orderlist-controls">
{upButton}
{topButton}
{downButton}
{bottomButton}
</div>
);

let listLength = this.props.value ? this.props.value.length: null;
let header = this.props.header && <div className="ui-orderlist-caption ui-widget-header ui-corner-top">{this.props.header}</div>;
let list = <ul ref={(el) => this.listContainer = el} className="ui-widget-content ui-orderlist-list ui-corner-bottom" style={this.props.listStyle} onDragOver={this.onListMouseMove}>
{
this.props.value && this.props.value.map((item, i) => {
let listItemContent = this.props.itemTemplate ? this.props.itemTemplate(item) : item;
let listStyleClass = classNames('ui-orderlist-item', {'ui-state-highlight': this.isSelected(item)});

return [
this.props.dragdrop && <li key={i + '_orderlistfirstdroppoint'} className="ui-orderlist-droppoint" onDragOver={(e) => this.onDragOver(e, i)} onDrop={(e) => this.onDrop(e, i)} onDragLeave={this.onDragLeave}></li>
,<li key={i + '_orderlistitem'} className={listStyleClass} onClick={(e) => this.onItemClick(e, item)} draggable={this.props.dragdrop} onDragStart={(e) => this.onDragStart(e, i)} onDragEnd={this.onDragEnd} onTouchEnd={this.onItemTouchEnd}>
{listItemContent}
</li>
,this.props.dragdrop && listLength === (i + 1) && <li key={i + '_orderlistdroppoint'} className="ui-orderlist-droppoint" onDragOver={(e) => this.onDragOver(e, i + 1)} onDrop={(e) => this.onDrop(e, i + 1)} onDragLeave={this.onDragLeave}></li>
];
})
}
</ul>;

let content = (
<div className="ui-orderlist-list-container">
{header}
{list}
</div>
);

return (
<div id={this.props.id} className={className} style={this.props.style}>
{controls}
{content}
<div ref={(el) => this.element = el} id={this.props.id} className={className} style={this.props.style}>
<OrderListControls value={this.props.value} selection={this.state.selection} onReorder={this.onReorder} />
<OrderListSubList ref={(el) => 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}/>
</div>
);
}
Expand Down
Loading

0 comments on commit 17611b7

Please sign in to comment.