I have this table where I loop through data from the backend. One of the rows contain a form with hidden input fields.
The table displays properly but the input fields are not bound to the form.
This is the SFC for the page:
<template>
<jet-action-section>
<template #title>
Pending Bills
</template>
<template #description>
A list of all pending payments.
</template>
<template #content>
<h3 v-if="pendingBills.length > 0">
Pending Payments.
</h3>
<div v-if="pendingBills.length > 0">
<div >
<table >
<tr >
<th >Payment Description</th>
<th >Amount</th>
<th >Action</th>
</tr>
<tr v-for="(bill, index) in pendingBills" :key="bill.id" >
<td >{{ bill.message }}</td>
<td >₦{{ bill.amount }}</td>
<td :id="bill.id">
<form @submit.prevent="payPerformanceFee(index)">
<input id="amount" type="hidden" v-model="form.amount" />
<input id="goal_id" type="hidden" v-model="form.goal_id" />
<div >
<jet-button : :disabled="form.processing">
Pay Performance Fee
</jet-button>
</div>
</form>
</td>
</tr>
</table>
</div>
</div>
<h3 v-else>
Payments you're yet to pay will show up here.
</h3>
</template>
</jet-action-section>
</template>
<script setup>
import { computed } from 'vue'
import JetActionSection from '@/Jetstream/ActionSection.vue'
import Pagination from '@/Jetstream/Pagination.vue'
import JetButton from '@/Jetstream/Button.vue'
import { useForm , usePage} from '@inertiajs/inertia-vue3'
defineProps({pendingBills: Object})
const bills = computed(() => usePage().props.value.pendingBills)
console.log(bills.value) //this returns all the data from the backend
bills.value.forEach((value, index) => {
const amount = value.amount
const goal_id = value.goal_id
console.log(goal_id) //this gives the expected values
console.log(amount) //this gives the expected values
})
const form = useForm({
amount: bills.value.amount, //this show up as undefined in vue dev tools
goal_id: bills.value.goal_id //this show up as undefined in vue dev tools
})
function payPerformanceFee(index) {
form.post(route('pending.bill'))
}
</script>
When I click on the button, it hits the backend with no data.
What I'm trying to achieve is to map amount and goal_id values to the corresponding inertia form so that the data is sent to the backend when the button is clicked. Obviously only one button can be clicked at a time.
I got stuck at the foreach loop. I don't know how to pass each loop cycle data to the inertia form or if I'm going about this the correct way.
CodePudding user response:
I would suggest not using the <form>
element. This is helpful when you're building forms without a frontend framework, but unless you want a fallback to work without js and using a framework this can get into the way.
Anothe issue I see is that you're using <input id="amount" type="hidden" v-model="form.amount" />
in a loop. id
s are meant to be unique, yet your code would generate multiple, so if you're doing a lookup by id, it will return the first one every time.
But, it looks like the id is not even being called. You're using v-model="form.amount"
and v-model="form.goal_id"
, where form is:
const form = useForm({
amount: bills.value.amount, //this show up as undefined in vue dev tools
goal_id: bills.value.goal_id //this show up as undefined in vue dev tools
})
The form
is shared between every instance in each of the table rows, so the form.amount would be same for each. bill
when you call payPerformanceFee
and pass it the index
, it is unused by the method, so another way it is not behaving as you might want it to.
function payPerformanceFee(index) {
form.post(route('pending.bill'))
}
You may have better luck if you just use the bills.value
with the index
And in the script move the form const definition into the payPerformanceFee
method
function payPerformanceFee(index) {
const form = useForm({
amount: bills.value[index].amount, //this show up as undefined in vue dev tools
goal_id: bills.value[index].goal_id //this show up as undefined in vue dev tools
})
form.post(route('pending.bill'))
}
In the table, because they are hidden anyway, no need to include the <input>
elements.
Note that in this case, it expects the indexes to match (ie 6th row in table needs to match 6th object in bills.value
) which may not be the case if the table can be sorted. If the index cannot be relied upon, you may need to use another id/key either from the data or define in component.