How to add radio button in a quiz app in react - reactjs

I am working on a quiz app and currently, I have just a button as my option but I want to choose radio buttons as my options and I also want to have a submit feature.
This is my code:
<>
{showScore ? null : <div>Countdown: {counter}</div>}
<div className="question_no">
<span>Question {currentQuestion + 2}</span>/{questions.length}
</div>
<div className="quiz-container">
{showScore ? (
<div className="score">
You scored {score} out of {questions.length}
</div>
) : (
<>
<div className="quiz-header">
<div className="question">
{questions[currentQuestion].questionText}
</div>
</div>
<div className="answer_div">
{questions[currentQuestion].answerOptions.map(
(answerOption) => (
<button
onClick={() =>
handleAnswerOptionClick(
answerOption.isCorrect
)
}
>
{answerOption.answerText}
</button>
)
)}
</div>
</>
)}
</div>
</>
how can i change the button option to radio button

Radio is not a button type, but an input type, so probably something like this:
<div className="answer_div">
{questions[currentQuestion].answerOptions.map(
(answerOption) => (
<input type="radio" id={answerOption.answerID}
onClick={() =>
handleAnswerOptionClick(
answerOption.isCorrect
)
}
/>
<label htmlFor={answerOption.answerID}>
{answerOption.answerText}
</label>
)
)}
</div>
Maybe you wanna also use onChange instead of onClick.

Related

onClick load react component in the same place

I have a panel with 3 buttons, i want to make onclick on every button, a different component will appear in the same place. How can this logic be done?
<AddNotification />
<EditNotification />
<DeleteNotification />
const AdminPanel = () => {
return (
<Card className={classes.input}>
<div><h1>Notification Panel</h1></div>
<form>
<div className="form-group">
<Button type="submit">Add Notification</Button>
</div>
<div className="form-group">
<Button type="submit">Edit Notification</Button>
</div>
<div className="form-group">
<Button type="submit">Delete Notification</Button>
</div>
</form>
</Card>
)
}
#MLDC No i don't have another divs, i want to replace the buttons with the crossponding component. For example: onclick on Add, then Add component will appears instead of the buttons.
In that case, create a boolean state for every Panel that you have (I created 3 so that you could open the panels simultaneously),
const [isAddPanelOpen, setIsAddPanelOpen] = useState(false);
const [isEditPanelOpen, setIsEditPanelOpen] = useState(false);
const [isDeletePanelOpen, setIsDeletePanelOpen] = useState(false);
Next, apply this to every button
<Button onClick={setIsAddPanelOpen(prevState=>!prevState)}>Add Notification</Button>
<Button onClick={setIsEditPanelOpen(prevState=>!prevState)}>Edit Notification</Button>
<Button onClick={setIsDeletePanelOpen(prevState=>!prevState)}>Delete Notification</Button>
Lastly, Refactor your html to
<div className="form-group">
{isAddPanelOpen ? <AddNotification/> : <Button type="submit">Add Notification</Button>}
</div>
<div className="form-group">
{isEditPanelOpen ? <EditNotification/> : <Button type="submit">Edit Notification</Button>}
</div>
<div className="form-group">
{isDeletePanelOpen ? <DeleteNotification/> :<Button type="submit">Delete Notification</Button>}
</div>
Try this if you want to display one component at a time and hide the others when you click a button
const AdminPanel = () => {
const [componentToDisplay, setComponentToDisplay] = useState("")
return (
<>
<Card className={classes.input}>
<div><h1>Notification Panel</h1></div>
<form>
<div className="form-group">
{componentToDisplay !== "add ? (
<Button type="submit" onCLick={() => setComponentTodisplay("add")}>Add Notification</Button>)
:(<AddNotification />)}
</div>
<div className="form-group">
{componentToDisplay !== "edit ? (
<Button type="submit" onCLick={() => setComponentTodisplay("edit")}>Edit Notification</Button>)
:(<EditNotification />)}
</div>
<div className="form-group">
{componentToDisplay !== "delete ? (
<Button type="submit" onCLick={() => setComponentTodisplay("delete")}>Delete Notification</Button>)
:(<DeleteNotification />)}
</div>
</form>
</Card>
</>
)
}
Or if you want to be able to replace every buttons, use this logic with one state per button
const AdminPanel = () => {
const [addNotif, setAddNotif] = useState(false)
const [editNotif, setEditNotif] = useState(false)
const [deleteNotif, setDeleteNotif] = useState(false)
return (
<>
<Card className={classes.input}>
<div><h1>Notification Panel</h1></div>
<form>
<div className={`form-group ${editNotif || deleteNotif ? "display: none" : "display: flex"}`}>
{!addNotif ? (
<Button type="submit" onCLick={() => setAddNotif(true)}>Add Notification</Button>)
:(<AddNotification setAddNotif={setAddNotif} />)}
</div>
<div className={`form-group ${addNotif || deleteNotif ? "display: none" : "display: flex"}`}>
{!editNotif ? (
<Button type="submit" onCLick={() => setEditNotif(true)}>Edit Notification</Button>)
:(<EditNotification setEditNotif={setEditNotif} />)}
</div>
<div className={`form-group ${addNotif || editNotif ? "display: none" : "display: flex"}`}>
{!deleteNotif ? (
<Button type="submit" onCLick={() => setDeleteNotif(true)}>Delete Notification</Button>)
:(<DeleteNotification setDeleteNotif={setDeleteNotif} />)}
</div>
</form>
</Card>
</>
)
}
Then in your component
const AddNotification = ({setAddNotif}) => {
...
return (
...
<button onCLick={() => setAddNotif(false)}>back</button>
...
)
}
Same logic for the other components
To achieve this logic you need to manage which component is displayed using a state.
This means:
Attribute an arbitrary id to each component.
Store the id of the active component in a useState hook.
Use conditional rendering to display the component that match the current state.
Update the state to the corresponding Id when clicking on each button.
A small example
const [activePanel, setActivePanel] = React.useState(0)
let currentPanel = <Panel0 />
switch(activePanel){
case 0:
currentPanel = <PanelO />
case 1:
currentPanel = <Panel1 />
// Continue as needed
}
return (
<div>
<CurrentPanel/>
<button onClick={() => setActivePanel (0)}> Panel 0 </button>
<button onClick={() => setActivePanel (1)}> Panel 1 </button>
// And so on
</div>
)
You can further refine this by extracting the switch statement into its own component that takes the activePanel as a prop.

