'Passing price of <select> to database - Laravel
I need to pass the data of the price to the database. But I have no idea how to do that without hidden inputs.
the ticket select:
<select name="ticket[{{$ticket->id}}]" class="p-2 bg-gray-100 rounded-lg" data-name="{{ $ticket->title }}" data-id="{{ $ticket->id }}" data-price="{{ $ticket->price }}" size="1" x-model="ticket" x-on:change="$store.tickets.add_ticket({{ $ticket->id }}, ticket)" @if ($event->bookable == '1') disabled @endif>
<option value="0">0</option>
@for ($i = $ticket->min; $i <= $ticket->max; $i++)
<option value="{{ $i }}">{{ $i }}</option>
@endfor
</select>
Input Form:
<input class="hidden" type="hidden" name="event_id" value="{{$event->id}}">
<input type="text" class="block w-full px-4 py-5 leading-tight text-gray-700 rounded-lg appearance-none bg-hartung-gray focus:ring focus:ring-primary/10 focus:outline-none" placeholder="Vorname*" name="firstname" pattern="[a-zA-ZÀ-ÖØ-öø-ÿ. -]+" required>
@if ($errors->has('firstname'))
<div class="font-normal text-red-700">
<p>Bitte geben Sie einen Vornamen ein.</p>
</div>
@endif
<input type="text" class="block w-full px-4 py-5 leading-tight text-gray-700 rounded-lg appearance-none bg-hartung-gray focus:ring focus:ring-primary/10 focus:outline-none" placeholder="Nachname*" name="lastname" pattern="[a-zA-ZÀ-ÖØ-öø-ÿ. -]+" required>
@if ($errors->has('lastname'))
<div class="font-normal text-red-700">
<p>Bitte geben Sie eine Nachnamen ein.</p>
</div>
@endif
<input type="email" class="block w-full px-4 py-5 leading-tight text-gray-700 rounded-lg appearance-none bg-hartung-gray focus:ring focus:ring-primary/10 focus:outline-none" placeholder="E-Mail*" name="email" required>
@if ($errors->has('email'))
<div class="font-normal text-red-700">
<p>Bitte geben Sie eine E-Mail ein.</p>
</div>
@endif
<input type="tel" class="block w-full px-4 py-5 leading-tight text-gray-700 rounded-lg appearance-none bg-hartung-gray focus:ring focus:ring-primary/10 focus:outline-none" placeholder="Telefonnummer*" name="phone" pattern="[0-9 (.)+]{3,15}" required>
@if ($errors->has('phone'))
<div class="font-normal text-red-700">
<p>Bitte geben Sie einen Telefonnummer ein.</p>
</div>
@endif
Controller:
<?php
namespace App\Http\Controllers;
use App\Mail\CheckoutConfirmation;
use App\Mail\CheckoutInformation;
use App\Models\Checkout;
use App\Models\Events;
use App\Models\OrderedTickets;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;
class EventsCheckoutController extends Controller
{
public function getCheckout($slug)
{
// get the course data from the database
$event = Events::query()
->where('url', '=', $slug)
->first();
// pass the data to the correct view
return view('pages.checkout.checkout', [
"event" => $event
]);
}
// Store Contact Form data
public function placeOrder(Request $request) {
// Form validation
$this->validate($request, [
'firstname' => 'required',
'lastname' => 'required',
'email' => 'required|email',
'phone' => 'required',
'dancepartner' => ''
]);
// Store data in database
$checkout = new Checkout();
$checkout->event_id = $request->event_id;
$checkout->quantity = array_sum($request->ticket);
$checkout->firstname = $request->firstname;
$checkout->lastname = $request->lastname;
$checkout->email = $request->email;
$checkout->phone = $request->phone;
$checkout->save();
// set the UUID
$uuid = $checkout->id;
foreach ($request->get('ticket') as $id => $quantity)
{
if ($quantity > 0) {
$ordered_ticket = new OrderedTickets();
$ordered_ticket->checkout_id = $uuid;
$ordered_ticket->ticket_id = $id;
$ordered_ticket->quantity = $quantity;
$ordered_ticket->amount = 100;
$ordered_ticket->save();
}
}
// send confirmation email to customer
Mail::to($request->email)->send(new CheckoutConfirmation($checkout));
// send confirmation email to company
Mail::to($request->email)->send(new CheckoutInformation($request));
// redirect to confirmation page with UUID
return redirect()->to('/checkout/confirmation/'. $uuid);
}
}
How it works:
There are events, each of them can have multiple tickets.They each have a different id. $ticket->id
They can also have different prices $ticket->price
What I need to do is pass the price of the selected tickets into the database. You can see that the $ordered_ticket->amount = 100;
is currently hardcoded.
So a user selects a ticket: Example Ticket 1 - 200€ (amount: 3) Example Ticket 2 - 100€ (amount: 2)
the Ticket 1 needs to have 600€ and the Ticket 2 needs to have 200€ saved to the database. Then the total pricing of all tickets would need to be saved onto the database like this:
array_sum($request->price); // example
Solution 1:[1]
So I found this How to pass data-id and data-value from select option to laravel controller?
Based on this SO posting I changed my controller to the following:
// Store data in database
$checkout = new Checkout();
$checkout->event_id = $request->event_id;
$checkout->quantity = array_sum($request->ticket);
$checkout->firstname = $request->firstname;
$checkout->lastname = $request->lastname;
$checkout->email = $request->email;
$checkout->phone = $request->phone;
foreach ($request->get('ticket') as $id => $quantity) {
if ($quantity > 0) {
$ticketInfo = explode('-', $quantity);
$total[] = $ticketInfo[0] * $ticketInfo[1];
}
}
$checkout->total = array_sum($total);
$checkout->save();
// set the UUID
$uuid = $checkout->id;
foreach ($request->get('ticket') as $id => $quantity)
{
$ticketInfo = explode('-', $quantity);
// [0] = quantity [1] = amount
if ($quantity > 0) {
$ordered_ticket = new OrderedTickets();
$ordered_ticket->checkout_id = $uuid;
$ordered_ticket->ticket_id = $id;
$ordered_ticket->quantity = $ticketInfo[0];
$ordered_ticket->amount = $ticketInfo[0] * $ticketInfo[1];
$ordered_ticket->save();
}
}
and the <select>
to this:
<select name="ticket[{{$ticket->id}}]" class="p-2 bg-gray-100 rounded-lg" data-name="{{ $ticket->title }}" data-id="{{ $ticket->id }}" data-price="{{ $ticket->price }}" size="1" x-model="ticket" x-on:change="$store.tickets.add_ticket({{ $ticket->id }}, ticket)" @if ($event->bookable == '1') disabled @endif>
<option value="0">0</option>
@for ($i = $ticket->min; $i <= $ticket->max; $i++)
<option value="{{ $i }}-{{$ticket->price}}">{{ $i }}</option>
@endfor
</select>
TLDR:
Passing the data inside the value=""
of the <option>
gives the option to pass multiple values, if seperated with an -
.
UPDATE:
It is very important that if it is done this way it is needed to verify the validity of the data that gets passed. The better way would be to use the name="ticket[{{$ticket->id}}]"
.
And do something like this:
foreach ($request->get('ticket') as $id => $quantity)
{
if ($quantity > 0) {
$ticket = DB::table('tickets')
->where('id', '=', $id)
->first();
$ordered_ticket = new OrderedTickets();
$ordered_ticket->checkout_id = $uuid;
$ordered_ticket->ticket_id = $id;
$ordered_ticket->quantity = $quantity;
$ordered_ticket->amount = $ticket->price * $quantity;
$ordered_ticket->save();
}
}
this way the verification of the data would be much easier!
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |