@shakthillc/components
Version:
React generic components for shakthi products
205 lines (191 loc) • 6.08 kB
JavaScript
import React from "react";
import PropTypes from "prop-types";
import style from "./MultiSelector.module.css";
import Badge from "./Badge";
import Popup from "../Popup/Popup";
import Avatar from "./../Avatar/Avatar";
import _ from "lodash";
class MultiSelector extends React.Component {
constructor(props) {
super(props);
this.state = {
selectedOption: this.props.selectedOption,
isOpen: false,
options: this.props.options || [],
selectedValue: this.props.selectedOption || [],
};
this.handleChange = this.handleChange.bind(this);
this.removeBadge = this.removeBadge.bind(this);
this.changePicker = this.changePicker.bind(this);
}
componentDidMount() {
const { selectedOption, options } = this.props;
if (
selectedOption &&
selectedOption.length > 0
) {
let filteredOptions = this.props.options.filter(
({ value: id1 }) =>
!this.props.selectedOption.some(({ value: id2 }) => id2 === id1)
);
this.setState({
selectedValue: selectedOption,
options: filteredOptions,
});
}
if (options && options.length > 0) {
var filteredOptions = options;
if (selectedOption && selectedOption.length > 0) {
filteredOptions = this.props.options.filter(
({ value: id1 }) =>
!this.props.selectedOption.some(({ value: id2 }) => id2 === id1)
);
}
this.setState({ options: filteredOptions });
}
}
componentDidUpdate(prevProps, prevState) {
// const { selectedValue, options, orig_options } = this.state;
const { selectedOption, options } = this.props;
if (
selectedOption &&
selectedOption.length > prevProps.selectedOption.length
) {
let filteredOptions = this.props.options.filter(
({ value: id1 }) =>
!this.props.selectedOption.some(({ value: id2 }) => id2 === id1)
);
this.setState({
selectedValue: selectedOption,
options: filteredOptions,
});
}
if (options && options.length != prevProps.options.length) {
var filteredOptions = options;
if (selectedOption && selectedOption.length > 0) {
filteredOptions = this.props.options.filter(
({ value: id1 }) =>
!this.props.selectedOption.some(({ value: id2 }) => id2 === id1)
);
}
this.setState({ options: filteredOptions,selectedValue:selectedOption || [] });
}
}
handleChange(val, mode) {
let { onChange } = this.props;
const { options } = this.state;
let modifedOptions = options.filter((data) => {
if (_.isEqual(data, val)) {
} else {
return data;
}
});
var selectedValue = this.state.selectedValue;
selectedValue.push(val);
this.setState({ selectedValue, options: modifedOptions });
onChange && onChange(selectedValue);
}
removeBadge(badgeObj) {
const { onChange } = this.props;
var selectedValue = [...this.state.selectedValue];
var options = [...this.state.options, badgeObj];
selectedValue = selectedValue.filter((obj) => obj.value !== badgeObj.value);
this.setState({ selectedValue, options });
onChange && onChange(selectedValue);
}
changePicker(val) {
let result = null;
const { selectedOption } = this.state;
let selectedValue = this.state.selectedValue;
result = selectedValue.map((obj) => {
return (
<Badge
text={obj.label}
avatar={obj.avatar}
color={obj["color"]}
onClick={(e) => this.removeBadge(obj)}
/>
);
});
return result;
}
render() {
let {
disabled = false,
mode,
isPopupOpen,
togglePopup,
removeClose,
text1 = "Choose one or more people",
text2 = "add more people",
} = this.props;
const { isOpen, selectedValue = "", options } = this.state;
let selectedLabel = this.changePicker(this.props.mode);
let inputText;
let singleStyle = mode === "S" ? "32px" : "";
if (mode !== "S") {
inputText = selectedValue.length !== 0 ? text2 : text1;
} else {
inputText = selectedValue.length !== 0 ? "" : "Enter people";
}
let html = options.map((obj, i) => {
return (
<span
key={i}
className={style.dropdownList}
onClick={this.handleChange.bind(this, obj, mode)}
>
<Avatar size="24px" text={obj["label"]} />
{obj.label}
</span>
);
});
html.push(
<span
style={{ display: options.length != 0 ? "none" : "" }}
className={style.dropdownList__noitems}
>
{" "}
No items found
</span>
);
return (
<div className={style.selectContainer}>
<div
style={{ maxHeight: singleStyle }}
className={
isPopupOpen === true ? style.selectStyle_click : style.selectStyle
}
onClick={togglePopup}
>
<div className={style.inputContainer}>
<div style={{ display: "inline" }} onClick={removeClose}>
{selectedLabel}
</div>
<p className={style.selectedTxt}>{inputText}</p>
</div>
</div>
{isPopupOpen ? (
<div onClick={removeClose} className={style.selectDropdown}>
{html}
</div>
) : null}
</div>
);
}
}
MultiSelector.defaultProps = {
options: [
{ value: "Rick", label: "Rick", color: "lightblue" },
{ value: "Morty", label: "Morty", color: "orange" },
{ value: "Perry", label: "Perry", color: "lightgreen" },
],
disabled: false,
};
MultiSelector.propTypes = {
disabled: PropTypes.bool,
onChange: PropTypes.func,
options: PropTypes.array,
selectedValue: PropTypes.string,
};
export default Popup(MultiSelector);