Creating a modal in React JS on pre-existing button

I want a modal to open when I click on an info circle on the product info button. I can't figure out how to do this in react after the export default statement.
The export default is important to other events in my code so I wanted to keep that as it is.
export default ({ product, addToBasket, removeFromBasket, openModal}) => {
return (
<div className={styles.tile}>
<div className={styles.tileGrid}>
<div className={styles.imageContainer}>
<FontAwesomeIcon icon={faCamera} />
</div>
<h3 className={styles.shortDescription}>{product.shortDescription}</h3>
<p className={styles.price}>£{product.price}</p>
{product.quantity && (
<p className={styles.quantity}>Quantity: {product.quantity}</p>
)}
{
<div className={styles.modal} onClick={() => openModal(product)}>
<FontAwesomeIcon icon={faInfoCircle} /> Product Info
</div>}
{addToBasket && (
<button className={styles.cta} onClick={() => addToBasket(product)}>
<FontAwesomeIcon icon={faShoppingBasket} /> Add to Basket
</button>
)}
{removeFromBasket && (
<button
className={styles.secondaryButton}
onClick={() => removeFromBasket(product)}
>
Remove from Basket
</button>
)}
</div>
</div>
);
};
Have used the following link but can't get it working in my code: https://www.pluralsight.com/guides/how-to-trigger-modal-for-react-bootstrap

filter firstname from 3 map() in react js

