Reputation: 19
I have created a dropdown box to display remaining number of tickets for selection. I also have a number input field to give the number of ticket. Consider the input field has 5 tickets, and selected 5 in the below dropdown now if I try to change the input to zero it shows error and does not display. Another problem is selection list should not display 0 for selection.
import { useState } from "react";
const Dropdown = () => {
const [numTickets, setNumTickets] = useState(0);
const [selectedValues, setSelectedValues] = useState({
adultNonVeg: 0,
childNonVeg: 0,
adultVeg: 0,
childVeg: 0,
});
function handleChange(event, name) {
const values = event.target.value;
setSelectedValues({ ...selectedValues, [name]: values });
console.log("1", values);
}
return (
<div>
<label>
Number of tickets:
<input
type="number"
value={numTickets}
onChange={(event) => setNumTickets(event.target.value)}
/>
</label>
<br />
<label>
Adult Non-Veg:
<select
value={selectedValues.adultNonVeg}
onChange={(event) => handleChange(event, "adultNonVeg")}
>
{[
...Array(
numTickets -
selectedValues.childNonVeg -
selectedValues.adultVeg -
selectedValues.childVeg +
1
),
].map((it, i) => (
<option key={i} value={i}>
{i}
</option>
))}
</select>
</label>
<br />
<label>
Child Non-Veg:
<select
value={selectedValues.childNonVeg}
onChange={(event) => handleChange(event, "childNonVeg")}
>
{[
...Array(
numTickets -
selectedValues.adultNonVeg -
selectedValues.adultVeg -
selectedValues.childVeg +
1
),
].map((it, i) => (
<option key={i} value={i}>
{i}
</option>
))}
</select>
</label>
<br />
<label>
Adult Veg:
<select
value={selectedValues.adultVeg}
onChange={(event) => handleChange(event, "adultVeg")}
>
{[
...Array(
numTickets -
selectedValues.adultNonVeg -
selectedValues.childNonVeg -
selectedValues.childVeg +
1
),
].map((it, i) => (
<option key={i} value={i}>
{i}
</option>
))}
</select>
</label>
<br />
<label>
Child Veg:
<select
value={selectedValues.childVeg}
onChange={(event) => handleChange(event, "childVeg")}
>
{[
...Array(
numTickets -
selectedValues.adultNonVeg -
selectedValues.childNonVeg -
selectedValues.adultVeg +
1
),
].map((it, i) => (
<option key={i} value={i}>
{i}
</option>
))}
</select>
</label>
</div>
);
};
export default Dropdown;
This is the code I tried what I need is if I change the input to 0 then the error should not occur . zero should not be available for selection. The selection field must start from 1
Upvotes: 0
Views: 171
Reputation: 929
I wanted to make this code as a challenge and was able to do it and fix it
the problem you were having is whenever you reset the value of numTickets by that would make your paramater passed to Array() a -ve number
because you don't reset the tickets chosen from previous state and the state still preserves their old values
so you will have numTickets = 0 but the other tickets will be more than 0 creating a -ve value even if we fixed that by making sure the total number of remaining tickets stays above 0
your tickets will be still of some value from the old state and numTickets = 0 defying the logic so you need to reset the num of tickets along the with the tickets chosen
please check: https://playcode.io/1055067
Upvotes: 0
Reputation: 663
your problem was when u put numTickets on ""
and you try to make addition with that value which is impossible, so what i did is to add a test if it's ""
it will be reset to 0 and problem solved
here is the solution :
import { useState } from "react";
const Dropdown = () => {
const [numTickets, setNumTickets] = useState(0);
const [selectedValues, setSelectedValues] = useState({
adultNonVeg: 0,
childNonVeg: 0,
adultVeg: 0,
childVeg: 0
});
function handleChange(event, name) {
const values = event.target.value;
setSelectedValues({ ...selectedValues, [name]: values });
console.log("1", values);
}
function reset(event, name) {
setNumTickets(0);
setSelectedValues({
adultNonVeg: 0,
childNonVeg: 0,
adultVeg: 0,
childVeg: 0
});
}
console.log("setNumTickets", numTickets);
return (
<div>
<label>
Number of tickets:
<input
type="number"
defaultValue={numTickets}
onChange={(event) =>
event.target.value === ""
? reset()
: setNumTickets(event.target.value)
}
/>
</label>
<br />
<label>
Adult Non-Veg:
<select
value={selectedValues.adultNonVeg}
onChange={(event) => handleChange(event, "adultNonVeg")}
>
{[
...Array(
numTickets -
selectedValues.childNonVeg -
selectedValues.adultVeg -
selectedValues.childVeg +
1
)
].map((it, i) => (
<option key={i} value={i}>
{i}
</option>
))}
</select>
</label>
<br />
<label>
Child Non-Veg:
<select
value={selectedValues.childNonVeg}
onChange={(event) => handleChange(event, "childNonVeg")}
>
{[
...Array(
numTickets -
selectedValues.adultNonVeg -
selectedValues.adultVeg -
selectedValues.childVeg +
1
)
].map((it, i) => (
<option key={i} value={i}>
{i}
</option>
))}
</select>
</label>
<br />
<label>
Adult Veg:
<select
value={selectedValues.adultVeg}
onChange={(event) => handleChange(event, "adultVeg")}
>
{[
...Array(
numTickets -
selectedValues.adultNonVeg -
selectedValues.childNonVeg -
selectedValues.childVeg +
1
)
].map((it, i) => (
<option key={i} value={i}>
{i}
</option>
))}
</select>
</label>
<br />
<label>
Child Veg:
<select
value={selectedValues.childVeg}
onChange={(event) => handleChange(event, "childVeg")}
>
{[
...Array(
numTickets -
selectedValues.adultNonVeg -
selectedValues.childNonVeg -
selectedValues.adultVeg +
1
)
].map((it, i) => (
<option key={i} value={i}>
{i}
</option>
))}
</select>
</label>
</div>
);
};
export default Dropdown;
Upvotes: 2