How to validate, that there is at least one checkbox checked? - laravel

I have a form for creating a question with multiple(as many as one wishes) possible answers. Here is the picture:
The code for a single possible answer:
<div class="input-group">
{{-- Checkbox for the answer --}}
<span class="input-group-addon">
<input type="checkbox" name="answer[0][is_correct]" value="1">
</span>
{{-- Input field for the answer --}}
<input type="text" class="form-control" name="answer[0][body]">
{{-- . . . --}}
</div>
I need to validate that, there exist at least three answers for a question and at least one of them is correct. How can I achieve this?

I would consider separating your answer text fields from your answer checkboxes for the sake of clarity.
Below hasn't been tested - but something like the following should hopefully help you along?
$numAnswers = count($input->only('answers_text'));
$rules = [
'answers_checked' => 'array|min:1|max:' . $numAnswers,
'answers_text' => 'array|min:3|required',
'answers_text.*' => 'required|string',
];
$v = Validator::make($input, $rules);
if ($v->fails()) {
return response()->json($v->errors(), 422);
}
...

Related

image does not want to be updated if the other values are not changed

I want to update the user image but the user image will only be updated if other values are also updated, such as name/username, I have tried various ways, even though in the edit post section there is no problem
so this is my form
<form action="/profile/{{ auth()->user()->id }}" method="post" enctype="multipart/form-data">
#method('put')
#csrf
<label for="">Name</label>
<input type="text" name="name" value="{{ auth()->user()->name }}">
<label for="">Username</label>
<input type="text" name="username" value="{{ auth()->user()->username }}">
<label for="">Profile Picture</label>
<input type="file" name="image">
<button type="submit">Update</button>
</form>
my web route
Route::get('/profile/{user}/edit', [ProfileController::class, 'edit'])->middleware('auth');
my ProfileController
$rules = [
'name' => ['required', 'max:15'],
'username' => ['required', 'min:5', 'max:12', 'unique:users'],
'image' => ['nullable','image','file','max:1024'],
];
$validatedData = $request->validate($rules);
if($request->file('image')) {
if($user->image){
Storage::delete($user->image);
}
$validatedData['image'] = $request->file('image')->store('profile-images');
}
$user->update($validatedData);
return back();
I have tried several ways and I have also created an edit post feature and it works well, I tried to copy and paste the code and change a little from the edit post feature but it doesn't work, the image is only updated if the other values are also edited / updated, what I want is that the image is updated even if the others are not updated, thank you
It seems to be due to the browser cache history.
Browsers usually store image data in cache. So if the image name is the same it won't be updated.
So I solved this problem like this.
All image names contain a unique random string with extension + ?
ex:Lynn.jpg?33f3r3

Save array [ ] of form data in same columns individual row - Laravel

when the user click add more and submit their form data, I'm having a problem saving form array like this (service[], Amount[], Description[]) in database rows. I have two related tables of invoices and invoice_details, i want the form array to submit the list of form data into the invoice_details table. I have successfully created the models and relations between the invoice and invoice_details.
<!--Blade -->
<div class="service-box">
<div class="row">
<div class="col-md-12 service-group">
<div class="row">
<div class="form-group mb-3 col-md-6">
<label class="form-label">Service</label>
<div >
<select type="text" class="form-select" placeholder="Services" value="" name="service[]" id="service">
<option value="" disabled selected>Select your option</option>
#foreach ($services as $service)
<option value="{{$service->service_name}}" data-id="{{$service->amount}}">{{$service->service_name}}</option>
#endforeach
</select>
</div>
</div>
<div class="form-group mb-3 col-md-6">
<label class="form-label">Amount</label>
<div >
<input type="text" class="form-control" name="amount[]" id="amount" placeholder="Amount" readonly>
</div>
</div>
<div class="form-group mb-3 col-md-12">
<label class="form-label">Description</label>
<textarea class="form-control" id="description" name="description[]" rows="6" placeholder="Description.." ></textarea>
</div>
</div>
</div>
</div>
</div>
//Controller
$invoicedetailModel = new Invoice_detail;
//Here is where the problem lies, I have to save for arrays.
$invoicedetailModel->service = request('service');
$invoicedetailModel->amount = request('amount');
$invoicedetailModel->description = request('description');
$invoiceModel->Invoice_details()->save($invoicedetailModel);
It seems to me (correct me if I'm misinterpreting) that you're trying to save a batch of different InvoiceDetails and attach them to an original Invoice model.
The problem here is that you're trying to do so by passing arrays to a single invoiceDetails model so let's suppose you have the you have two detail instances passed by form you would have the request parameters structured like this:
$request->service: ['serviceX','serviceY']
$request->amount: [1,2]
$request->description: ['Lorem', 'Ipsum']
So if you tried to create the model you're trying to save in your code you would be doing something like this:
Invoice_Details::create([
'service' => ['serviceX', 'serviceY'],
'amount' => [1,2]
'description' => ['Lorem', 'Ipsum']
]);
Which can not work because those values are not set as Json to the database, and also explains why the createMany is not working, because there's a single object that uses an array of values for each value. What you might want is a situation like this:
Invoice_Details::createMany([
[
'service' => 'serviceX',
'amount' => 1
'description' => 'Lorem'
],
[
'service' => 'serviceY',
'amount' => 2
'description' => 'Ipsum'
]
]);
So you should iterate the request parameters and save a whole array of single models rather than try to stuff everything into a single one.
Also, it's pretty legitimate to ask yourself "Sure, but they all have two parameters, why doesn't it just split them when I use the createMany method?" Well, let's suppose the same situation with different parameters:
$request->service: ['serviceX','serviceY']
$request->amount: [1,2]
$request->description: ['Ipsum']
To which model does that description belong to? We could just go by appearence order, but this kind of assumption might lead to huge problems in case of bad implementations. This sadly means that everytime we need to create multiple models we need to define every single one, even though it means adding an iteration beforehand.
TL;DR: Instead of an array of parameters you need an array of models. Iterate through your parameters and build your models before saving them.
//Supposing you already fetched the arrays and they are all of the same length
$details = [];
foreach($services as $key => $service) {
$invoicedetailModel = new Invoice_detail();
$invoicedetailModel->service = $services[$key];
$invoicedetailModel->amount = $amounts[$key];
$invoicedetailModel->description = $descriptions[$key]);
$details[] = $invoicedetailModel;
}
// code to create and attach the many models