i have this input filed in my code for serching the list i have 3 catagery of list which are displayed by three map() i want to input a name in the input fild and if it exist i want to show the firstname just like whatsapps serach works
<form style={{ display: "flex" }}>
<input
className="w-100 msserserch gradiantblur"
placeholder="seach messages"
onChange={(e) =>
this.setState({ serchinput: e.target.value })
}
type="Search"
/>
</form>
the map() are given below there are 3 i want when i type in input fild fistname mustbe filterd from this
{this.state.tablist == "doctor" ? (
<div
className="chat-avatar gradiantblur"
onClick={() => this.livechat(this.state.list.id)}
>
<div></div>
<div className="alignstart">
{this.state.list.firstname} {this.state.list.lastname}
<p className="margin-0">
{" "}
{this.state.list.speciality}
</p>
<p className="margin-0">
✓ {this.state.list.speciality}
</p>
</div>
<div>152:11</div>
</div>
) : this.state.tablist == "consultant" ? (
<>
<div className="scrollerchatlist">
{console.log(this.state.consulatnt)}
{this.state.consulatnt.map((data) => (
<div
className="chat-avatar gradiantblur"
onClick={() => this.livechat(data.id)}
>
<div>
</div>
<div className="alignstart">
{data.firstname} {data.lastname}
<p className="margin-0"> {data.speciality}</p>
<p className="margin-0">
✓ {data.firstname}
</p>
</div>
<div>152:11</div>
</div>
))}
</div>
</>
) : this.state.tablist == "sales" ? (
<>
<div className="scrollerchatlist">
{this.state.sales.map((data) => (
<div
className="chat-avatar gradiantblur"
onClick={() => this.livechat(data.id)}
>
<div>
</div>
<div className="alignstart">
{data.firstname}
<p className="margin-0">
</p>
</div>
<div>152:11</div>
</div>
))}
</div>
</>
) : null}
my code is big so i put it in codesandbox
https://codesandbox.io/s/intelligent-nova-v7pb1?file=/src/App.js
I see in your code, you have this.state.tablist which is deciding what to render when any tab gets selected. So whenever user types in the input, you can just filter out firstname string from all three array and render them in your list:
onChange={this.onSearchTextChange}
onSearchTextChange(event) {
const query = event.query.target;
if(query){
const dataSet = [this.state.sales, this.state.consultants, ...];
const filteredName = dataSet.map(
data => data.filter(row => row.firstName).filter(Boolean)
).flat();
// now set the state with this data
this.setState({...});
}
}

Select only one plan at the time React State Hook

So basically I got 3 plans, but I want to be able to only select 1 at the time. But when I do click on 1 all 3 are selected. I output the plans from map, tried using index of each plan, but didn't work.
const [selectedPlan, setSelectedPlan] = useState(false);
const handleSelectPlan = () => {
setSelectedPlan((prevSelectedPlan) => !prevSelectedPlan);
};
`
{data.plans.map((each) => (
<div className={styles.pricingPlans__each} key={each.id}>
<div className={styles.header}>
<h3>{each.header}</h3>
</div>
<div className={styles.price}>
<h4>£{each.price}/mo.</h4>
</div>
<div className={styles.body}>{each.body}</div>
<div className={styles.cta}>
<button onClick={() => handleSelectPlan(each.id)}>
{selectedPlan ? <FaCheck /> : null} Select
</button>
</div>
</div>
))}
You need to check for the correct selected plan not just if one is selected:
{data.plans.map((each) => (
<div className={styles.pricingPlans__each} key={each.id}>
<div className={styles.header}>
<h3>{each.header}</h3>
</div>
<div className={styles.price}>
<h4>£{each.price}/mo.</h4>
</div>
<div className={styles.body}>{each.body}</div>
<div className={styles.cta}>
<button onClick={() => handleSelectPlan(each.id)}>
{selectedPlan === each.id ? <FaCheck /> : null} Select
</button>
</div>
</div>
))}
selectedPlan ?: will only check for any plan, since a strings is truthy and will result in Facheck to be rendered for all.

ReactJS is Giving me unreachable code when I'm passing truthness test

I'm trying to create truthness check in my component to render other components but it is giving me unreachable code error
I dont know how to fix it or where to start
Please help me to solve this issue,
Thanks in advance
return (
checkCommentAuthor() ? (
<IsCommentAuthor/>
) : (
<IsNotCommentAuthor/>
) :
After this everything is unreachable
(
<div id="card" className="card">
<div id="postButtons" className="buttons">
<button onClick={() => history.push("/homepage")}>Home</button>
<button onClick={() => history.push("/profile")}>My Profile</button>
<button onClick={() => LogOut()}>Log Out</button>
</div>
<div className="posts">
<p>
Author :
{grabUsernameFromLocation()}
</p>
<p>
Title :
{grabTitleFromLocation()}
</p>
<p>
Description :
{grabDescriptionFromLocation()}
</p>
<div>
<ul>
{
comments.map((items: any) => {
return (
<p
key={uuidv4()}
>Comment :
{items.comment}
</p>
);
})}
</ul>
</div>
<div className="comments">
<input ref={commentRef} placeholder={'Write Comment'}/>
<button onClick={() => {
addComment(grabIdFromLocation())
}}>Add Comment
</button>
</div>
</div>
</div>
)
)
}

Resources