Validation on checkbox where one one checkbox must be checked in laravel - 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.

Related

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 not working correctly in Laravel Livewire

I dont know what I am doing wrong. I have some fields with images, I want to do an update to the database only if there is an image. I have tried setting to nullable but I keep on getting error the photo must be of type image.
This is my code in Livewire class:
$this->validate([
'photo1'=>'sometimes|image',
'photo2'=>'nullable|image',
'photo3'=>'nullable|image'
]);
In the blade
<div class="col-md-6">
<label>Front Right</label>
<input type="file" wire:model="photo1" accept="image/*">
<span class="text-danger">#error('photo1'){{ $message }}#enderror</span>
</div>
<div class="col-md-6">
<label>Flont Left</label>
<input type="file" wire:model="photo2" accept="image/*">
<span class="text-danger">#error('photo2'){{ $message }}#enderror</span>
</div>
</div>
Probably it's bit late for it, but I had the same issue and this is the solution:
If you are using updated instead of updating it will work. The problem when using updating is that the property does not have the file assigned, so it's still null during validation.
Let's say your are using updating() and your property name is $logo:
You would need to assign the $value to the property ($logo) before validation, e.g.:
function updating($key,$value) {
$this-logo = $value; // This line you need to add to make it work
$this-validateOnly($key);
}
I do simply use updated() instead.
Have you added enctype="multipart/form-data" in form element?
Add mimes in validation: 'photo2'=>'nullable|image|mimes:jpg,jpeg,png,svg,gif' and then check if it works.

Issues with radio button in laravel

