gpt4 book ai didi

javascript - 仅在单击提交按钮时将数据从多个复选框传递到 api :react js

转载 作者:行者123 更新时间:2023-12-05 00:37:56 27 4
gpt4 key购买 nike

仅在单击提交按钮时将数据从多个复选框传递到 api
当我单击复选框时,我的网站上有这个 Accordion ,所有复选框值都存储在状态中,最后当我单击提交时,只有数据被传递给 api,存储的数据如下所示

   const getAccordionItem = ({ key, label }) => {
const source = key === "Custom" ? "custom" : "items";

return (
<div className="accordion-item" key={key}>
<div
className="accordion-title gradiantblur"
onClick={() => navClose(key)}
>
{/* // onClick={setActiveCurrentIndex(item[0].date)}> */}
<div>{label}</div>
<i className="fa fa-plus" aria-hidden="true"></i>
</div>
{state[key] ? (
<div className="accordion-content tableforsymtm">
{(source !== "custom"
? state[source].filter(
(item) => item.category === label || item.category === key
)
: state[source]
).map((item, index) => {
return (
<span
key={`${key}__${item.id}__${index}`}
className="trforsymtm"
>
<td>
<input
// className="invinsiveinput"
data-id={item.id}
type="checkbox"
id={item.id}
checked={item && item.positive}
onChange={(e) => handleCheckboxChange(e, source, item.id)}
/>
</td>
<td className="tdoneline">
<label htmlFor={item.id}>{item.name}</label>
</td>
</span>
);
})}
</div>
) : null}
</div>
);
};

const handleCheckboxChange = (e, stateKey, itemId) => {
const stateItems = state[stateKey];
const index = stateItems.findIndex((item) => item.id === itemId);

setState((prevState) => ({
...prevState,
[stateKey]: [
...stateItems.slice(0, index),
{
...stateItems[index],
positive: e.target.checked,
},
...stateItems.slice(index + 1),
],
}));
};

提交按钮点击
 const chekbox = (e) => {
e.preventDefault();
const headers = {


};
const data = {
items: [...state.items]
.filter((item) => item.positive)
.map((item) => ({
date: state.today,
symptom: item.id,
positive: item.positive,
})),
};

const custum = {
items: [...state.custom]
.filter((item) => item.positive)
.map((item) => ({
date: state.today,
symptom: item.id,
positive: item.positive,
})),
};
console.log(custum);
axios.post("/customer/submit-multiple/", data, {
headers: headers,
});
axios
.post("/customer/submit-custom-multiple/", custum, {
headers: headers,
})
.then(() => {
alert("was submitted");
window.location.reload();
})
.catch((error) => {
alert("Cannot add submittedagain");
});
};


