reactjs - 我们如何在多选下拉框中传递整个选项列表
问题描述
multiselect-react-dropdown
如果loginUserEmail is not equal to data1[0].useremail
. _ 我已经通过了选项,setShowOptions(options)
但没有任何反应。
loginUserEmail = "user_2@test.com"
如果与提交匹配,系统将完美显示选择的下拉列表>>useremail
代码框链接:
https://codesandbox.io/s/clever-browser-txprq?file=/src/App.js
import "./styles.css";
import React, { useRef, useEffect, useState } from "react";
import { useParams } from "react-router-dom";
import { useForm } from "react-hook-form";
import Axios from "axios";
import { Link, useHistory } from "react-router-dom";
import Multiselect from "multiselect-react-dropdown";
import Button from "@material-ui/core/Button";
import { toast } from "react-toastify";
import { notify } from "./HelperFunctions";
import "react-toastify/dist/ReactToastify.css";
const options = [
{ id: 1, name: "Ath", email: "ath.best@test1.com", access: null },
{ id: 2, name: "Arnolds", email: "arnold@test1.com", access: null },
{ id: 3, name: "Alter", email: "alloop@test1.com", access: null },
{ id: 4, name: "Brandan", email: "brandan@test1.com", access: null },
{ id: 5, name: "Ron", email: "ron@test1.com", access: null },
{ id: 6, name: "Rads", email: "rad@test1.com", access: null },
{ id: 7, name: "Sam", email: "sam@y.com", access: null }
];
const submitted = [
{
id: 4,
useremail: "user_1@test.com",
name: "Brandan",
email: "brandan@test1.com",
access: null,
displayValue: "Brandan brandan@test1.com"
},
{
id: 5,
useremail: "user_1@test.com",
name: "Ron",
email: "ron@test1.com",
access: null,
displayValue: "Ron ron@test1.com"
}
];
export default function App() {
toast.configure();
const [option, setOption] = useState([]);
const [selectedOption, setSelectedOption] = useState([]);
const [nomRegister, setNomRegister] = useState([{}]);
const [helperText, setHelperText] = useState("");
const [userEmail, setUserEmail] = useState("");
const {
register,
handleSubmit,
watch,
formState: { errors },
reset
} = useForm();
const refSelect = useRef(null);
const [submittedNominees, setSubmittedNominees] = useState([{}]);
const [maxOptions, setMaxOptions] = useState(0); //-making maxOption dynamic because we don't the length of data from submittednominations
const [openDialog, setOpenDialog] = useState(false); // dialog confirmation
const [validationMsgs, setValidationMsgs] = useState([true, true, true]);
const [showOptions, setShowOptions] = useState(false); // toogle between show/hide option on checkbox
//A.H
useEffect(() => {
if (maxOptions === 0) setShowOptions(false);
else setShowOptions(true);
}, [selectedOption, maxOptions]);
// verify textarea & maximum limit & submit withtout selectoption before open dialog
const handleClickOpenDialog = () => {
const updateList = [...validationMsgs];
if (selectedOption.length === 0 && showOptions) {
//if we want submit without choosing a nomniation & not achieve maximum limit (we used showOptions to know if we got the limit or no)
notify("You must select a nominee before you submit !", toast, "error");
updateList[0] = false;
setValidationMsgs(updateList);
} else {
updateList[0] = true;
setValidationMsgs(updateList);
}
if (!showOptions && selectedOption.length === 0) {
//if we achieve maximum limit
notify(
"Sorry, nomination has exceeded the maximum limit!",
toast,
"error"
);
updateList[1] = false;
setValidationMsgs(updateList);
} else {
updateList[1] = true;
setValidationMsgs(updateList);
}
if (selectedOption.length !== 0) {
//text aread required and <245
let ok = true;
selectedOption.map((selectedOpt) => {
if (
!selectedOpt.reason ||
selectedOpt.reason === "" ||
selectedOpt.reason.length > 245
)
ok = ok && false;
else ok = ok && true;
});
if (!ok) {
notify(
"Reason for nomination is required or reason should be less than 245 characters..!",
toast,
"error"
);
}
updateList[2] = ok;
setValidationMsgs(updateList);
}
let textareaVerification = true;
for (let index = 0; index < updateList.length; index++) {
if (!updateList[index]) {
textareaVerification = false;
break;
}
}
if (textareaVerification) setOpenDialog(true);
};
const handleCloseDialog = () => {
setOpenDialog(false);
};
useEffect(() => {
const userEmail = localStorage.getItem("loginEmail");
setUserEmail(userEmail);
});
useEffect(() => {
const fetchData = async () => {
const loginUserEmail = "user_2@test.com";
try {
const data1 = submitted;
console.log(data1, "data1");
if (loginUserEmail == data1[0].useremail) {
setSubmittedNominees(data1);
setMaxOptions(3 - data1.length); //-making maxOption dynamic because we don't the length of data from submittednominations
console.log("Submitted nominations :" + JSON.stringify(data1));
} else {
setShowOptions(options);
}
} catch (e) {
console.log(e);
}
};
fetchData();
}, []);
useEffect(() => {
const fetchData = async () => {
try {
const res = await Axios.get(
"http://localhost:8000/service/nomineeslist"
);
console.log(res.data, "aaa");
const data1 = res.data;
setOption(data1);
console.log("Get the list of nomineeslist :" + JSON.stringify(data1));
} catch (e) {
console.log(e);
}
};
fetchData();
}, [maxOptions]);
const handleTypeSelect = (e, i) => {
const copy = [...selectedOption];
copy.push(e[3 - maxOptions]); //-fix error: select one more record it still console log the pre selected one
setSelectedOption(copy);
setMaxOptions((prevState) => prevState - 1); //-making maxOption dynamic
};
const handleTypeRemove = (e) => {
const copy = [...selectedOption];
let index = copy.indexOf(e);
copy.splice(index, 1);
setSelectedOption(copy);
setMaxOptions((prevState) => prevState + 1); //-making maxOption dynamic
// immutating state (best practice)
const updateList = nomRegister.map((item) => {
return { ...item };
});
//delete the specific array case depends on the id
updateList.splice(index, 1);
setNomRegister(updateList);
};
const sendNomination = () => {
console.log("What the Array holds: " + JSON.stringify(nomRegister));
const headers = {
"Content-Type": "application/json"
};
const fetchData = async (nomRegister) => {
try {
const res = await Axios.post(
"http://localhost:8000/service/nominateperson",
{ userEmail, nomRegister },
headers
);
if (res.data) {
console.log("Print data:" + res.data);
const successMessage = res.data.message;
setHelperText(successMessage);
notify("Nomination submitted successfully !", toast, "success");
const updateList = selectedOption.map((item) => {
return { ...item, reason: "" };
});
setSelectedOption(updateList);
setNomRegister(updateList);
}
} catch (e) {
console.log(e);
setNomRegister(reset);
setHelperText(e.message);
//history.push('/errorPage');
const updateList = selectedOption.map((item) => {
return { ...item, reason: "" };
});
setSelectedOption(updateList);
setNomRegister(updateList);
}
};
fetchData(nomRegister);
};
option.forEach((option) => {
option.displayValue =
option.firstName + "\t" + option.lastName + "\t" + option.email;
submittedNominees.forEach((item) => {
if (item.nomineeemail === option.email) {
item.displayValue =
item.nomineeFirstName +
"\t" +
item.nomineeLastName +
"\t" +
item.nomineeemail;
}
});
});
const handleChange = (e, i, lastName) => {
const { name, email, value } = e.target;
// immutating state (best practice)
const updateList = selectedOption.map((item) => {
return { ...item };
});
//change the specific array case depends on the id //email:emailList[i],
updateList[i] = {
name: name,
lastName: lastName,
email: updateList[i].email,
reason: value
};
setSelectedOption(updateList);
setNomRegister(updateList);
};
// - cancel the selection and clear the field.
const handleCancel = () => {
window.location.reload(false); //resetSelectedValues will reset all options even the disabled ones so the best choice here is to reload page
};
// A.H close the dialog after submit
useEffect(() => {
if (helperText === "Nomination submitted successfully !") {
handleCloseDialog();
setSelectedOption([]);
setNomRegister([]);
}
}, [helperText]);
// console.log(selectedOption, "selectedOption");
return (
<div className="App">
<div className="navbar-nav">
<div className="leftNavItem"></div>
</div>
<div className="nomHeader">
<h2>Nominate a person</h2>
</div>
<br></br>
<div className="nomineeSelectBox">
<div id="dialog2" className="triangle_down1" />
<div className="arrowdown">
<Multiselect
ref={refSelect}
onSelect={(e) => handleTypeSelect(e, selectedOption.length)}
onRemove={handleTypeRemove}
options={!showOptions ? [] : option} //A.H toogle
displayValue="displayValue"
disablePreSelectedValues={true}
selectedValues={submittedNominees}
showCheckbox={true}
emptyRecordMsg={"Maximum nominees selected !"}
/>
</div>
</div>
{/* A.H NP-5 */}
<div className="nominationcount">
<span
style={{
position: "absolute",
top: "23%",
left: "43%",
color: "#fff"
}}
>
{3 - maxOptions}
</span>
</div>
<form>
<div className="nomineesSelectedList">
<h4>Selected Nominees</h4>
{selectedOption.map((x, i) => (
<div key={i}>
<div className="row eachrecord">
<div className="column">
<label className="nomlabel">
{x?.name} <b>>></b>
</label>
</div>
<input
required
type="textarea"
placeholder="Please provide reason for nomination.."
key={i}
id={i}
name={x?.name}
value={x?.reason}
className="nomineechoosed"
maxLength="245"
onChange={(e) => handleChange(e, i, x.lastName)}
/>
</div>
</div>
))}
<div className="row">
<div className="buttongroup">
<input
id="Submit"
type="button"
value="Submit"
onClick={handleClickOpenDialog}
/>
<input
id="Cancel"
type="button"
value="Cancel"
onClick={handleCancel}
/>
</div>
</div>
</div>
</form>
</div>
);
}
解决方案
推荐阅读
- owl - 如何修复在 owlready2 中加载本体的此错误
- mongodb - Svelte 不会重新排序 Meteor 集合
- notepad++ - Notepad++:停止将我的制表符转换为 python 的空格
- javascript - npm 错误!反应中的代码ELIFECYCLE(构建问题)
- mongodb - Quarkus中如何清除测试环境TestContainer
- javascript - Typescript 中的 Promise 函数“类型 void 不可分配……”
- arrays - MongoDB - 从对象数组中检索对象数组。使用猫鼬
- scala - Flink:找不到类型信息类型的证据参数的隐式值
- excel - 使用 Vlookup 从两个工作表的公共列中获取多个匹配的行
- node.js - updating and validating multiple files from different fields uploded with multer