Every row in my schedules table has start_time
and end_time
.
I can get and map them by using the code below.
My question is how can I deliver an object with moments
as an array of arrays, containing the intervals start_time
, end_time
of every row I get from my schedules
table?
Below is the format I want to achieve, you can see there are two arrays inside of moments
they are the two rows that came from my schedules
table.
{
moments: [
[ { hour: 6, minute: 45 }, { hour: 7, minute: 45 }, ],
[ { hour: 10, minute: 30 }, { hour: 11, minute: 30 }, ]
]
}
Here are my schedules
table and sample records.
---------- ------------------ ---------------- -------------
| id | start_time | end_time | user_id |
---------- ------------------ ---------------- -------------
| 1 | 6:45 | 7:45 | 1 |
| 2 | 10:30 | 11:30 | 1 |
---------- ------------------ ---------------- -------------
Code
$user = User::find(1);
$schedules = Schedule::select('start_time', 'end_time')
->whereBelongsTo($user)
->get();
$collection = $schedules->map(function ($time) {
return [date("g:i", strtotime($time['start_time'])), date("g:i", strtotime($time['end_time']))];
});
$data = $collection->values()->all();
// result
[
[
"6:45",
"7:45",
],
[
"10:30",
"11:30",
],
]
Q: Why do I need that specific format?
A: Because I will use that on the client side's DateTimePicker to disable time intervals - https://getdatepicker.com/4/Options/#disabledtimeintervals
Client side code
Here I will access the formatted response from my backend by passing it inside JSON.stringify()
.
const timeIntervalsData = JSON.stringify( { moments: [
[ { hour: 6, minute: 45 }, { hour: 7, minute: 45 }, ],
[ { hour: 10, minute: 30 }, { hour: 11, minute: 30 }, ]
]
});
let options = {
format: 'hh:mm A',
disabledTimeIntervals: JSON.parse(timeIntervalsData)
.moments
.map( ([start, end]) => [ moment(start), moment(end) ] )
}
$('.datetimepicker').datetimepicker(options)
CodePudding user response:
Providing my own answer to this question from SO, proving our only ally is ourselves.
in my controller method
$user = User::find(1);
$schedules = Schedule::select('start_time', 'end_time')
->whereBelongsTo($user)
->get();
$collection = $schedules->map(function ($time) {
return [
date("H:i", strtotime($time['start_time'])),
date("H:i", strtotime($time['end_time'])),
];
});
return response()->json([
'status' => true,
'time' => $collection->all(),
], 200);
client side
<input type="text" name="time" required>
// From AJAX response.
const time = data.time
// Format the times into moment.js instances.
const timeIntervalsData = time.map(function(schedule) {
return [
moment(schedule[0], 'H:mm'), // Start time
moment(schedule[1], 'H:mm') // End time
]
})
let options = {
format: 'hh:mm A',
disabledTimeIntervals: timeIntervalsData
}
$('.datetimepicker').datetimepicker(options)
Hope this helps anyone with the same problem in the future.
CodePudding user response:
You can map over all the items in the collection and then use something like
$collection = collect($schedules)->map(function ($time) {
// your logic
return [
'hour' => $time->start_time->diff($time->end_time)->format('%H'),
'minute' => $time->start_time->diff($time->end_time)->format('%I'),
],
});
And in your model make sure you cast them to Carbon instances, that makes it easier.