我在代码沙箱中添加的完整代码
注意根据 Hirens 的回答更新
https://codesandbox.io/s/objective-jone5tlds
现在我面临的问题是,如果用户单击复选框,则其检查值将添加到状态中,并且如果用户在提交之前取消选中该复选框,则数组中将有 2 个条目
  • 一个已选中 (true)
  • 2nd as unchecked (false)

  • 所以复选框数据2值不能提交到数组并传递给api
    我希望像这样传递数据
    我收到 500 错误
    [
    {
    "date" : "2022-02-15",
    "id" : 6,
    "positive" : true
    },
    {
    "date" : "2022-02-15",
    "id" : 5,
    "positive" : true
    },
    {
    "date" : "2022-02-15",
    "id" :7,
    "positive" : true
    },
    {
    "date" : "2022-02-15",
    "id" : 11,
    "positive" : true
    },
    {
    "date" : "2022-02-15",
    "id" : 4,
    "positive" : true
    }
    ]

    最佳答案

    我不确定我是否正确理解了您的问题。但我试图让它只在提交按钮点击时提交值。另外,我尝试使用功能组件并修改了您的代码以使其更简单(如果没有,我希望您了解新的功能组件方式,这是编写 React 组件的新方式)。
    您可以在此处查看完整版本:https://codesandbox.io/s/relaxed-tesla-qwmh7v?file=/src/App.js .
    由于某种原因,API 仍然失败,但不知道为什么,但有效负载是你想要的。并且,添加了一些评论来帮助你。让我知道事情的后续!祝你好运! 👍

    import React from "react";
    import axios from "axios";
    import moment from "moment";

    import "./styles.css";
    // function to get data from API, taken it out since it
    // does not depend on state as such, we can pass date a param
    const getData = (date) => {
    const config = {
    headers: {
    // can be taken from localStorage
    Authorization: `token 67f023b5e798b8e7217bffc4b74a23b40666c589`
    }
    };
    return axios
    .get(
    `https://shebirth.herokuapp.com/customer/Symptoms-GET/?date=${date}`,
    config
    )
    .then((res) => res.data)
    .catch((err) => {
    console.error("error ocurred while fetching data", err);
    return null;
    });
    };

    const SYMPTOMS_CATEGORIES = [
    { key: "Head", label: "Head" },
    { key: "Pelvis", label: "Pelvis" },
    { key: "Legs", label: "Legs" },
    { key: "Other", label: "Other" },
    { key: "Abdomen", label: "Abdomen" },
    { key: "Mental", label: "Mental Health" },
    { key: "Custom", label: "User Defined" }
    ];

    const styles = {
    trgrid: {
    display: "grid",
    gridTemplateColumns: "1fr 1fr 1fr 1fr"
    },
    module: {
    position: "relative",
    // background: "rgb(76, 0, 61) none repeat scroll 0% 0%",
    background: "#ffffff1c 0% 0% no-repeat padding-box",
    margin: "0px 30px",
    borderRadius: "10px",
    padding: "0px 0px 20px 0px",
    height: "40rem",
    overflowY: "scroll",
    scrollbarWidth: "thin",
    marginbottom: "10px"
    },
    txt: {
    textAlign: "left"
    },
    btn: {
    border: "1px solid #974cae",
    padding: "5px 30px",
    background: "#974cae",
    fontSize: "12px"
    },
    left: {
    textAlign: "left"
    },
    boxstyle: {
    background: "#ffffff1c 0% 0% no-repeat padding-box",
    marginTop: "10px"
    },
    flex: {
    background: "#ffffff1c 0% 0% no-repeat padding-box",
    marginTop: "10px",
    display: "flex"
    // justifyContent: "space-evenly",
    //background: "#971cae",
    },
    subbtn: {
    background: "linear-gradient(90deg, #3a51a7 30%, #b53899)",
    padding: "10px 30px",
    border: "none",
    borderRadius: "10px",
    color: "#fff",
    cursor: "pointer",
    margin: "10px"
    },
    // NOTE: just for demo styling purpose for separate headings a bit!!
    // use your own styles!!!
    accordionItem: {
    marginTop: "10px",
    marginBottom: "10px"
    },
    accordionHeader: {
    fontWeight: "bold",
    cursor: "pointer",
    backgroundColor: "#7986cb",
    color: "#000",
    padding: "2px 4px"
    }
    // demo styles ends
    };

    const SymptomTracker = () => {
    const [state, setState] = React.useState({
    medicineOpen: true,
    medicineReady: true,
    symptomReady: false,
    items: [],
    dateState: [],
    custom: [],
    Head: false,
    Pelvis: false,
    Legs: false,
    Mental: false,
    Other: false,
    Custom: false,
    today: moment().format("YYYY-MM-DD"),
    report: [],
    allValues: {
    others: "",
    bloodSugar: "",
    bloodPressure: ""
    }
    });

    // const closeMedicine = () => {
    // setState((prevState) => ({
    // ...prevState,
    // medicineOpen: !state.medicineOpen
    // }));
    // };

    // const addMedicine = () => {
    // setState((prevState) => ({
    // ...prevState,
    // medicineReady: !state.medicineReady
    // }));
    // };

    const addSymptom = () => {
    setState((prevState) => ({
    ...prevState,
    symptomReady: !state.symptomReady
    }));
    };

    const navClose = (e) => {
    setState((prevState) => ({
    ...prevState,
    [e]: !prevState[e]
    }));
    };

    const onDateChange = (e) => {
    var dateSelected = e.target.value;
    var date = moment(dateSelected).format("YYYY-MM-DD");
    console.log({ date });
    setState((prevState) => ({ ...prevState, today: date }));
    };

    const handleCheckboxChange = (e, stateKey, itemId) => {
    const stateItems = state[stateKey];
    console.table(stateItems);
    console.log({ stateKey });
    const index = stateItems.findIndex((item) => item.id === itemId);

    console.log({ item: stateItems[index] });

    setState((prevState) => ({
    ...prevState,
    [stateKey]: [
    ...stateItems.slice(0, index),
    {
    ...stateItems[index],
    positive: e.target.checked
    },
    ...stateItems.slice(index + 1)
    ]
    }));
    };

    const changeHandler = (e) => {
    setState((prevState) => ({
    ...prevState,
    allValues: {
    ...prevState.allValues,
    [e.target.name]: e.target.value
    }
    }));
    };

    const getAccordionItem = ({ key, label }) => {
    const source = key === "Custom" ? "custom" : "items";

    return (
    <div className="accordion-item" style={styles.accordionItem} key={key}>
    <div
    className="accordion-title gradiantblur"
    style={styles.accordionHeader}
    onClick={() => navClose(key)}
    >
    {/* // onClick={setActiveCurrentIndex(item[0].date)}> */}
    <span>{label}</span>
    <i className="fa fa-plus" aria-hidden="true"></i>
    </div>
    {state[key] ? (
    <div className="accordion-content tableforsymtm">
    {(source !== "custom"
    ? state[source].filter(
    (item) => item.category === label || item.category === key
    )
    : state[source]
    ).map((item, index) => {
    const itemId = `${key}__${item.name}__${item.id}__${index}`;
    return (
    <span key={itemId} className="trforsymtm">
    <td>
    <input
    // className="invinsiveinput"
    data-id={item.id}
    type="checkbox"
    id={itemId}
    checked={item && item.positive}
    onChange={(e) => handleCheckboxChange(e, source, item.id)}
    />
    </td>
    <td className="tdoneline">
    <label htmlFor={itemId}>{item.name}</label>
    </td>
    </span>
    );
    })}
    </div>
    ) : null}
    </div>
    );
    };

    // handle checked items submission
    const chekbox = (e) => {
    e.preventDefault();
    const headers = {
    // Authorization: `token ` + localStorage.getItem("token")
    Authorization: `token 67f023b5e798b8e7217bffc4b74a23b40666c589`
    // Authorization: `token 67f023b5e798b8e7217bffc4b74a23b40666c589`,
    };
    const data = [...state.items]
    // keep all items
    // .filter((item) => item.positive)
    .map((item) => ({
    date: state.today,
    symptom: item.id,
    positive: item.positive
    }));

    const custom = [...state.custom]
    // keep all items
    //.filter((item) => item.positive)
    .map((item) => ({
    date: state.today,
    symptom: item.id,
    positive: item.positive
    }));

    console.log(custom);
    // submit both requests parallelly and once both gets done
    // then only reload the page.
    Promise.all([
    axios.post(
    "https://shebirth.herokuapp.com/customer/symptoms-submit-multiple/",
    data,
    {
    headers: headers
    }
    ),
    axios.post(
    "https://shebirth.herokuapp.com/customer/submit-custom-symptom-multiple/",
    custom,
    {
    headers: headers
    }
    )
    ])
    .then(() => {
    alert("symptoms are submitted");
    window.location.reload();
    })
    .catch((error) => {
    alert("Cannot add symptoms again");
    console.error(error);
    });
    };

    const onSubmit = (e) => {
    e.preventDefault();

    const headers = {
    // Authorization: `token ` + localStorage.getItem("token")
    Authorization: `token 67f023b5e798b8e7217bffc4b74a23b40666c589`
    };

    // prepare data object
    const data = {
    others: state.allValues.others,
    bloodSugar: state.allValues.bloodSugar,
    bloodPressure: state.allValues.bloodPressure,
    date: state.today,
    // combining custom and normal items together, can be separated if you want
    // in their each keys
    items: [...state.items, ...state.custom]
    // keep all items
    // .filter((item) => item.positive)
    .map((item) => ({
    date: state.today,
    symptom: item.id,
    positive: item.positive
    }))
    };

    axios
    .patch("customer/submit-symptoms-with-input/", data, {
    headers: headers
    })
    .then(() => {
    alert("symptom was submitted");
    window.location.reload();
    })
    .catch((error) => {
    alert("Cannot add symptoms again");
    });
    };

    // this effect will fire once the component is mounted, and on `state.date` changes.
    React.useEffect(() => {
    (async () => {
    const data = await getData(state.today);
    // console.log({ data });

    if (data) {
    setState((prevState) => ({
    ...prevState,
    items: data.Symptoms,
    custom: data.customSymptom,
    allValues: data.symptomsWithIputs,
    report: data.last_week_symptom_report
    }));
    }
    })();
    }, [state.today]);

    return state.medicineOpen ? (
    <div className="symptom-container" style={styles.module}>
    <h2
    className="lightgradient"
    style={{
    borderBottom: "1px solid #fff",
    padding: "10px",
    margin: "0px",
    fontSize: "24px",
    // background: "#6f1f6d",
    borderTopLeftRadius: "10px",
    borderTopRightRadius: "10px"
    }}
    >
    Symptom Tracker
    </h2>

    <div style={styles.boxstyle}>
    <span style={{ fontSize: "16px" }}> Enter Date</span>
    <input
    type="date"
    className="calanderbutton"
    value={state.today}
    onChange={onDateChange}
    />

    {/* accordion */}
    <div className="accordion">
    {SYMPTOMS_CATEGORIES.map(getAccordionItem)}
    </div>
    <button type="Button" className="pinkbutton" onClick={chekbox}>
    submit check boxes
    </button>
    {/* form */}
    <form onSubmit={onSubmit}>
    <div style={styles.flex}>
    <div
    className="marign-5"
    style={{
    transform: "rotate(90deg)",
    fontSize: "4rem",
    padding: "15px"
    }}
    >
    {/* <img src={img1} /> */}
    {/* <i className="fa fa-pencil"></i> */}
    </div>
    <div className="marign-5" style={{ padding: "10px" }}>
    <strong>Enter your weight</strong>
    <br />
    <br />

    <input
    className="inputofsymtum"
    style={{ float: "left" }}
    name="others"
    placeholder="Kg"
    onChange={changeHandler}
    defaultValue={state.allValues && state.allValues.others}
    type="text"
    // placeholder="Description"
    />
    </div>
    </div>
    <div style={styles.flex}>
    <div
    className="marign-5"
    style={{ fontSize: "4rem", padding: "15px" }}
    >
    {/* <img src={img2} /> */}
    {/* <i className="fa fa-level-up"></i> */}
    </div>
    <div className="marign-5" style={{ padding: "10px" }}>
    <strong>Enter your blood sugar level</strong>
    <br />
    <br />
    <input
    className="inputofsymtum"
    style={{ float: "left" }}
    type="text"
    name="bloodSugar"
    placeholder="(mg/dL)"
    onChange={changeHandler}
    defaultValue={state.allValues && state.allValues.bloodSugar}
    />
    </div>
    </div>
    <div style={styles.flex}>
    <div
    className="marign-5"
    style={{ fontSize: "4rem", padding: "15px" }}
    >
    {/* <img src={img3} /> */}
    {/* <i className="fa fa-area-chart"></i> */}
    </div>
    <div className="marign-5" style={{ padding: "10px" }}>
    <strong>Enter your blood pressure level</strong>
    <br />
    <br />
    <input
    className="inputofsymtum"
    style={{ float: "left" }}
    type="text"
    placeholder="(mmHg)"
    name="bloodPressure"
    onChange={changeHandler}
    defaultValue={state.allValues && state.allValues.bloodPressure}
    // onChange={changeHandler}
    // value={state.allValues.bloodPressure}
    />
    </div>
    </div>
    <div style={styles.flex}>
    <div
    className="marign-5"
    style={{
    transform: "rotate(90deg)",
    fontSize: "4rem",
    padding: "15px"
    }}
    >
    {/* <img src={img4} /> */}
    {/* <i className="fa fa-pie-chart"></i> */}
    </div>
    <div className="marign-5" style={{ padding: "10px" }}>
    <strong>Last week report</strong>
    <br />
    <br />
    <p className="fontin12">
    Last week you have experienced &nbsp;
    {state.report.map((personData, key) => {
    return (
    <span key={key}>
    {personData.count}&nbsp;times&nbsp;
    {personData.symptom}&nbsp;,&nbsp;
    </span>
    );
    })}
    </p>
    </div>
    </div>
    <div>
    <button type="submit" className="pinkbutton">
    Submit
    </button>
    </div>
    <br />
    {/* {state.symptomReady ? <AddSymptom /> : null} */}
    <span
    onClick={addSymptom}
    // style={styles.subbtn}
    className="pinkbutton"
    style={{ cursor: "pointer", fontSize: "16px" }}
    >
    Add User Defined Symptom
    </span>
    <hr />
    </form>
    </div>
    </div>
    ) : null;
    };

    export default SymptomTracker;

    关于javascript - 仅在单击提交按钮时将数据从多个复选框传递到 api :react js,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71140935/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com