I am updating an existing card record, which has inputs like cardText, source and ownedBy. ownedBy is an array, it is not editable and I don't want the user to see it. But when I do my Patch I want it to be passed along, in order for the value to be preserved.
A quick fix is to set the style of the input field in the form to "display:none", which is what I am doing in the code presented below. Still, this input field is being rendered, and a user who knows how to inpect source code will see the field. I want to prevent that.
export default function Form() {
const router = useRouter()
const cardId = router.query.id
const submitCard = async event => {
event.preventDefault()
const res = cardId ? await fetch(
'/api/cards/' cardId,
{
body: JSON.stringify({
cardText: event.target.cardText.value,
category: event.target.category.value,
cardUsers: event.target.cardUsers.value,
source: event.target.source.value,
ownedBy: event.target.ownedBy.value.split(","),
}),
headers: {
'Content-Type': 'application/json'
},
method: 'PATCH'
}
) : await fetch(
'/api/cards/insertCard',
{
body: JSON.stringify({
cardText: event.target.cardText.value,
category: event.target.category.value,
cardUsers: event.target.cardUsers.value,
source: event.target.source.value
}),
headers: {
'Content-Type': 'application/json'
},
method: 'POST'
}
)
alert("Card Submitted");
}
const [card, setCard] = useState('');
const fetchCard = async () => {
const res = await fetch('/api/cards/' cardId)
const card = await res.json()
setCard(card);
}
useEffect( () => {
cardId ? fetchCard() : ''
}, [cardId])
return (
<div className={styles.container}>
<Head>
<title>CardX - {cardId ? 'Edit' : 'New Card'}</title>
<meta name="description" content="The place to edit or create cards" />
<link rel="icon" href="/favicon.ico" />
</Head>
<form onSubmit={submitCard}>
<label className={utilStyles.input_label} htmlFor="cardText">Card Text</label>
<div className={utilStyles.input}>
<textarea className={utilStyles.input_field} cols="30" rows="3" id="cardText" name="cardText" type="text" defaultValue={card.cardText} required />
</div>
<label className={utilStyles.input_label} htmlFor="category">What is the card category?</label>
<div className={utilStyles.input}>
<select name="category" id="category-select" value={card.category} >
<option value="">--Please choose an option--</option>
<option value="Q">Quebra-Gelo</option>
<option value="P">Profunda</option>
<option value="D">Divertida</option>
</select>
</div>
<label className={utilStyles.input_label} htmlFor="cardUsers">To whom is this card designed for?</label>
<div className={utilStyles.input}>
<textarea className={utilStyles.input_field} cols="30" rows="3" id="cardUsers" name="cardUsers" type="text" defaultValue={card.cardUsers} />
</div>
<label className={utilStyles.input_label} htmlFor="source">Where have you found inspiration to create this card?</label>
<div className={utilStyles.input}>
<textarea className={utilStyles.input_field} cols="30" rows="3" id="source" name="source" type="text" defaultValue={card.source} />
</div>
<input className={utilStyles.input_field} style={{display:"none"}} id="ownedBy" name="ownedBy" type="text" defaultValue={card.ownedBy} />
<button className={utilStyles.card_button} type="submit">Submit</button>
<br />
<Link href="/">
<a>Back home!</a>
</Link>
</form>
</div>
)
}
This code is part of an open source project, and code can be found at https://github.com/diogocsc/cardx.
A published version can be found at https://cardx.vercel.app
CodePudding user response:
Found a tip at https://stackoverflow.com/a/62681621/1461972 and solved it like this:
export default function Form() {
const router = useRouter()
const cardId = router.query.id
async function submitCard(event, ownedBy) {
event.preventDefault()
const res = cardId ? await fetch(
'/api/cards/' cardId,
{
body: JSON.stringify({
cardText: event.target.cardText.value,
category: event.target.category.value,
cardUsers: event.target.cardUsers.value,
source: event.target.source.value,
ownedBy: ownedBy,
}),
headers: {
'Content-Type': 'application/json'
},
method: 'PATCH'
}
) : await fetch(
'/api/cards/insertCard',
{
body: JSON.stringify({
cardText: event.target.cardText.value,
category: event.target.category.value,
cardUsers: event.target.cardUsers.value,
source: event.target.source.value
}),
headers: {
'Content-Type': 'application/json'
},
method: 'POST'
}
)
alert("Card Submitted")
}
const [card, setCard] = useState('');
const fetchCard = async () => {
const res = await fetch('/api/cards/' cardId)
const card = await res.json()
setCard(card);
}
useEffect( () => {
cardId ? fetchCard() : ''
}, [cardId])
return (
<div className={styles.container}>
<Head>
<title>CardX - {cardId ? 'Edit' : 'New Card'}</title>
<meta name="description" content="The place to edit or create cards" />
<link rel="icon" href="/favicon.ico" />
</Head>
<form onSubmit={(event) => submitCard(event, card.ownedBy)}>
<label className={utilStyles.input_label} htmlFor="cardText">Card Text</label>
<div className={utilStyles.input}>
<textarea className={utilStyles.input_field} cols="30" rows="3" id="cardText" name="cardText" type="text" defaultValue={card.cardText} required />
</div>
<label className={utilStyles.input_label} htmlFor="category">What is the card category?</label>
<div className={utilStyles.input}>
<select name="category" id="category-select" value={card.category} >
<option value="">--Please choose an option--</option>
<option value="Q">Quebra-Gelo</option>
<option value="P">Profunda</option>
<option value="D">Divertida</option>
</select>
</div>
<label className={utilStyles.input_label} htmlFor="cardUsers">To whom is this card designed for?</label>
<div className={utilStyles.input}>
<textarea className={utilStyles.input_field} cols="30" rows="3" id="cardUsers" name="cardUsers" type="text" defaultValue={card.cardUsers} />
</div>
<label className={utilStyles.input_label} htmlFor="source">Where have you found inspiration to create this card?</label>
<div className={utilStyles.input}>
<textarea className={utilStyles.input_field} cols="30" rows="3" id="source" name="source" type="text" defaultValue={card.source} />
</div>
<button className={utilStyles.card_button} type="submit">Submit</button>
<br />
<Link href="/">
<a>Back home!</a>
</Link>
</form>
</div>
)
}