Validation on checkbox where one one checkbox must be checked in laravel

I have the following Checkboxes now a want put validation in checkbox that one checkbox must be checked . But i dont't know how to do that.
CheckBox
<div class="form-group clearfix">
<label for="" class="col-sm-2 col-form-label">Arch (es) </label>
<div class="col-sm-10">
<label class="control-label" for="inputError" style="color: red"><i
id="arch_upper_error"></i></label>
<div class="demo-checkbox">
<input id="md_checkbox_1" name="arch_upper" value="41" class="chk-col-black"
type="checkbox">
<label for="md_checkbox_1">Upper</label>
<input id="md_checkbox_2" name="arch_lower" value="41" class="chk-col-black"
type="checkbox">
<label for="md_checkbox_2">Lower</label>
</div>
</div>
</div>
I tried this in laravel validation but i know its wrong because it required for both but i want at least one checkbox is checked.
public function rules()
{
return [
'arch_lower' => 'required',
'agarch_upper' => 'required',
,
];
}
I think you could use Laravel's required-without method:
The field under validation must be present and not empty only when any
of the other specified fields are not present.
Implementation would look something like this:
'arch_upper' => 'required_without: arch_lower',
If, by any chance, you have more checkboxes, you could use required-without-all:
The field under validation must be present and not empty only when all
of the other specified fields are not present.
Implementation:
'arch_upper' => 'required_without_all: arch_lower,another_checkbox',
Note: Code is not tested, if you encounter any errors, let me know.
You can read more on Laravel's official documentantion.

Why validation two checkbox in one form not working on laravel?

My view blade like this :
...
<div class="checkbox">
<label>
{{Form::checkbox('is_anonymous', 1, false)}} As anonymous
</label>
#if ($errors->has('is_anonymous'))
<div class="help-block">
<strong>{{ $errors->first('is_anonymous') }}</strong>
</div>
#endif
</div>
<div class="checkbox">
<label>
{{Form::checkbox('term', 1, false, array('id'=>'term'))}} I aggree
</label>
#if ($errors->has('term'))
<div class="help-block">
<strong>{{ $errors->first('term') }}</strong>
</div>
#endif
</div>
My validation like this :
public function rules()
{
return [
'is_anonymous' =>'required',
'term' =>'required'
...
];
}
If the code executed, the validation not work
There does not appear a message. Whether on the checkbox the validation process is different?
How can I solve this problem?
You can replace your required rule with accepted when dealing with checkboxes.
As stated from the docs:
The field under validation must be yes, on, 1, or true. This is useful
for validating "Terms of Service" acceptance.
I came across this problem. I think it occurs because when a checkbox is not checked, it won't be included in the request. And if is not included in the request, Laravel will not try to validate it.
My solution was to add a hidden input with a default value before the actual checkbox.
{{Form::hidden('term', false)}}
{{Form::checkbox('term', 1, false, array('id'=>'term'))}} I aggree
Here is a related question about this behaviour.

Laravel 5: Check for Specific Error

I have Password and Confirm Password inputs. I have coded these inputs so that in the event of an error the inputs highlight, like so:
<div class="form-group {{ $errors->has('password') ? 'has-error' : '' }}>
<label>Password</label>
<input type="password" name="password" class="form-control">
</div>
<div class="form-group {{ $errors->has('password_confirmation') ? 'has-error' : '' }}>
<label>Password</label>
<input type="password" name="password_confirmation" class="form-control">
</div>
In my Controller, I validate these inputs as follows:
$this->validate($request, [
....
'password' => 'required|min:8|confirmed',
'password_confirmation' => 'required',
....
]);
When either input is null and/or less than 8 characters, the inputs highlight as expected. However, when the inputs don't match, I would logically expect the Confirm Password input to highlight. However, it is the Password field that highlights, because that is the input that the "confirmed" rule is set to.
The "$errors->has()" method simply checks if an error exists for an input. Is there a way to check if an input has a specific kind of error?
Yes, you can get the array of errors for a given input name by using:
{{ $errors->get('password') }}
So you can check if the password errors array has the confirmation error and then add the additional class to your confirmation input field:
#if (in_array(trans('validation.confirmed', ['attribute' => 'password']), $errors->get('password'))) has-error #endif
And the helper methods may vary between Laravel versions:
Laravel < 5.4: trans('validation.confirmed', ['attribute' => 'password'])
Laravel 5.4: __('validation.confirmed', ['attribute' => 'password'])

Resources