Multiple Checkbox with textbox enable/disable & array - laravel

I have multiple checkbox field and when any checkbox checked then 3 input field appear. I want to insert data for 1 checkbox value with 3 input value.
Form:
<div class="form-check">
<input class="form-check-input fighting_style" name="txt_fightingStyle[]" type="checkbox" value="MMA" id="MMA">
<label class="form-check-label" for="flexCheckDefault">
MMA
</label>
<section class="fighiting_value" id="MMA_input" style="display: none;">
<div class="row">
<div class="col-3">
<div class="mb-3">
<label for="exampleFormControlInput1" class="form-label text-dark">WIN</label>
<input type="text" class="form-control fights txt_win"
name="txt_win[]" onblur="totalFights()" id="txt-win" placeholder="">
</div>
</div>
<div class="col-3">
<div class="mb-3">
<label for="exampleFormControlInput1" class="form-label text-dark">LOSS </label>
<input type="text" class="form-control fights txt_loss" data-points = "75"
name="txt_loss[]" onblur="totalFights()" id="txt-loss" placeholder="">
</div>
</div>
<div class="col-3">
<div class="mb-3">
<label for="exampleFormControlInput1" class="form-label text-dark">DRAW</label>
<input type="text" class="form-control fights txt_draw" data-points = "150"
name="txt_draw[]" onblur="totalFights()" id="txt-draw" placeholder="">
</div>
</div>
</div>
</section>
</div>
Javascript:
document.querySelectorAll("input[type=checkbox]").forEach(cb=>cb.addEventListener("click",ev=>{
let sibl=(cb.closest("label")??cb).nextElementSibling;
while(sibl&&!sibl.matches("section"))
sibl=sibl.nextElementSibling;
sibl.style.display=ev.target.checked?"":"none";
}));
document.querySelectorAll("input[type=text]").forEach(t=>t.addEventListener("blur",ev=>totalFights()));
This is my dd result
"txt_win" => array:12 [▼
0 => null
1 => null
2 => null
3 => "4"
4 => null
5 => "4"
6 => null
7 => null
8 => null
9 => null
10 => null
11 => null
]
"txt_loss" => array:12 [▼
0 => null
1 => null
2 => null
3 => "5"
4 => null
5 => "5"
6 => null
7 => null
8 => null
9 => null
10 => null
11 => null
]
"txt_draw" => array:12 [▼
0 => null
1 => null
2 => null
3 => "6"
4 => null
5 => "6"
6 => null
7 => null
8 => null
9 => null
10 => null
11 => null
]
my controller:
$dataWin = $request->txt_win;
$dataLoss = $request->txt_loss;
$dataDraw = $request->txt_draw;
foreach ($dataFightingStyle as $fightStyle) {
FighitData::create([
'fighting_style' => $fightStyle,
'winning_game' =>$dataWin,
'lost_game' => $dataLoss,
'draw_game' => $dataDraw,
]);
}
I just want to which checkbox box checked only when the check box is selected only the data of its text field can be taken and the rest will be disabled. Is there any way to do this.

I i understood your problem correctly, you need to get text fields related to checkboxes. In this case you could try something like that :
$dataWin = $request->txt_win;
$dataLoss = $request->txt_loss;
$dataDraw = $request->txt_draw;
foreach ($dataFightingStyle as $key => $fightStyle) {
FighitData::create([
'winning_game' =>$dataWin[$key],
'lost_game' => $dataLoss[$key],
'draw_game' => $dataDraw[$key],
]);
}

Related

Livewire quantity input field not update dynamically when change value

I've purchased pos software which is not updated the quantity input field when changed into the checkout page it's working with a button. I want to change form submit button quantity input to dynamic input field with cart total, not with a hard-coded button.
Screenshot of this problem
Blade Code
<form wire:submit.prevent="updateQuantity('{{ $cart_item->rowId }}', '{{ $cart_item->id }}')">
<div class="input-group">
<input wire:model.lazy="quantity.{{ $cart_item->id }}" style="min-width: 40px;max-width: 90px;" type="number" class="form-control" value="{{ $cart_item->qty }}" min="1">
<div class="input-group-append">
<button type="submit" class="btn btn-primary">
<i class="bi bi-check"></i>
</button>
</div>
</div>
Update function
public function updateQuantity($row_id, $product_id) {
if ($this->check_quantity[$product_id] < $this->quantity[$product_id]) {
session()->flash('message', 'The requested quantity is not available in stock.');
return;
}
Cart::instance($this->cart_instance)->update($row_id, $this->quantity[$product_id]);
$cart_item = Cart::instance($this->cart_instance)->get($row_id);
Cart::instance($this->cart_instance)->update($row_id, [
'options' => [
'sub_total' => $cart_item->price * $cart_item->qty,
'code' => $cart_item->options->code,
'stock' => $cart_item->options->stock,
'unit' => $cart_item->options->unit,
'product_tax' => $cart_item->options->product_tax,
'unit_price' => $cart_item->options->unit_price,
'product_discount' => $cart_item->options->product_discount,
'product_discount_type' => $cart_item->options->product_discount_type,
]
]);
}