i want to set the radio button in the form using controller
( note: no database included).
And i even have no idea how to set the radio
button in the form using controller .
{this is my radio button}
<div class="row">
<div class="col-25">
<label for="gender">Gender</label>
</div>
<div class="col-75">
<input type="radio" name="gender" value="male" > Male
<input type="radio" name="gender" value="female"> Female
</div>
</div>
this is my controller :
class NewController extends Controller
{
public function index(Request $request)
{
$fullname='sagar basnet';
$subject='this is my test form';
return view('newfile/forms')
->withFullname($fullname)
->withSubject($subject);
}
I am going make a best effort to answer your question as their is no sample code provided.
I am assuming that you want to set the state of a radio button in the UI based on conditions that occur within your controller logic.
In your controller..
$radioVal = false;
if ($condition) {
$radioVal = 'checked';
}
return view('your.view', [
'radioVal' = $radioVal;
]);
The condition is the condition that determines whether or not your radio is checked (e.g. apples = fruit)...
In your view...
<input type="radio" {{ $radioVal or 'checked' }} />
The "or" keyword in blade offers you a ternary shorthand alternative.
You will need to give your radio button a name obviously...

Parsing data from blade form to controller using request

I want to parsing my label name="predictDataTemp" in form into my controller, I already set the value form my label, but when I want to request the data still null
content.blade.php
<div class="form-group" align="center">
<label for="exampleResult" name="result">Result</label>
<label for="examplePredict" id="predictData" class="form-control">
<input type="hidden" name="predictDataTemp">
</label>
</div>
controller
public function result(Request $request){
$this->validate($request,[
'mCalories'=>'required',
'mCholesterol'=>'required',
'mFat'=>'required',
'mProtein'=>'required',
'mSugars'=>'required'
]);
$item= array();
array_push($item,array('Calories'=>$request->mCalories,'Cholesterol'=>$request->mCholesterol,'Fat'=>$request->mFat,'Protein'=>$request->mProtein,'Sugars'=>$request->mSugars,'Predict'=>$request->predictDataTemp));
return json_encode($item);
}
Your input has no value.
If you want to give it a value with jQuery (looking at your previous comments)
Give the input an id
<input type="hidden" name="predictDataTemp" id="predictDataTemp">
Then assign it in jQuery
$('#predictDataTemp').val('pass value here');
label don't have name attribute, it has only two attribute for and form so you can pass value in hidden input tag, Read this article
Instead
<label type="text" for="examplePredict" id="predictData" name="predictDataTemp" class="form-control"></label>
Use this
<label type="text" for="examplePredict" class="form-control"></label>
<input type="hidden" name="predictDataTemp" id="predictData" value="something">

How do we check Twitter Bootstrap radio buttons using Laravel Dusk?

According to twitter bootstrap, this is how we do a radio:
<div class="radio">
<label>
<input type="radio" name="optionsRadios" id="optionsRadios1" value="option1" checked>
Option one is this and that—be sure to include why it's great
</label>
</div>
And this is my code:
$browser->click('#menu-reports')
->waitForText('Users')
->click('#menu-reports-users')
->radio('sitesActive', '2')
->radio('includeDisabled', '2')
->radio('includeNonCertifiable', '2')
->press('Apply')
->waitForText('Showing 0 to 0 of 0 entries')
;
With the input inside the label tag. But the problem is that Dusk (actually Facebook Webdriver) is not able to find it this way. It keeps raising:
Facebook\WebDriver\Exception\ElementNotVisibleException: element not visible
To make it work I have put the input outside the label, but then, of course, the boostrap radio does not show as it should anymore.
<div class="radio">
<input type="radio" name="optionsRadios" id="optionsRadios1" value="option1" checked>
<label>
Option one is this and that—be sure to include why it's great
</label>
</div>
Does not work using IDs either:
Not even setting an ID to the input:
<input
type="radio"
name="sitesActive"
id="sitesActive3"
value="2"
>
And trying to select it this way:
->radio('#sitesActive3', '2')
The problem is that Dusk (Webdriver) cannot even see the element in the page, as this simple like fails the exact same way:
$browser->waitFor('#sitesActive3');
Resulting in:
Facebook\WebDriver\Exception\TimeOutException: Waited 5 seconds for selector [#sitesActive3].
And that happens every time I have a form with an input with a label surrounding it, if I take the input out of the label, it works. But that's not as simple with radios, as it was with some other inputs, radios.
This is a properly coded radio:
This is a radio with the input outside the label tag:
So, how are you doing this?
My form has a radio button. This how I checked it.
userCreate.blade.php
<div class="row">
<div class="col-md-12">
<div class="form-group">
<label>Gender</label>
<div>
<label class="radio-inline">
<input type="radio" id="gender" name="gender" value="m">Male
</label>
<label class="radio-inline">
<input type="radio" id="gender" name="gender" value="f">Female
</label>
</div>
</div>
</div>
</div>
CreateUserTest.php
class CreateUserTest extends DuskTestCase
{
public function testCreateForm()
{
$this->browse(function (Browser $browser) {
$browser->visit('/user/create')
->radio('#gender', 'm')
->click('button[type="submit"]')
->assertSee('Successfully created user.');
});
}
}
This works for me. I think this will help you.
simplest way is to click on the parent
$el = $this->resolver->resolveForRadioSelection($field, $value);
$el = $el->findElement(WebDriverBy::xpath(".."));
$el->click();
Since the radio is not visible dusk cannot click on it
You may create a trait like the following if you are using bootstrap in your project
trait BootstrapInteraction
{
/**
* Undocumented variable
* #var \Laravel\Dusk\ElementResolver $resolver
*/
public $resolver;
public function radioB($field, $value)
{
/**
* #var RemoteWebElement $el
*/
$radio = $this->resolver->resolveForRadioSelection($field, $value);
// click on parent
$el = $radio->findElement(WebDriverBy::xpath(".."));
$el->click();
// if not selected click on label
if (!$radio->isSelected()) {
$el = $el->findElement(WebDriverBy::cssSelector("label"));
$el->click();
}
PHPUnit::assertTrue(
$radio->isSelected(),
"Not able to select Radio [{$field}] within value [{$value}]."
);
return $this;
}
You may not be happy to edit your views for the sake of your test script but if you are open to that, what about adding a class to the
<input type="radio" ... >
and then using
->click('.yourClass')
in your Dusk test?
The Dusk docs say:
To "select" a radio button option, you may use the radio method. Like many other input related methods, a full CSS selector is not required. If an exact selector match can't be found, Dusk will search for a radio with matching name and value attributes: $browser->radio('version', 'php7');
In my case, Dusk was working fine for most of my radio buttons, but it would not work for:
->radio('Field728', 'Know it\'s what anyone committed to this dream would do if she found a great program that features a proven process and supportive community')
I also tried using double-quotes, but that didn't work either. (Maybe the value is too long? I don't know.)
So instead I did this:
->radio('#Field728_0', true)//this is the specific ID of the first radio button of this group

Resources