My checkbox is marking a noteid but whenever page is refreshed the checkbox vanishes. Also it's never saved to the database for some reason. Any ideas?
Part of the relevant code. ( full code in comments)
<div className="Data-flex" key={data.noteId}> <div className="NoteID" style={{ flex: 1 }}> {data.noteId} </div> <Checkbox style={{ flex: 1 }} onChange={handleStatus}
Function Below!
const [Status2, setStatus2] = useState(false);
const handleStatus = (event, data) => {
console.log("Marking todo ... Data : ", data);
setStatus2(true);
};
Related
So I have a group of buttons that are displayed using a map. When I hover over one of these buttons I want a black box to appear on the side of it. This black box will be developed into a preview.
However, because of the map function, the rest of the buttons get a preview when I hover over one button. This is how the buttons look before the hover. You have a subject, and the courses are listed under this. Both the courses and subjects are mapped.
When I hover over a single button all the button previews are set to true. When I move my mouse off the button, all the previews are removed. How can I single out a button to have a specific preview?
export default function Yeartwo() {
const [grade, setGrade] = useState(localStorage.getItem('grade'));
const [preview, setPreview] = useState(false);
let grades = Object.keys(courseData)
let nextGrade = grades[Object.keys(courseData).indexOf(grade)+1]
let subjects = courseData[nextGrade].subjects
let courses = courseData[nextGrade].classes
function coursePreview(e) {
e.preventDefault();
console.log('hovered')
setPreview(true)
}
return (
<div className="courseSelect">
{subjects.map((subject, index) => (
<div key={index}>
<h2 className="subject">{subject}</h2>
<div className="courses">
{courses[subject].map((course, index) => (
<div key={index}>
<button value={subject} className="course_btn" onMouseEnter={() => setPreview(true)} onMouseLeave={() => setPreview(false)}>{course}</button>
{preview && <div className="preview"> {course} </div>}
</div>
))}
</div>
</div>
))}
</div>
)
}
Reorder your preview state to contain an object instead of booleans. The object should be in the following format: { 'course1': boolean, 'course2': boolean, ..., 'courseN': boolean } - course is the key and the boolean value represents whether the preview for this item should be shown or not.
Therefore, your condition should look like this: {preview['course'] && <div className="preview"> {course} </div>}
And update your listeners to be like this: {... onMouseEnter={() => setPreview({...preview, 'course': true}) ...} and the same for the onMouseLeave method.
I wanted to emulate a Google Photos gallery style in my project. Where if I click on an image it will provide a partial view, but when I click on another image the first partial view is replaced by the new image and data.
The structure of my code is that I have a set of components Pictures that contains another component PartialView, I have an onClick function that checks if that picture is clicked, the PartialView component will appear. However, I don't know how to manage the states so that when I click on another different image, the opened PartialView will close and the other component's PartialView will open instead.
My current bug is that I can open both PartialView at the same time, and they end up overlapping. I just want the newly clicked Pictures component to have a PartialView opened.
The structure of my code:
// the function that allows me to click on each Picture independently
// state only updated on Picture id
const [open, setOpen] = useState(false);
function openFunction (id) {
setOpen({
...open,
[id]: !open[id],
});
}
// each Picture component made from different inputs from server
// PartialView will only appear if Picture is clicked
let pictures = null;
if (userData) {
pictures = userData.map(
({ artefactName, artefactImg, description, artefactDate, _id }) => (
<article
className="card-container"
onClick={() => openFunction(_id)}
style={{ padding: open[_id] ? '0 0 480px 0' : '0 0 0 0' }}
>
<div>
<div className="card">
<img src={artefactImg.imgURL} />
<div className="card-title">
<p>{artefactName}</p>
</div>
</div>
<div style={{ display: open[_id] ? 'block' : 'none' }}>
<PartialView title={artefactName} image={artefactImg} desc={description}
date={artefactDate} />
</div>
</div>
</article>
)
);
}
// item Pictures are returned
return (
<main>
<div className="main-container">
<div className="main-cards">
<div className="section-cards">
<div className="feed-cards">
{pictures}
</div>
</div>
</div>
</div>
</main>
);
a division has a checkboxs and by clicking that checkbox radio buttons options need to be shown for a particular checkbox
checkbox is mapped as according to the array
<form id="lab_test_detail">
{item.subcategory.map((item, index) =>
<>
<input type={"checkbox"} onChange={() => handleChange(item, index)} name={item.id}></input>
<label style={{ position: "inherit", zIndex: "10" }}>{item.categoryname} </label>
<div id={index}></div>
</>
)}
</form>
when the checkbox is changed radio buttons option should have to populate on
handleChange is
const handleChange = (item, index) => {
httpClient.GET(`medical-institute/categoryId/${item.id}`, false, true)
.then(resp => {
// debugger;
document.getElementById(index).innerHTML =
`
${
resp.data.data.map((item1,index1)=>{
return`<form>
<input type="radio" onChange=${handleRadioChange(item,index)}></input>
<label >${item1.medicalinstitutename}</label>
<span> Rs.${item1.price}</span>
<br/>
</form>
`
})
}
`
console.log("response is", resp.data.data)
})
}
const handleRadioChange = (item, index) => {
console.log("inside radiochange")
console.log("dasdas", item, index)
}
so when radio button is clicked i need to do a particular thing but handleRadioChange is called when i click on the checkox but not when i click on radio , why is this happening, a ny solution?
Because you are executing the handleRadioChange once the node is added into the DOM.
Change the onChange handler
handleRadioChange(item,index)
to
() => handleRadioChange(item,index)
You should try to work with the virtual DOM instead of insert html string.
In your case, I think you can use state to store the item data for display and trigger the re-render. BTW you might don't have to fetch the data every time user clicks a check box.
While working with the controlled input components if we set the value of the controlled component to null or undefined the previous value is still displayed on the UI instead of changing it and the state holding that input value changes to null or undefined. I have created a sandbox for better understanding
https://codesandbox.io/s/black-architecture-0wqw1
Thank you
If the data type is null or undefined react automatically supress that value and log nothing.
If you want to see the type of that particular value, write {typeof data}, then you'll get your answer.
...
setData(null)
typeof data // object
setData("hi")
typeof data // string
setData(undefined)
typeof data // undefined
...
here is quick fix, it never changes value variable, if data then put data else empty string, that how it works
<input
type="text"
onChange={(e) => setData(e.target.value)}
value={data ? data:""}
/>
i hope this will solve your problem,
here is complete fix,
https://codesandbox.io/embed/optimistic-currying-snn8t?fontsize=14&hidenavigation=1&theme=dark
You can use ref tout change the value of your input anywhere outside your input component, see bellow :
import React, { useState, useEffect } from "react";
import "./styles.css";
export default function App() {
const [data, setData] = useState(null);
const inputRef = React.useRef(null);
useEffect(() => {
console.log(data);
}, [data]);
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<input
ref={inputRef}
type="text"
onChange={(e) => setData(e.target.value)}
value={data}
/>
<div style={{ marginTop: "10px" }}>
<button onClick={() => {
setData(null);
inputRef.current.value = ''
}}>SET DATA NULL</button>
</div>
<div style={{ marginTop: "10px" }}>
<button onClick={() => {
setData(undefined)
inputRef.current.value = ''
}}>
SET DATA UNDEFINED
</button>
</div>
<div style={{ marginTop: "10px" }}>INPUT VALUE {data}</div>
</div>
);
}
Sorry, I can't be very specific with the details of the problem as it only happens sometimes, and I haven't been able to recreate it, which means I have no clue where to start trying to fix it.
It appears to only happen on really cheap android tablets.
I have a page with a form where the user fills in details, The problem happens just after they have entered their name into a text field and then once they press onto the react-signature-canvas to start drawing their signature the app crashes (doesn't crash all the time).
in the past, I think the crash was caused when the keyboard was still open when the user tried to start drawing on the signature pad.
As I said, I'm finding it really difficult to fix as I can't recreate it, so any help at all would be greatly appreciated.
I'm using React Hooks and Formik.
Form:
<h2>Guardian Full Name</h2>
<MyTextField
label="Guardian Full Name"
name="parentName"
required
/>
<ErrorMessage
component={"div"}
className={"termsConditionText error"}
name={"parentSignature"}
/>
<SignaturePad setFieldValue={setFieldValue} />
SignaturePad:
import React, { useRef, useState } from "react";
import { Button } from "semantic-ui-react";
import "../../pages/SignDisclaimerForm/SignDisclaimerForm.css";
import "./signaturePad.css";
import SignatureCanvas from "react-signature-canvas";
export const SignaturePad = props => {
const [canvasImageUrl, setCanvasImageUrl] = useState([
props.parentSignature || ""
]);
let sigCanvas = useRef();
const clearCanvas = () => sigCanvas.current.clear();
const saveCanvas = async () => {
if (sigCanvas.current.isEmpty()) return;
document.getElementById("parentName").blur();
props.setFieldValue(
"parentSignature",
sigCanvas.current.getTrimmedCanvas().toDataURL("image/png")
);
setCanvasImageUrl(
sigCanvas.current.getTrimmedCanvas().toDataURL("image/png")
);
};
return (
<div>
{!props.disabled && (
<div>
<h2 style={{ marginLeft: "5%" }}>Guardian Signature</h2>
<div className={"sigContainer"}>
<SignatureCanvas
ref={sigCanvas}
canvasProps={{ className: "sigPad" }}
onEnd={saveCanvas}
/>
</div>
<Button
style={{ marginLeft: "5%", marginTop: "2%", marginRight: "2%" }}
type={"button"}
onClick={clearCanvas}
children={"Clear"}
/>
<br />
<br />
</div>
)}
{canvasImageUrl[0] && (
<div className={"signatureDisplay"}>
<img
src={canvasImageUrl}
alt={"Guardian Signature"}
style={{ height: "100%", width: "100%" }}
/>
</div>
)}
</div>
);
};
Sentry issue report also below.
Issue Title:
TypeError HTMLCanvasElement.r(src/helpers)
error
Cannot read property 'push' of undefined
Issue Body:
../../src/helpers.ts in HTMLCanvasElement.r at line 85:17
}
// Attempt to invoke user-land function
// NOTE: If you are a Sentry user, and you are seeing this stack frame, it
// means the sentry.javascript SDK caught an error invoking your application code. This
// is expected behavior and NOT indicative of a bug with sentry.javascript.
return fn.apply(this, wrappedArguments);
// tslint:enable:no-unsafe-any
} catch (ex) {
ignoreNextOnError();
withScope((scope: Scope) => {
Bread Crumbs:
This is what the form looks like:
Formik author here...
You might be setting state from an unmounted DOM element (the canvas). It doesn't happen all the time because it's a race condition. You should check whether the canvas ref is actually mounted before using methods on it within your callbacks.
// ...
const sigCanvas = useRef(null);
const clearCanvas = () => {
if (sigCanvas.current != null) {
sigCanvas.current.clear();
}
};
const saveCanvas = async () => {
// Ensure that the canvas is mounted before using it
if (sigCanvas.current != null) {
if (sigCanvas.current.isEmpty()) return;
document.getElementById("parentName").blur();
props.setFieldValue(
"parentSignature",
sigCanvas.current.getTrimmedCanvas().toDataURL("image/png")
);
setCanvasImageUrl(
sigCanvas.current.getTrimmedCanvas().toDataURL("image/png")
);
}
};
// ...
Thank you to everyone who helped me, I really appreciated it.
What I did in the end to fix the problem was just to have a green button the user had to press in order to open the signature pad.
The fact that the user has to press the open button, gives the keyboard enough time to completely dismiss before the user starts to draw on the signature pad.
Thank you :)