How to update a table record using laravel inertia and vue.js

I use Laravel 8 inertia and vue
I want to update a post and I use this component in a main vue
<template>
<div class="container p-3 bg-green-600 flex flex-col">
<div class="mb-8 text-2xl">{{ current_post.title }}</div>
<div v-if="!edit" id="mode-display">
<div v-html="compiledMarkdown" class="text-gray-700"></div>
</div>
<div v-else id="mode-edit">
<form class="flex flex-col" #submit.prevent="updatePost">
<input type="hidden" name="id" id="id" v-model="current_post.id">
<button type="submit">Mettre à jour</button>
<div class="flex">
<div class="m-5 flex flex-col">
<label for="category">Catégorie du post</label>
<select class="px-2" name="category" id="category" v-model="current_post.category">
<option value="undefined">Sans</option>
<option value="Announcements">Annonce</option>
<option value="Narratives">Récit</option>
<option value="Pages">Page</option>
</select>
</div>
<div class="m-5 flex flex-col">
<label for="diaporama_dir">Dossier du diaporama</label>
<input name="diaporama_dir" id="diaporama_dir" type="text" placeholder="admin|1/Noël2019" v-model="current_post.diaporama_dir">
</div>
</div>
<div class="flex">
<div class="m-5">
<label for="beg_date">Date de début de l'événement</label>
<date-picker name="beg_date" format="YYYY-MM-DD" valueType="format" v-model="current_post.beg_date"></date-picker>
</div>
<div class="m-5">
<label for="end_date">Date de fin de l'événement</label>
<date-picker name="end_date" format="YYYY-MM-DD" valueType="format" v-model="current_post.end_date"></date-picker>
</div>
<div class="m-5">
<label for="close_date">Date de clôture des inscriptions</label>
<date-picker name="close_date" format="YYYY-MM-DD" valueType="format" v-model="current_post.close_date"></date-picker>
</div>
<div class="m-5 flex flex-col">
<label for="receive_registration">Accepte des inscriptions</label>
<select class="px-2" name="receive_registration" id="receive_registration" v-model="current_post.receive_registration">
<option value="false">Non</option>
<option value="true">Oui</option>
</select>
</div>
</div>
<input class="p-5 mb-5 text-xl" type="text" v-model="current_post.title" />
<div class="m-5 flex flex-col">
<label for="abstract">Résumé</label>
<textarea class="markdown bg-green-500 text-gray-100" name="abstract" id="abstract" v-model="current_post.abstract" rows="3"></textarea>
</div>
<div class="m-5 flex flex-col">
<label for="body">Résumé</label>
<textarea class="markdown bg-green-500 text-gray-100" name="body" id="body" v-model="current_post.body" rows="50"></textarea>
</div>
</form>
</div>
</div>
</template>
<script>
import DatePicker from 'vue2-datepicker';
import 'vue2-datepicker/index.css';
import 'vue2-datepicker/locale/fr';
import marked from 'marked';
export default {
name: "PostDetails",
props: ["current_post", "edit"],
components: {
DatePicker
},
data() {
return {
form:{
id:null,
title: null,
abstract: null,
body: null,
category: null,
beg_date: null,
end_date: null,
close_date : null,
receive_registration : null,
diaporama_dir: null
}
};
},
methods:{
updatePost(){
this.$inertia.post('/post', this.form);
}
},
computed: {
compiledMarkdown: function () {
if (this.current_post) {
//transform markdown to html
return marked(this.current_post.body);
}
},
mounted() {},
}
};
</script>
When displaying this template with the form , I receive a correct post and its values are correctly displayed in the various input fields.
My controller, at the moment is very simple :
public function Update(Request $request)
{
dd($request);
}
On submitting this form the dd outputs this:
Illuminate\Http\Request {#43 ▼
#json: Symfony\Component\HttpFoundation\ParameterBag {#35 ▶}
#convertedFiles: null
#userResolver: Closure($guard = null) {#342 ▶}
#routeResolver: Closure() {#351 ▶}
+attributes: Symfony\Component\HttpFoundation\ParameterBag {#45 ▶}
+request: Symfony\Component\HttpFoundation\ParameterBag {#35 ▼
#parameters: array:10 [▼
"id" => null
"title" => null
"abstract" => null
"body" => null
"category" => null
"beg_date" => null
"end_date" => null
"close_date" => null
"receive_registration" => null
"diaporama_dir" => null
]
}
+query: Symfony\Component\HttpFoundation\InputBag {#51 ▶}
+server: Symfony\Component\HttpFoundation\ServerBag {#47 ▶}
+files: Symfony\Component\HttpFoundation\FileBag {#48 ▶}
+cookies: Symfony\Component\HttpFoundation\InputBag {#46 ▶}
+headers: Symfony\Component\HttpFoundation\HeaderBag {#49 ▶}
#content: "{"id":null,"title":null,"abstract":null,"body":null,"category":null,"beg_date":null,"end_date":null,"close_date":null,"receive_registration":null,"diaporama_dir ▶"
#languages: null
#charsets: null
#encodings: null
#acceptableContentTypes: null
#pathInfo: "/post"
#requestUri: "/post"
#baseUrl: ""
#basePath: null
#method: "POST"
#format: null
#session: Illuminate\Session\Store {#392 ▶}
#locale: null
#defaultLocale: "en"
-preferredFormat: null
-isHostValid: true
-isForwardedValid: true
-isSafeContentPreferred: null
basePath: ""
format: "html"
}
It seems to me I am obeying the guidance given in this page https://inertiajs.com/forms but why on earth the form's value are not uploaded to the server?
In your code, you're sending the form object (which is full of null values).
For now, you can fix it like this:
updatePost () {
this.$inertia.post('/post', this.current_post);
}
But probably you're having a vue-warn saying that it's not recommended to edit a prop.
so I suggest also the following:
you receive the post prop as current_post
you should copy it to your form object (on mounted)
link all of your form inputs to the form object instead of current_post
I can not add a comment yet but wanted to add that if You clone a reactive object You are not actually copying it. The cloned object is the same as the original and modifying this new object modifies the original object too and vice versa so basically You are doing exactly the same thing that got You in trouble at the first place: Modifying properties.
Vue states that You should not modify a property because if a parent component modifies a prop your changes are gone.
Lodash clonedeep creates a new object from the property:
this.items = _.cloneDeep(this.data);

How to define an onclick function on Laravel Collectives?

I have implemented a drop down using Laravel collectives. I need to call function setMaterialValue(let x){ console.log(x)} on each time I select a material. This should be specific to each material as cotton-10, wetlook-20, crocodile-30 etc. Without Laravel collective this can be performed as
<option onclick="setMaterialValue(10);">Cotton</option>
How to perform this using Laravel collectives?
My code is as follows:
<div class="card">
<div class="card-header"><h2 class="card-title m-0">Feature Selector</h2></div>
<div class="card-body">
<h5 class="card-title"><b>Material Selector</b></h5>
<div class="row">
<div class="col-md-6">
Textile Material
</div>
<div class="col-md-6">
{{Form::select('material_selector', [
'10' => 'Cotton',
'20' => 'Wet Look',
'30' => 'Crocodile',
], null, ['placeholder' => 'Select Material'],['class'=>'form-control'])
}}
</div>
</div>
<hr>
</div>
</div>
FYI - Where your class declaration is add it and any other html attributes there as well:
{{ Form::select('material_selector',
[
'1' => 'Cotton',
'2' => 'Wet Look',
'3' => 'Crocodile',
],
null,
['placeholder' => 'Select Material'],
[
'class'=>'form-control',
'onclick'=>'setMaterialValue(10)' // <== ADD IT HERE
])
}}
You should probably use jQuery. Then you can address your select element as follows
$(document).ready(function() {
$('.form-control[name="material_selector"]').on('change', showSelectedValue);
function showSelectedValue(event) {
var target = $(event.target);
console.log(target.val() + " = " + target.find('option:selected').text());
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select name="material_selector" class="form-control">
<option value="10">Cotton</option>
<option value="20">Wet Look</option>
<option value="30">Crocodile</option>
</select>
Another option
If you really do not want to use jQuery, then try to use the onChange attribute for the select tag like the example below
{{Form::select(
'material_selector', // name attribute of the select
['10' => 'Cotton', '20' => 'Wet Look', '30' => 'Crocodile'], // option values
null, // selected value, for example '20'
['placeholder' => 'Select Material', 'class' => 'form-control', 'onChange' => 'showSelectedValue(this)'], // attributes for <select>
)}}
function showSelectedValue(element) {
console.log(element.value + " = " + element.options[element.selectedIndex].text);
}
<select name="material_selector" class="form-control" onChange="showSelectedValue(this)">
<option value="10">Cotton</option>
<option value="20">Wet Look</option>
<option value="30">Crocodile</option>
</select>

Input array inside json by ajax not working properly in laravel

I'm using Semantic UI and Laravel 6
I got this html code:
<div class="field">
<label for="realTime">Tiempo real</label>
<input type="text" id="realTime" name="schedules[{{ $service->id_service }}][realTime]" required/>
</div>
<div class="field">
<label for="delayTime">Tiempo de demora</label>
<input type="text" id="delayTime" name="schedules[{{ $service->id_service }}][delayTime]" required/>
</div>
<div class="field">
<label for="deathTime">Tiempo muerto</label>
<input type="text" id="deathTime" name="schedules[{{ $service->id_service }}][deathTime]" required/>
</div>
And I'm sending this info by ajax using this code:
$.ajax({
url: "...",
data: {
"formData": $(formClass).form('get values')
},
success: function (response) {
// skipped code
}
});
But when I dump the request data in controller using:
dd($request->input('formData'));
I got this result:
array:1 [
"formData" => array:1 [
"schedules[1" => array:3 [
"realTime" => "12:00:00"
"delayTime" => "13:00:00"
"deathTime" => "14:00:00"
]
]
]
Instead of:
array:1 [
"formData" => array:1 [
"schedules" => array:1 [
1 => array:3 [
"realTime" => "12:00:00"
"delayTime" => "13:00:00"
"deathTime" => "14:00:00"
]
]
]
]
I checked out the content sent shown in Headers tab (using Chrome) and I found this:
formData[schedules[1][realTime]]: 12:00:00
formData[schedules[1][delayTime]]: 13:00:00
formData[schedules[1][deathTime]]: 14:00:00
I also realized that if I put the name as "schedules][{{ $service->id_service }}][realTime]" (putting an extra closing bracket after "schedules"), the dump shows the array correctly.
Any solution?

SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'score' cannot be null

Controller
public function getScore(Request $request, $id)
{
// $scores = Criteria::find($id);
$contestants = Contestant::find($id);
foreach ($request->criteria as $id => $criteria){
$criteriaModel = Score::find($id);
$scores = new Score();
$scores->judge_name = $request->input('judge_name');
$scores->contestant = $contestants->name;
$scores->criteria = $criteriaModel->criteria;
$scores->score = $scores->score;
$scores->save();
}
return redirect('/tabulation')->with('status', 'Score saved!');
}
Blade
#foreach ($criterias as $criteria)
<div class="form-group col-md-6">
<label for="{{$criteria->name}}">{{$criteria->name}} </br> (0 - {{$criteria->points}})</label>
<input type="text" name="criteria[{{$criteria->id}}][criteria]" value="{{$criteria->name}}" hidden>
<input type="text" name="score[{{$criteria->id}}][score]" class="form-control" placeholder="Input score" required>
</div>
#endforeach
Form field names can contain brackets to store multiple properties for a single name:
#foreach ($criterias as $criteria)
<div class="form-group col-md-6">
<label for="{{$criteria->name}}">{{$criteria->name}} </br> (0 - {{$criteria->points}})</label>
<input type="text" name="criterias[{{$criteria->id}}][name]" value="{{$criteria->name}}" hidden>
<input type="text" name="criterias[{{$criteria->id}}][points]" class="form-control" placeholder="Input score" max="{{$criteria->points}}" name="score" required>
</div>
#endforeach
The above form would result the $request->criterias variable containing the following value:
array:2 [▼
1 => array:2 [▼
"name" => "test"
"points" => "dd"
]
2 => array:2 [▼
"name" => "tes22t"
"points" => "sdsd"
]
]
This value can be used in the controller for creating multiple scores:
foreach ($request->criterias as $id => $criteria){
$criteriaModel = Criteria::find($id);
$scores = new Score();
$scores->judge_name = $request->input('judge_name');
$scores->contestant = $contestants->name;
$scores->criteria = $criteriaModel->name;
$scores->score = $criteria->points;
$scores->save();
}
First of all you have to change the name of your input to be an array like so:
<input type="text" name="criteria[]" value="{{$criterias->name}}" hidden>
and in your controller you have to loop through the inputs:
foreach ($request->input('criteria') as $criteria){
$scores = new Score();
$scores->judge_name = $request->input('judge_name');
$scores->contestant = $contestants->name;
$scores->criteria = $request->input('criteria');
$scores->score = $request->input('score');
$scores->save();
}

Resources