Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Melodia's avatar

How can I save multiple checkbox inputs in a single request

I am doing a small booking system in which a user should capable of selecting the days and times of the week which the rooms are available for viewing. For that, I am using datepicker to capture the "from" and "to" dates, and I also show a list of days from Monday to Sunday.

What I want is to save all the records in a single request, at the moment my form looks like this:

<form method="post" action="{{route('viewing.store')}}">
    @csrf
    
    <div class="flddex">
        <label class="day">Monday</label>
        <input type="hidden" name="property_id" value="{{$property->id}}">
        <input type="checkbox" name="day[]" value="Mon">
        <label>From</label>
        <input type="text" class="timepicker form-cont" name="from[]"></input>
        <label>To</label>
        <input type="text" class="timepicker form-cont" name="to[]"></input>                
    </div>
    <div class="flddex">
        <label class="day">Tuesday</label>
        <input type="hidden" name="property_id" value="{{$property->id}}">
        <input type="checkbox" name="day[]" value="Tue">
        <label>From</label>
        <input type="text" class="timepicker form-cont" name="from[]"></input>
        <label>To</label>
        <input type="text" class="timepicker form-cont" name="to[]"></input>                
    </div>
    <div class="flddex">
        <label class="day">Wednesday</label>
        <input type="hidden" name="property_id" value="{{$property->id}}">
        <input type="checkbox" name="day[]" value="Wed">
        <label>From</label>
        <input type="text" class="timepicker form-cont" name="from[]"></input>
        <label>To</label>
        <input type="text" class="timepicker form-cont" name="to[]"></input>                
    </div>
    <div class="flddex">
        <label class="day">Thursday</label>
        <input type="hidden" name="property_id" value="{{$property->id}}">
        <input type="checkbox" name="day[]" value="Thu">
        <label>From</label>
        <input type="text" class="timepicker form-cont" name="from[]"></input>
        <label>To</label>
        <input type="text" class="timepicker form-cont" name="to[]"></input>                
    </div>
    <div class="flddex">
        <label class="day">Friday</label>
        <input type="hidden" name="property_id" value="{{$property->id}}">
        <input type="checkbox" name="day[]" value="Fri">
        <label>From</label>
        <input type="text" class="timepicker form-cont" name="from[]"></input>
        <label>To</label>
        <input type="text" class="timepicker form-cont" name="to[]"></input>                
    </div>
    <div class="flddex">
        <label class="day">Saturday</label>
        <input type="hidden" name="property_id" value="{{$property->id}}">
        <input type="checkbox" name="day[]" value="Sat">
        <label>From</label>
        <input type="text" class="timepicker form-cont" name="from[]"></input>
        <label>To</label>
        <input type="text" class="timepicker form-cont" name="to[]"></input>                
    </div>
    <div class="flddex">
        <label class="day">Sunday</label>
        <input type="hidden" name="property_id" value="{{$property->id}}">
        <input type="checkbox" name="day[]" value="Sun">
        <label>From</label>
        <input type="text" class="timepicker form-cont" name="from[]"></input>
        <label>To</label>
        <input type="text" class="timepicker form-cont" name="to[]"></input>                
    </div>

    <button type="submit" class="btn1-primary btn1">Add</button>
</form>

If it was on value it would have easy:

