I have a site about reserves of sports complexes, which have a certain number of associated courts. In the I have a checkbox that are generated automatically according to the number of associated courts that have the complex, a range of dates (2 <input>
) and 2 <select>
with schedules that also correspond to a range. All this designed in Laravel 5.5.40 with PHP.
Before the form data is sent I would like to establish a validation; for now I explain how the site works.
First a sports complex is selected, then the associated courts are selected, then a range of dates is chosen and finally the schedules that it will have are chosen.
As the only validation that I would like to establish, is that according to the chosen fields plus the range of dates chosen, and more schedules, multiple records are generated for each court, that is, for example:
The next sports complex named 'SuperSporting' has 2 associated courts, one for tennis and one for football. For this sports complex, a range of dates was selected from 01-12-2018
to 31-12-2018.
and a range of hours from 08:00 AM until 23:00 PM. At the time of saving I should generate the following in the database.
-
For new registrations, each one will have a definite date that necessarily depends on the range of selected dates, for example:
-
One will have a
2018-12-01
date, another will have2018-12-02
, the next one will have2018-12-03
and so on until the last day chosen from the range of dates. -
Then you should save hour by hour starting from
8:00
and ending in23:00
(For this case).
-
That is; a record will have as initial date, the initial day chosen plus the initial schedule chosen, this will increase from hour to hour for each new record until the end of the day, and once completed will continue with the next day, from hour to hour, until end with the last chosen date in the range.
Finally staying like this:
_We'll change the example a bit, now we have selected a range of dates from 01-12-2018
to 01-12-2018
; the schedule stays desde las 08:00 hasta las 23:00 Hrs,
and the selected field is football, it is the same day; but the following is so that it is understood the way in which the schedules should be generated to me:
'MI TABLA HORARIO'
id|horario_inicio |horario_fin |estado_horario_id|cancha_id
1|2018-12-01 08:00:00|2018-12-01 09:00:00| 1| 2
2|2018-12-01 09:00:00|2018-12-01 10:00:00| 1| 2
3|2018-12-01 10:00:00|2018-12-01 11:00:00| 1| 2
4|2018-12-01 11:00:00|2018-12-01 12:00:00| 1| 2
5|2018-12-01 12:00:00|2018-12-01 13:00:00| 1| 2
6|2018-12-01 13:00:00|2018-12-01 14:00:00| 1| 2
7|2018-12-01 14:00:00|2018-12-01 15:00:00| 1| 2
8|2018-12-01 15:00:00|2018-12-01 16:00:00| 1| 2
9|2018-12-01 16:00:00|2018-12-01 17:00:00| 1| 2
10|2018-12-01 17:00:00|2018-12-01 18:00:00| 1| 2
11|2018-12-01 18:00:00|2018-12-01 19:00:00| 1| 2
12|2018-12-01 19:00:00|2018-12-01 20:00:00| 1| 2
13|2018-12-01 20:00:00|2018-12-01 21:00:00| 1| 2
14|2018-12-01 21:00:00|2018-12-01 22:00:00| 1| 2
15|2018-12-01 22:00:00|2018-12-01 23:00:00| 1| 2
That corresponds to a day, if the range had been for example until December 2, the registration would have continued until the end of the following day.
To understand a little better about the structure of this, if it looks like a flow chart, about how the order should be when generating the new records ; It would be something like the following:
Inicio
-> CANCHA 1 (SELECCIONA)
* RANGO FECHAS (SELECCIONA Y APLICA A TODAS LAS CANCHAS SELECCIONADAS)
# POR DIA
° HORARIOS (SE GENERAN)
-> CANCHA 2 (SELECCIONA)
* RANGO FECHAS
# POR DIA
° HORARIOS
-> CANCHA 3 (SELECCIONA)
* RANGO FECHAS
# POR DIA
° HORARIOS
/*EN CASO DE SER MAYOR O MENOR LA CANTIDAD DE CANCHAS ASOCIADAS y
SELECCIONADAS EL PROCESO CONTINUA HASTA FINALIZAR CON LA ÚLTIMA O LA
ÚNICA CANCHA SELECCIONADA MAS EL RANGO DE FECHAS Y HORARIOS ELEGIDOS*/
-> GUARDAR
FIN
But as I explained at the beginning, it does not generate multiple record keeping in that way. At the time of sending the data does not take the range of date or time, saves them as independent records, but if you take the selected checkbox.
This image explains it in a better way, I selected 2 checkboxes for a sports complex, a range of dates from 01-01-2019 until 05-01-2019 and a range of hours from 08:00 to 23 : 00 Hrs, but as I explained it does not take the range of dates and times.
It should be generated for each checkbox, and each day of the range chosen all the hours from 08:00 to 23:00 Hrs of time in hours 08-09, 09-10, etc.
At the moment this I have in my controller. What generates the new records:
public function store(Request $request){
try {
foreach($request->horario as $id_horario=>$row){
foreach($row['check'] as $check){
$horarios = new HorariosNew();
$horarios->hora_inicio = $row['desde'].' '.$row['sel'];
$horarios->hora_fin = $row['hasta'].' '.$row['sel2'];
$horarios->estado_horario_id = $row['estado_horario_id'];
$horarios->cancha_id = $check;
$horarios->save();
}
}
} catch (\Illuminate\Database\QueryException $e) {
Session::flash('error', 'Hubo un error desconocido, no se pudo registrar el horario');
return redirect()->route('horarios.store');
}
Session::flash('message', 'Se agregó correctamente el horario');
return redirect()->route('horarios.store');
}
And this is the form, this time I'll put it in a snippet just because it's something long.
/*FUNCION QUE VALIDA LA SELECCION DE FECHAS, COMO POR EJEMPLO QUE NO PUEDE SER MENOR
QUE LA ACTUAL, Y QUE NO PUEDE SER MENOR QUE LA PRIMERA FECHA ESCOGIDA*/
function ValidaFecha(e){
var fecha1 = new Date(desde.value);
var fecha2 = new Date(hasta.value);
var hoy = new Date();
var Anio = hoy.getFullYear();
var months = ["Enero","Febrero","Marzo","Abril","Mayo","Junio","Julio","Agosto","Septiembre","Octubre","Noviembre","Diciembre"];
var days = ["Lunes", "Martes", "Miercoles", "Jueves", "Viernes", "Sabado", "Domingo"];
var Mes = months[hoy.getMonth()];
var Dia = days[hoy.getDate()];
var dia_n = hoy.getDate();
/*if(fecha1 <= hoy){
$('#desde').focus();
$.alert({
title: ''+'<nav style=" background: #478573; color:white; width: 20cm; height: 10mm; margin-top: -5mm; margin-left: -5mm; padding-top: 2.5mm;"> <i class="fa fa-warning"></i> ¡Atencion!</nav>',
content: ''+'<p style="color:black;font-weight: 500; text-align: justify !important; font-size: 12pt;" >La fecha de escogida no puede ser menor que la fecha actual.</p><p style="font-size: 10pt; color: black; font-weight: 600; text-align: justify;">Actualmente estamos a: <br> '+Dia+' '+dia_n+' '+'de'+' '+Mes+' '+'del'+' '+Anio+'</p>',
});
return false;
}else */if (fecha2 < fecha1) {
$('#hasta').focus();
$.alert({
title: ''+'<nav style=" background: #478573; color:white; width: 15cm; height: 10mm; margin-top: -5mm; margin-left: -5mm; padding-top: 2.5mm;"> <i class="fa fa-warning"></i> ¡Atencion!</nav>',
content: ''+' <p style= "color: black; font-weight: 500;" >La fecha de termino no puede ser menor que la fecha inicial.</p>',
});
return false;
}
else{
return true;
}
}
/*FUNCION QUE VALIDA QUE SE SELECCIONE AL MENOS UN CHECKBOX*/
$('form').submit(function(e){
// si la cantidad de checkboxes "chequeados" es cero,
// entonces se evita que se envíe el formulario y se
// muestra una alerta al usuario
if ($('input[type=checkbox]:checked').length === 0) {
e.preventDefault();
$('#top_page').focus();
$('#img_warning').fadeIn(1000);
$.alert({
title: ''+'<nav style=" background: #478573; color:white; width: 15cm; height: 10mm; margin-top: -5mm; margin-left: -5mm; padding-top: 2.5mm;"> ¡Atencion!</nav>',
content: ''+' <label style= "color: black; font-weight: 500;" >Debe seleccionar al menos un elemento de la lista.</label>',
});
}
});
function MuestraCanchas(event){ /*OK*/
var target = $(event.target);
var value = target.val();
$('.DivCheckCanchas').hide();
$('.DivCanchas').hide();
$('#img_warning').hide();
$('[data-complejo="'+value+'"]').closest('.DivCanchas').show().css({"margin-bottom":"10px"});
$('[data-complejo="'+value+'"]').closest('.DivCheckCanchas').show().css({"margin-bottom":"10px"});;
}
/*OK*/
function numeros(e){
var tecla = e.keyCode;
if (tecla==8 || tecla==9 || tecla==13){
return true;
}
var patron =/[1-2]/;
var tecla_final = String.fromCharCode(tecla);
return patron.test(tecla_final);
}
@section('content')
<div class="right_col" role="main">
<div class="card">
<div class="card-body">
<h4 class="card-title" style="color: black;">Agregar un nuevo Horario</h4>
<input type="text" id="top_page" readonly="readonly">
<h6 class="card-subtitle" style="color: grey; position: relative; bottom: 7mm;"> Debe rellenar los campos solicitados</h6>
{!! Form::open(['route'=> 'horarios.store','method'=> 'POST' ,'class'=>"form-material m-t-40",'name'=>'horario', 'id'=>'horario_id', 'files' => true] ) !!}
<div style="position: relative; bottom: 1cm;">
<label style="color: black;">Complejos</label>
<br>
<label style="color: grey;">Seleccione un complejo</label>
<br>
<select id="complejos" required="required" onchange="MuestraCanchas(event)">
<option value="">Seleccione...</option>
<option value="{{$complejo->id}}">{{$complejo->nombre}}</option>
</select>
<br><br>
<div class="DivCheckCanchas" id="DivCheckCanchas">
<label style="color: black;" id="label_check">* Seleccione una cancha o campo</label>
<div id="img_warning">
<img src="https://image.flaticon.com/icons/svg/148/148768.svg" class="img_warning" width="30">
</div>
<h6 style="color: grey;"> Tambien puede seleccionar más de una opción.</h6>
<br>
@foreach($campos as $campos)
<div id="DivCanchas" class="DivCanchas" style="width: 22%;">
<input type="checkbox" data-complejo="{{$campos->complejo_id}}" id="{{$campos->nombre}}" value="{{$campos->id}}" name="horario[{{$last_horario->id}}][check][]" >
<label id="LabelCanchas" style="color: grey; margin-left: 2mm;" for="{{$campos->nombre}}">{{$campos->nombre}}</label>
<br>
</div>
@endforeach
</div>
<br>
<label style="color: black;">FECHAS</label>
<br><br>
<div class="input-daterange input-group">
<span class="input-group-addon bg-info b-0 text-white">DESDE</span>
<input type="date" class="form-control" name="horario[{{$last_horario->id}}][desde]" id="desde" required="required" />
<span class="input-group-addon bg-info b-0 text-white">HASTA</span>
<input type="date" class="form-control" name="horario[{{$last_horario->id}}][hasta]" id="hasta" required="required"/>
</div>
<br><br>
<label style="color: black;">HORARIO DE INICIO</label>
<label style="color: black; position: relative; left: 10cm;">HORARIO DE TERMINO</label>
<br>
<label style="color: grey;">Seleccione una hora</label>
<label style="position: relative; left: 94.5mm; color: grey;">Seleccione una hora</label>
<br>
<select name="horario[{{$last_horario->id}}][sel]" id="options1" required="required" class="option">
<option value="">Seleccione</option>
<option value="08:00:00">08:00:00</option>
<option value="09:00:00">09:00:00</option>
<option value="10:00:00">10:00:00</option>
<option value="11:00:00">11:00:00</option>
<option value="12:00:00">12:00:00</option>
<option value="13:00:00">13:00:00</option>
<option value="14:00:00">14:00:00</option>
<option value="15:00:00">15:00:00</option>
<option value="16:00:00">16:00:00</option>
<option value="17:00:00">17:00:00</option>
<option value="18:00:00">18:00:00</option>
<option value="19:00:00">19:00:00</option>
<option value="20:00:00">20:00:00</option>
<option value="21:00:00">21:00:00</option>
<option value="22:00:00">22:00:00</option>
</select>
<select name="horario[{{$last_horario->id}}][sel2]" id="options2" required="required" class="option2">
<option value="">Seleccione</option>
<option value="09:00:00">09:00:00</option>
<option value="10:00:00">10:00:00</option>
<option value="11:00:00">11:00:00</option>
<option value="12:00:00">12:00:00</option>
<option value="13:00:00">13:00:00</option>
<option value="14:00:00">14:00:00</option>
<option value="15:00:00">15:00:00</option>
<option value="16:00:00">16:00:00</option>
<option value="17:00:00">17:00:00</option>
<option value="18:00:00">18:00:00</option>
<option value="19:00:00">19:00:00</option>
<option value="20:00:00">20:00:00</option>
<option value="21:00:00">21:00:00</option>
<option value="22:00:00">22:00:00</option>
<option value="23:00:00">23:00:00</option>
</select>
<br><br><br>
<label style="color: black;">Estado</label>
<br>
<input type="text" value="2" class="form-control form-control-line" style="width: 10%;" onkeypress="return numeros(event)" maxlength="1" required="required" name="horario[{{$last_horario->id}}][estado_horario_id]">
<br><br><br>
<input type="submit" id="btn-success" value="REGISTRAR" onclick="return ValidaFecha(event)">
<a href="{{route('horarios.show', [" id, nombre, direccion, comuna, telefono" => $complejo-> id, 'nombre', 'direccion', 'comuna', 'telefono'])}}"">
<input type="button" id="btn-cancelar" value="CANCELAR">
</a>
<br><br>
</div>
{!! Form::close() !!}
</div>
</div>
</div>
@endsection
I also add a capture of the form, which I designed.
I hope you understand, how can I solve it?