我想通过排序实现元素的拖放操作,并且我不想使用任何外部库。
将有2个容器,我想对一个容器中的元素进行排序,然后在两个容器之间拖放。有什么建议吗?
我尝试了HTML5和其他方法,但没有成功
答案 0 :(得分:0)
答案 1 :(得分:0)
您可以将onDrop
和onDrag
事件分配给div。您可以将每个组件固定在数组中,拖动时可以将其从and数组中删除,拖放时可以将该项目添加到array中。之后,您可以按array.sort()
<div onDrag={this.handleDrag()} onDrop={thishandleDrop()}>
handleDrag = () => {
//remove your item in array here
}
handleDrag = () => {
//add your item to array here
}
答案 2 :(得分:0)
/**
* Displays Dialog for Table show/hide columns
* @default {string} submitLabel, cancelLabel
* @default {bool} open
* @default {array} suggestions
*/
import React from "react";
import PropTypes from "prop-types";
import { withStyles } from "@material-ui/core/styles";
import SettingsIcon from "@material-ui/icons/Settings";
import IconButton from "@material-ui/core/IconButton";
import { theme } from "../../../../utilities/theme-default";
import HLTooltip from "../../../atoms/ToolTip";
import HLDialog from "../../../grouped/Dialog";
import HLSaveSettings from "../SaveTableSettings";
import HLTypography from "../../../atoms/Typography";
import HLChip from "@material-ui/core/Chip";
import * as colors from "../../../../utilities/color";
import Draggable from "react-draggable";
export const styles = () => ({
tableAction: {
width: "100%",
marginTop: `${theme.spacing.unit}px`
},
container: {
display: "flex"
},
title: {
flex: "0 0 auto"
},
section: {
border: `1px solid ${colors.neutralDark["120"]}`,
marginTop: `${theme.spacing.unit * 3}px`,
padding: `${theme.spacing.unit}px 0 ${theme.spacing.unit * 3}px ${theme
.spacing.unit * 6}px`,
display: "flex"
},
chipTextStyle: {
marginTop: `${theme.spacing.unit * 4}px`
},
chipStyle: {
padding: `${theme.spacing.unit * 3}px`,
marginTop: `${theme.spacing.unit}px`
},
dialogStyle: {
width: "500px"
},
defaultSection: {
marginTop: `${theme.spacing.unit * 2}px`
}
});
/**
* state component which handles table show/hide columns
*/
export class HLShowHide extends React.Component {
state = {
open: false,
headers: this.props.headers
};
/**
* function to display dialog for show/hide opetations
*/
dialogToggle = () => {
this.setState({
open: !this.state.open
});
};
onStart() {
this.setState({ activeDrags: this.state.activeDrags + 1 });
}
onStop() {
this.setState({ activeDrags: this.state.activeDrags - 1 });
}
onDragStart = (e, sectionIndex, index) => {
e.stopPropagation();
this.draggedItem = this.state.headers.sections[sectionIndex].items[index];
this.dragItemSection = sectionIndex;
this.dragItemIndex = index;
e.dataTransfer.effectAllowed = "move";
e.dataTransfer.setData("text/html", e.target.parentNode);
e.dataTransfer.setDragImage(e.target.parentNode, 20, 20);
};
onDragOver = (sectionIndex, index) => {
const draggedOverItem = this.state.headers.sections[sectionIndex].items[
index
];
// if the item is dragged over itself, ignore
if (this.draggedItem === draggedOverItem) {
return;
}
if (this.dragItemSection !== sectionIndex) {
var otherItems = this.state.headers.sections[this.dragItemSection].items;
otherItems.splice(this.dragItemIndex, 1);
}
// filter out the currently dragged item
let items = this.state.headers.sections[sectionIndex].items.filter(
item => item !== this.draggedItem
);
// add the dragged item after the dragged over item
items.splice(index, 0, this.draggedItem);
const sections = this.state.headers.sections;
sections[sectionIndex].items = items;
sections[this.dragItemSection].items = otherItems;
this.setState({ headers: { ...this.state.headers, sections } });
};
onDragOverSection = sectionIndex => {
if (this.state.headers.sections[sectionIndex].length === 0) {
var otherItems = this.state.headers.sections[this.dragItemSection].items;
otherItems.splice(this.dragItemIndex, 1);
let items = this.state.headers.sections[sectionIndex].items;
items.push(this.draggedItem);
const sections = this.state.headers.sections;
sections[this.dragItemSection].items = otherItems;
sections[sectionIndex].items = items;
this.setState({ headers: { ...this.state.headers, sections } });
}
};
onDragEnd = () => {
this.draggedIdx = null;
};
render() {
const { classes, submitLabel, cancelLabel } = this.props;
const { open, headers } = this.state;
const dragHandlers = {
onStart: this.onStart.bind(this),
onStop: this.onStop.bind(this)
};
const dialogBody = (
<div className={classes.dialogStyle}>
{headers.sections.map((section, sectionIndex) => (
<div className={classes.section}>
<span className={classes.chipTextStyle}>
<HLTypography
variant={
theme.palette.tableConstant.showHideColumn.sections.variant
}
color={
theme.palette.tableConstant.showHideColumn.sections.color
}
>
{section.label}
</HLTypography>
</span>
<span onDragOver={() => this.onDragOverSection(sectionIndex)}>
{section.items.map((item, itemIndex) => (
<div
className={classes.chipStyle}
key={item.value}
data-id={`${itemIndex}_${sectionIndex}`}
onDragOver={() => this.onDragOver(sectionIndex, itemIndex)}
>
<Draggable
onDrag={this.handleDrag.bind(this)}
{...dragHandlers}
>
<HLChip label={item.label} />
</Draggable>
</div>
))}
</span>
</div>
))}
<div className={classes.defaultSection}>
<HLSaveSettings
defaultLabel={headers.defaultLabel}
isDefault={headers.isDefault}
/>
</div>
</div>
);
return (
<React.Fragment>
{open && (
<div className={classes.container}>
<div className={classes.tableAction}>
<HLDialog
open={open}
submitLabel={submitLabel}
cancelLabel={cancelLabel}
bodyText={dialogBody}
maxWidth="xl"
onSubmit={() => {}}
onCancel={() => {
this.dialogToggle();
}}
/>
</div>
</div>
)}
{!open && (
<React.Fragment>
<HLTooltip title="Settings" placement="top">
<IconButton aria-label="Settings">
<SettingsIcon onClick={this.dialogToggle} />
</IconButton>
</HLTooltip>
</React.Fragment>
)}
</React.Fragment>
);
}
}
HLShowHide.propTypes = {
classes: PropTypes.object,
headers: PropTypes.arrayOf().isRequired,
open: PropTypes.bool,
submitLabel: PropTypes.string,
cancelLabel: PropTypes.string
};
HLShowHide.defaultProps = {
open: false,
submitLabel: "Set",
cancelLabel: "Cancel"
};
export default withStyles(styles)(HLShowHide);
我尝试过的代码