Skip to content

Commit

Permalink
Add dragdrop support to OrderList
Browse files Browse the repository at this point in the history
  • Loading branch information
mertsincan committed Jul 25, 2017
1 parent 6978ffa commit c194f19
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 7 deletions.
87 changes: 82 additions & 5 deletions src/components/orderlist/OrderList.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Button } from '../button/Button';
import DomHandler from '../utils/DomHandler';
import ObjectUtils from '../utils/ObjectUtils';
import classNames from 'classnames'

export class OrderList extends Component {
Expand All @@ -13,6 +14,8 @@ export class OrderList extends Component {
styleClass: null,
listStyle: null,
responsive: false,
dragdrop: false,
dragdropScope: null,
onReorder: null,
itemTemplate: null
}
Expand All @@ -24,13 +27,22 @@ export class OrderList extends Component {
styleClass: PropTypes.string,
listStyle: PropTypes.string,
responsive: PropTypes.bool,
dragdrop: PropTypes.func,
dragdropScope: PropTypes.string,
onReorder: PropTypes.func,
itemTemplate: PropTypes.func
}

constructor(props) {
super(props);
this.state = {values: this.props.value, selectedItems: []};
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);
}

onItemClick(event, item) {
Expand All @@ -49,6 +61,14 @@ export class OrderList extends Component {
this.setState({selectedItems: this.selectedItems});
}

isItemVisible(item){
return true;
}

onItemTouchEnd(event) {
this.itemTouched = true;
}

isSelected(item) {
return this.findIndexInList(item, this.state.selectedItems) !== -1;
}
Expand Down Expand Up @@ -180,6 +200,59 @@ export class OrderList extends Component {
}
}

onDragStart(event, index) {
this.dragging = true;
this.draggedItemIndex = index;
if(this.props.dragdropScope) {
event.dataTransfer.setData("text", this.props.dragdropScope);
}
}

onDragOver(event, index) {
if(this.draggedItemIndex !== index && this.draggedItemIndex + 1 !== index) {
this.dragOverItemIndex = index;
DomHandler.addClass(event.target, 'ui-state-highlight');
event.preventDefault();
}
}

onDragLeave(event, index) {
this.dragOverItemIndex = null;
DomHandler.removeClass(event.target, 'ui-state-highlight');
}

onDrop(event, index) {
let dropIndex = (this.draggedItemIndex > index) ? index : (index === 0) ? 0 : index - 1,
_value = [...this.state.values];
ObjectUtils.reorderArray(_value, this.draggedItemIndex, dropIndex);
this.setState({values: _value});
this.dragOverItemIndex = null;
DomHandler.removeClass(event.target, 'ui-state-highlight');

if(this.props.onReorder) {
this.props.onReorder({
originalEvent: event,
value: _value
})
}
}

onDragEnd(event) {
this.dragging = false;
}

onListMouseMove(event) {
if(this.dragging) {
let offsetY = this.listContainer.getBoundingClientRect().top + document.body.scrollTop;
let bottomDiff = (offsetY + this.listContainer.clientHeight) - event.pageY;
let topDiff = (event.pageY - offsetY);
if(bottomDiff < 25 && bottomDiff > 0)
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');
Expand Down Expand Up @@ -228,10 +301,11 @@ export class OrderList extends Component {
</div>
);

var content = (
var valuesLength = this.state.values && this.state.values.length,
content = (
<div className="ui-grid-col-10">
{this.props.header && <div className="ui-orderlist-caption ui-widget-header ui-corner-top">{this.props.header}</div>}
<ul ref={(el) => this.listContainer = el} className="ui-widget-content ui-orderlist-list ui-corner-bottom" style={this.props.listStyle}>
<ul ref={(el) => this.listContainer = el} className="ui-widget-content ui-orderlist-list ui-corner-bottom" style={this.props.listStyle} onDragOver={this.onListMouseMove}>
{
this.state.values && this.state.values.map((item, i) => {

Expand All @@ -240,11 +314,14 @@ export class OrderList extends Component {
'ui-state-highlight': this.isSelected(item)
});

return (
<li key={i + '_orderlistitem'} className={listStyleClass} onClick={(e) => this.onItemClick(e, item)}>
return [
this.props.dragdrop && this.isItemVisible(item) && <li 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 && valuesLength === (i + 1) && <li className="ui-orderlist-droppoint" onDragOver={(e) => this.onDragOver(e, i + 1)} onDrop={(e) => this.onDrop(e, i + 1)} onDragLeave={this.onDragLeave}></li>
]

})
}
</ul>
Expand Down
13 changes: 13 additions & 0 deletions src/components/utils/ObjectUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,17 @@ export default class ObjectUtils {
return filteredItems;
}

static reorderArray(value, from, to) {
let target;
if(value && (from !== to)) {
if(to >= value.length) {
target = to - value.length;
while((target--) + 1) {
value.push(undefined);
}
}
value.splice(to, 0, value.splice(from, 1)[0]);
}
}

}
25 changes: 23 additions & 2 deletions src/showcase/orderlist/OrderListDemo.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export class OrderListDemo extends Component {
<div className="content-section implementation">
<div className="ui-g">
<div className="ui-g-12 ui-md-6">
<OrderList value={this.state.cars} itemTemplate={this.carTemplate.bind(this)} responsive={true} header="Responsive Cars" listStyle={{ height: '250px' }} onReorder={this.onReorderCars.bind(this)}></OrderList>
<OrderList value={this.state.cars} dragdrop={true} itemTemplate={this.carTemplate.bind(this)} responsive={true} header="Responsive Cars" listStyle={{ height: '250px' }} onReorder={this.onReorderCars.bind(this)}></OrderList>
</div>
<div className="ui-g-12 ui-md-6">
<ul>
Expand Down Expand Up @@ -105,6 +105,15 @@ onReorderCars(e) {
this.setState({ cars: e.value });
}
`}
</CodeHighlight>

<h3>DragDrop</h3>
<p>Items can be reordered using drag and drop by enabling dragdrop property along with dragdropScope to avoid conflict with other drag drop events on view.</p>
<CodeHighlight className="language-markup">
{`
<OrderList value={this.state.cars} itemTemplate={this.carTemplate.bind(this)} dragdrop={true} onReorder={this.onReorderCars.bind(this)}></OrderList>
`}
</CodeHighlight>

Expand Down Expand Up @@ -171,6 +180,18 @@ onReorderCars(e) {
<td>null</td>
<td>Function that gets the option and returns the content for it.</td>
</tr>
<tr>
<td>dragdrop</td>
<td>boolean</td>
<td>false</td>
<td>Whether to enable dragdrop based reordering.</td>
</tr>
<tr>
<td>dragdropScope</td>
<td>string</td>
<td>null</td>
<td>Unique key of drag drop events to avoid conflict with other drag drop events on the page.</td>
</tr>
</tbody>
</table>
</div>
Expand Down Expand Up @@ -276,7 +297,7 @@ export class OrderListDemo extends Component {
<div className="content-section implementation">
<div className="ui-g">
<div className="ui-g-12 ui-md-6">
<OrderList value={this.state.cars} itemTemplate={this.carTemplate.bind(this)} responsive={true} header="Responsive Cars" listStyle={{ height: '250px' }} onReorder={this.onReorderCars.bind(this)}></OrderList>
<OrderList value={this.state.cars} dragdrop={true} itemTemplate={this.carTemplate.bind(this)} responsive={true} header="Responsive Cars" listStyle={{ height: '250px' }} onReorder={this.onReorderCars.bind(this)}></OrderList>
</div>
<div className="ui-g-12 ui-md-6">
<ul>
Expand Down

0 comments on commit c194f19

Please sign in to comment.