I have, on my edit view of a model, a checkbox list whose elements should be initially checked with the correspondent values chosen at the creation of the instance.
Despite I’ve tried a lot, by consulting a lot of web articles and documentation, I couldn’t achieve that purpose.
I have the edit view coded at the same file than the create view, conditionally rendered, with the first one receiving an instance of the model ‘Alquiler’ (at ‘$alquiler’ variable’) and the ‘$editar’ variable with a boolean value setted on ‘true’ on it. I’m using Alpine to pass some values to the Blade component.
So then, in my main view, I have this code:
‘caracteristicas.blade.php’:
@php
$condiciones = [];
if($editar) {
foreach($alquiler->servicios as $servicioOfrecido) {
foreach($servicios as $servicio) {
if($servicioOfrecido['id'] == $servicio['id']) {
debug_to_console($servicio); //This is an aux function I've defined to log to the browser some PHP data when needed
array_push($condiciones, $servicioOfrecido['id']);
}
}
}
}
else {
$condiciones[] = false;
}
@endphp
...
@if($editar)
<form action="{{ route('partes.caracteristicas',$alquiler)}}" method="POST" id="caracteristicas">
@else
<form action="{{ route('partes.caracteristicas')}}" method="POST" id="caracteristicas">
@endif
@csrf
...
<div x-data='{servicios:@json($servicios),condiciones:@json($condiciones)}' class="w-full">
<ul class="whitespace-normal">
<template x-for="(servicio,indice) in servicios" :key="indice">
<x-check-boton x-bind::id='servicio.identificador' x-bind::texto='servicio.servicio' x-bind::valor='servicio.id' x-bind::condiciones='condiciones'></x-check-boton>
</template>
</ul>
</div>
...
</form>
...
<script>
console.log(@json($servicios));
console.log(@json($condiciones));
</script>
...
My code at the blade component is this one:
‘check-boton.blade.php’:
<li class="inline-block" {{$attributes}} x-data="{
id:'',
texto:'',
valor:'',
condicion:false,
condiciones:[],
init: function() {
this.$nextTick( () => {
this.id = this.$el.attributes[':id'].value;
this.texto = this.$el.attributes[':texto'].value;
this.valor = this.$el.attributes[':valor'].value;
this.condiciones = this.$el.attributes[':condiciones'].value;e
this.condicion = this.condiciones.includes(this.valor);
});
}
}">
<div class="flex" x-init='console.log(condiciones)'>
<input type="checkbox" :id="id" name="servicios[]" :value="valor" class="peer hidden" x-model="condiciones" />
<label :for="id" class="select-none cursor-pointer rounded-full border-[1px] border-gray-400
py-2 px-6 font-light text-gray-800 transition-colors duration-200 ease-in-out
peer-checked:bg-emerald-800 bg-transparent peer-checked:text-gray-50 peer-checked:border-none m-2"
x-text="texto"></label>
</div>
</li>
So then, I’m having this result on the browser, showing here also the ‘console.log’s results defined in the main view for debugging purposes, and also the logging coded at the @php/@endphp section:
The result at the <div class="flex" x-init='console.log(condiciones)'>
is:
Meaning that the array is not properly received at the component.
I’ve tried some other stuff, like doing in the component:
<li class="inline-block" {{$attributes}} x-data="{
id: '',
texto: '',
valor: '',
condiciones: [],
condicion: false,
init: function() {
this.$nextTick(() => {
this.id = this.$el.attributes[':id'].value;
this.texto = this.$el.attributes[':texto'].value;
this.valor = this.$el.attributes[':valor'].value;
this.condiciones = JSON.parse(this.$el.attributes[':condiciones'].value);
this.condicion = this.condiciones.includes(parseInt(this.valor));
});
}
}">
....
</li>
But I’m getting at the console:
Uncaught SyntaxError: Unexpected end of JSON input
at JSON.parse (<anonymous>)
at eval (eval at <anonymous> (app-7a4f3435.js:48:671), <anonymous>:14:31)
at app-7a4f3435.js:48:3704
at Ri (app-7a4f3435.js:48:3761)
at app-7a4f3435.js:48:3666
eval @ VM1105:14
(anonymous) @ app-7a4f3435.js:48
Ri @ app-7a4f3435.js:48
(anonymous) @ app-7a4f3435.js:48
setTimeout (async)
(anonymous) @ app-7a4f3435.js:48
I’ve also tried using ‘condicion’ instead of ‘condiciones’ in the ‘x-model’ like this:
<input type="checkbox" :id="id" name="servicios[]" :value="valor" class="peer hidden" x-model="condicion" />
Any idea of what I’m doing wrong? Any more info needed?
If necessary, I can share the section of the controller with the relevant methods for this issue, an also the content of some ‘Alquiler’ instance, obtained by tinker, as an example.
Thanks a lot!
Leandro
2
Answers
@Pippo Despite your suggested solution should work, I finally could solve this issue like this:
'caracteristecas.blade.php':
'check-boton.blade.php':
Despite the section
Worked for other values, it doesn't update at the needed moment the value of the array 'condiciones[]', resulting in an empty array when I refer to it on 'x-model'
Thanks a lot!
Leandro
One solution can be passing the list of values to the component using the PHP and imploding it:
then in the init() function the values can be extracted by splitting the string:
but, since the child component inherits the parent’s properties, I think a better solution would be to completely remove the condiciones property from the check-boton component, so each child will refer to the parent’s condiciones list:
in the child component:
In any case the x-model must be set on condicion