public function store(Request $request)
{
    $days = $request->day;
  
    foreach ($days as $day) {
        //then save to table here
    }

But now in this case is different. I want to save the day, from and to at once.

As result, I could have something like:

Viewings: Mon 8am - 3pm | Wed 9am - 12pm

I was trying to use nested foreach but I got really confused.

Hope someone can help

0 likes
12 replies
Cronix's avatar
$days = $request->day;
$froms = $request->from;
$tos = $request->to;

foreach ($days as $key => $day) {
    Thing::create([
        'day' => $day,
        'from' => $froms[$key],
        'to' => $tos[$key],
    ]);
}

Your question also mentions checkboxes, but I don't see anything related to checkboxes here?

Edit: it looks like these are all for the same property, so just do

<form method="post" action="{{route('viewing.store')}}">
    @csrf
    <input type="hidden" name="property_id" value="{{$property->id}}">

and remove all of the other hidden property_id fields. They are not doing anything.

Melodia's avatar

I just tried that:

public function store(Request $request)
{

    $days = $request->days;
    $froms = $request->from;
    $tos = $request->to;

    foreach ($days as $key => $day) {
        Viewingdate::create([
            'property_id' => $request->property_id,
            'day' => $day,
            'from' => $froms[$key],
            'to' => $tos[$key],
        ]);
    }
}

But it gives me an invalid argument error

Invalid argument supplied for foreach()
Cronix's avatar

Ah, the problem is the days are checkboxes. In html forms, checkboxes only get submitted if they are checked, so that's throwing it off.

Cronix's avatar

This will work.

Change your inputs to this:

<div class="flddex">
        <label class="day">Tuesday</label>
        <input type="checkbox" name="day[Tue]" value="Tue">
        <label>From</label>
        <input type="text" class="timepicker form-cont" name="from[Tue]"></input>
        <label>To</label>
        <input type="text" class="timepicker form-cont" name="to[Tue]"></input>
    </div>

Notice the name attributes now use the day name as the array key in the inputs day[Tue], from[Tue] and to[Tue]. So you'd do that to all of the other day sections as well (using the correct day, obviously)

and in the controller

        $days = $request->day;
        $froms = $request->from;
        $tos = $request->to;

        if (count($days)) {
            foreach ($days as $key => $day) {
                Viewingdate::create([
                    'property_id' => $request->property_id,
                    'day' => $day,
                    'from' => $froms[$key],
                    'to' => $tos[$key],
                ]);
            }
        }
Melodia's avatar

So in this case I have to save one row at the time.

I try doing that, but when I return a $request I can only get the day, and not the from and to.

{"_token":"rnKBPQJrJk8K5MlwNIe9tGdVHOQ7MzcWkEci2xmo","property_id":"21","from":null,"to":null,"day":"Thu"}

I replaced

<input type="text" class="timepicker form-cont" name="from[]"></input>

for this:

But it didnt make a difference in the error.

Cronix's avatar

You could save a bit of code as well, since these are all basically the same thing repeated over and over.

In the controller,

$days = [
    'Monday' => 'Mon',
    'Tuesday' => 'Tue',
    // etc
];

Then pass $days to your view in addition to property, and in the view, generate the form.

<form method="post" action="{{route('viewing.store')}}">
    @csrf
    <input type="hidden" name="property_id" value="{{$property->id}}">

    @foreach ($days as $dayName => $dayAbbr)
    <div class="flddex">
        <label class="day">{{ $dayName }}</label>       
        <input type="checkbox" name="day[{{ $dayAbbr }}]" value="{{ $dayAbbr }}">
        <label>From</label>
        <input type="text" class="timepicker form-cont" name="from[{{ $dayAbbr }}]"></input>
        <label>To</label>
        <input type="text" class="timepicker form-cont" name="to[{{ $dayAbbr }}]"></input>                
    </div>
    @endforeach

    <button type="submit" class="btn1-primary btn1">Add</button>
</form>
Cronix's avatar

So in this case I have to save one row at the time.

I try doing that, but when I return a $request I can only get the day, and not the from and to.

Did you do what I said in the post just before you posted that? I tested it, and it works.

<div class="flddex">
        <label class="day">Tuesday</label>
        <input type="checkbox" name="day[Tue]" value="Tue">
        <label>From</label>
        <input type="text" class="timepicker form-cont" name="from[Tue]"></input>
        <label>To</label>
        <input type="text" class="timepicker form-cont" name="to[Tue]"></input>
    </div>

etc. Please reread that post.

Melodia's avatar

Sorry I didnt notice the previous answer. And yes you are right:

<form method="post" action="{{route('viewing.store')}}">
    @csrf
    <input type="hidden" name="property_id" value="{{$property->id}}">

    @foreach ($days as $dayName => $dayAbbr)
    <div class="flddex">
        <label class="day">{{ $dayName }}</label>       
        <input type="checkbox" name="day[{{ $dayAbbr }}]" value="{{ $dayAbbr }}">
        <label>From</label>
        <input type="text" class="timepicker form-cont" name="from[{{ $dayAbbr }}]"></input>
        <label>To</label>
        <input type="text" class="timepicker form-cont" name="to[{{ $dayAbbr }}]"></input>                
    </div>
    @endforeach

    <button type="submit" class="btn1-primary btn1">Add</button>
</form>

In the controller:

    $days = $request->day;
    $froms = $request->from;
    $tos = $request->to;

    if (count($days)) {
        foreach ($days as $key => $day) {
            Viewingdate::create([
                'property_id' => $request->property_id,
                'day' => $day,
                'from' => $froms[$key],
                'to' => $tos[$key],
            ]);
        }
    }

It saves one record at the time. If I try select multiple rows then it gives integrity contraint error:

SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'from_time' cannot be null (SQL: insert into `viewingdates` (`property_id`, `day`, `from_time`, `to_time`, `updated_at`, `created_at`) values (21, Tue, , , 2018-09-26 20:17:26, 2018-09-26 20:17:26))
Cronix's avatar

Well, it looks like you're saving them under different field names than they actually are!

Looks like in the db, the columns are actually named from_time and to_time, but when you're saving them here

            Viewingdate::create([
                'property_id' => $request->property_id,
                'day' => $day,
                'from' => $froms[$key],
                'to' => $tos[$key],
            ]);

you're using from and to. Change those to from_time and to_time

Melodia's avatar

Not really the case and yes I made it a little confusing with the names. but I have it saved as from_time and to_time

if (count($days)) {
    foreach ($days as $key => $day) {
        Viewingdate::create([
            'property_id' => $request->property_id,
            'day' => $day,
            'from_time' => $froms[$key],
            'to_time' => $tos[$key],
        ]);
    }
}

If I choose one day and times it works. But if I try to select many days and times it gives the integrity constraint

Cronix's avatar

Then I suspect something is not working properly with your timepicker script.

If you do dd($request->all()); in the controller method as the first thing, do you see values coming through for the from/to times? If not, something is wrong with your form and they're not being submitted properly in the request. I think we're onto a totally different problem now.

Melodia's avatar

@Cronix I checked the dd and here the results:

array:5 [▼
   "_token" => "t8dE2LYYvoHjOvXIAVB6bGTGWb9rj3LJjWgjPcAx"
   "property_id" => "22"
   "from" => array:6 [▼
   "Mon" => null
   "Tue" => null
   "Wed" => "12:00 AM"
   "Thu" => null
   "Fri" => null
   "Sun" => null
]
"to" => array:6 [▼
"Mon" => null
"Tue" => null
"Wed" => "08:30 AM"
"Thu" => null
"Fri" => null
"Sun" => null
]
"day" => array:2 [▼
"Tue" => "Tue"
"Wed" => "Wed"
]
]

Please or to participate in this conversation.