How to translate custom values for all indexes of array based form input fields for validation in Laravel - laravel

Take this array based form input fields that allows user to add and remove items with type (simple or complex) and complex infos:
<div class="item">
<div>
<h2>Type</h2>
<label><input type="radio" name="data[0][type]" value="simple"> Simple ABC stuff</label>
<label><input type="radio" name="data[0][type]" value="complex"> Complex XYZ stuff</label>
</div>
<div class="complex"> <!-- it will be visible only when type is "Complex XYZ stuff" -->
<h2>Complex info</h2>
<input type="text" name="data[0][complex_info]"/>
</div>
<button class="remove">Remove item</button>
</div>
<div class="item">
<div>
<h2>Type</h2>
<label><input type="radio" name="data[1][type]" value="simple"> Simple ABC stuff</label>
<label><input type="radio" name="data[1][type]" value="complex"> Complex XYZ stuff</label>
</div>
<div class="complex"> <!-- it will be visible only when type is "Complex XYZ stuff" -->
<h2>Complex info</h2>
<input type="text" name="data[1][complex_info]"/>
</div>
<button class="remove">Remove item</button>
</div>
<button class="add">Add item</button>
When user selects the "Complex XYZ stuff" type, then "Complex info" input should be required. So we set this form request rule in Laravel 6.x:
public function rules() {
return ['data.*.complex_info' => 'required_if:data.*.type,complex'];
}
When the required_if validation rule fails, we get the error message The :attribute field is required when :other is :value. that with the filled parameters should result in a message like this: The Complex info field is required when Type is Complex XYZ stuff. (expected message).
The following validation.php language file would work for a form of 2 items:
return [
/* ... */
'values' => [
'data' => [
0 => [
'type' => [
'simple' => 'Simple ABC stuff',
'complex' => 'Complex XYZ stuff',
]
],
1 => [
'type' => [
'simple' => 'Simple ABC stuff',
'complex' => 'Complex XYZ stuff',
]
],
]
]
];
And I need it to work for a form with an indefinite number of items (all indexes), so I thought about using the * wildcard like:
return [
/* ... */
'values' => [
'data' => [
'*' => [
'type' => [
'simple' => 'Simple ABC stuff',
'complex' => 'Complex XYZ stuff',
]
],
]
]
];
But it doesn't work, the :value parameter of the required_if validation rule's error message is not properly translated: The Complex info field is required when Type is complex. (actual message).

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 show Array of errors in Vue.js ? Backend Validation with Laravel

I have some complex data and I want to show the validation error array data in vue file but I can not do it because I have got some data that has an index and showing like contacts.0.name: ["...."].
Please share your opinion how I can show the error.
vue file
<template>
<div>
<form enctype="multipart/form-data" #submit.prevent="handleSubmit">
<div v-for="(contact, index) in contacts" :key="index" class="row">
<div class="col col-md-3">
<div class="form-group mb-4">
<label for="personName">Contact Person Name</label>
<input
id="personName"
v-model="contact.name"
type="text"
class="form-control"
/>
<small> Want to show here the error ? </small
>
</div>
</div>
<!-- Add or Remove button -->
<div class="col col-md-12 text-right">
<div class="row ml-4">
<div v-show="index == contacts.length - 1">
<button
class="btn btn-warning mb-2 mr-2 btn-rounded"
#click.prevent="add"
>
Add More
</button>
</div>
<div v-show="index || (!index && contacts.length > 1)">
<button
class="btn btn-danger mb-2 mr-2 btn-rounded"
#click.prevent="remove"
>
Remove
</button>
</div>
</div>
</div>
</div>
</form>
</div>
</template>
<script>
export default {
data() {
return {
contacts: [
{
name: "",
},
],
errors: [],
};
},
methods: {
handleSubmit() {
let data = new FormData();
data.append("contacts", JSON.stringify(this.contacts));
Request.POST_REQ(data, "/add-institute")
.then(() => {
alert("success");
})
.catch((err) => {
this.errors = err.response.data.errors;
});
},
add() {
this.contacts.push({
name: "",
email: "",
phone: "",
alternate_phone: "",
});
},
remove(index) {
this.contacts.splice(index, 1);
},
},
};
</script>
controller file
public function add_institute(Request $request) {
$request['contacts'] = json_decode($request['contacts'], true);
$request->validate([
'contacts.*.name'=> 'unique:institute_contact_people|distinct',
]);
...rest of code of insert
return response()->json("Success...");
}
Getting Error Response data
errors: {
contacts.0.name: ["The contacts.0.name has already been taken.", "The contacts.0.name field has a duplicate value."]
0: "The contacts.0.name has already been taken."
contacts.1.name: ["The contacts.1.name has already been taken.", "The contacts.1.name field has a duplicate value."]
0: "The contacts.1.name has already been taken."
}
Okay, so your error data is basically an object with array of errors in it.
Pretty much like this
errors: {
'contacts.0.name': [
'The contacts.0.name has already been taken.',
'The contacts.0.name field has a duplicate value.',
],
'contacts.1.name': [
'The contacts.1.name has already been taken.',
'The contacts.1.name field has a duplicate value.',
],
},
For me, it will be better if you could achieve something like this as an error response (an array of objects with errors array in it)
betterErrors: [
{
location: 'contact.0.name',
errors: [
'The contacts.0.name has already been taken.',
'The contacts.0.name field has a duplicate value.',
],
},
{
location: 'contact.1.name',
errors: [
'The contacts.1.name has already been taken.',
'The contacts.1.name field has a duplicate value.',
],
},
],
For me, as of right now, it feels wrong but you can achieve a display of your errors with something like this
<template>
<div>
<div v-for="(error, key) in errors" :key="key">
<hr />
<span v-for="(errorItem, innerKey) in error" :key="innerKey" style="margin-top: 2rem">
{{ errorItem }}
</span>
</div>
</div>
</template>
<script>
export default {
data() {
return {
errors: {
'contacts.0.name': [
'The contacts.0.name has already been taken.',
'The contacts.0.name field has a duplicate value.',
],
'contacts.1.name': [
'The contacts.1.name has already been taken.',
'The contacts.1.name field has a duplicate value.',
],
},
}
},
}
</script>
PS: having a :key with an array looping index is really bad tbh. That's why I do recommend a location field in your error response.
in your controller
$request->validate([
'ClinicName' => 'required|string|min:200',
'Branches.*.BranchName'=>'required|string|min:200'
]);
in your vue3 file, to access the errors which will have keys such as,
'Branches.0.BranchName'
then you can access the above error with for loop similar to this
<p v-if="form.errors['Branches.' + counter + '.BranchName']"
class="mt-2 text-sm text-red-600 dark:text-red-500">
{{ form.errors["Branches." + counter + ".BranchName"] }}
</p>
here the counter can be any counter starting from 0.

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?

CodeIgniter form validation radio button not working

I have a form with 3 radio buttons. The IDs are unique in the form, and all three have the same name, namely "vehicle_type". The radio buttons are generated correctly when I do source view
<input type="radio" name="vehicle_type" id="type_vehicle" value="1">
<input type="radio" name="vehicle_type" id="type_trailer" value="2" checked>
<input type="radio" name="vehicle_type" id="type_plant" value="3">
I have no validation rule set for the radio group, yet my form complains that the field is required.
I can confirm that there is no validation rule by running:
echo $this->form_validation->has_rule('vehicle_type');
It indicates no validation. Using that call on another field, i.e., client_name, returns "boolean: 1"
Why would the field try to validate if there is no validation rule set?
EDIT
I am using Wiredesignz HMVC in my project, so the Form_validation class is extended.
if ($this->form_validation->run($this)) {
$test = do_file_upload($post_data);
} else {
var_dump(validation_errors());
// echos "The Vehicle type field is required"
}
This problem only occurs with radio buttons:
All other forms without radio buttons validate correctly using the same check: ($this->form_validation->run($this)
My form validation is set with this function:
public function set_form_validation_rules($data)
{
foreach ($data as $field) {
if (!empty($field['validation']['rules'])) {
if (!is_array($field['validation']['rules'])) {
$this->form_validation->set_rules($field['name'], $field['label'], $field['validation']['rules']);
} else {
foreach ($field['validation']['rules'] as $fv) {
$this->form_validation->set_rules($field['name'], $field['label'], $fv);
}
}
}
}
}
And the radio button is defined as:
$data['fields']['type_plant'] = [
'name' => 'vehicle_type',
'id' => 'type_plant',
'input_class' => 'input-group width-100',
'color' => 'red',
'value' => 3,
'validation' => '',
'checked' => ($posts['vehicle_type'] == 3)
];
The other two radio buttons in the group are the same, just have different values and IDs.
Use this,
$this->form_validation->set_rules('vehicle_type', 'Vehicle type', 'required');
Load library for form validation and other helpers in application/config/autoload.php
$autoload['libraries'] = array('form_validation');
$autoload['helper'] = array('form', 'url');
In your controller file :
$this->form_validation->set_rules('vehicle_type', 'Vehicle Type', 'required');
In your view file use below code for printing validation errors
<?php echo validation_errors(); ?>
The answers given above tells me how to use form validation. It is not what I requested. I am far beyond that - as they all worked, except for radio buttons. As it turns out, passing the validation array incorrectly to the function in the $data array. Once I passed the data correctly, the form validation also worked.
Hey Bro Try this maybe it can help
This method is very simple
In form
<div class="form-group">
<label for="vehicle_type" class="col-sm-3 control-label">vehicle</label>
<div class="col-sm-9">
<div class="col-md-3">
<label><input type="radio" name="vehicle_type" id="vehicle_type" value="1"> ONE </label>
</div>
<div class="col-md-3">
<label><input type="radio" name="vehicle_type" value="2"> TWO </label>
</div>
<div class="col-md-3">
<label><input type="radio" name="vehicle_type" value="3"> THREE </label>
</div>
<small class="info help-block"></small>
</div>
</div>
Set Your Controller
public function add_save(){
if ($this->input->post('vehicle_type') == "1"){
}else if($this->input->post('vehicle_type') == "2"){
}else if($this->input->post('vehicle_type') == "3"){
}else{
$this->form_validation->set_rules('vehicle_type', 'Vehicle', 'required');
}
if ($this->form_validation->run()) {
$save = [
'vehicle_type' => $this->input->post('vehicle_type')
];
$this->model_yourmoderl->add($save);
} else {
$this->data['errors'] = $this->form_validation->error_array();
}
$this->response($this->data);
}

Laravel Validation If checkbox ticked then Input text is required?

I have been reading Laravel validation documentation. I am not clear how to combine two rules.
For example:
<input type="checkbox" name="has_login" value="1">
<input type="text" name="pin" value="">
If has_login checkbox is ticked then Input text pin value is required.
If has_login is not ticked then Input text pin is not required.
Laravel Validation:
public function rules()
{
return [
'has_login' => 'accepted',
'pin' => 'required',
];
}
Use required_with or required_if
required_with:foo,bar
The field under validation must be present and not empty only if any of the other specified fields are present.
return [
'has_login' => 'sometimes',
'pin' => 'required_with:has_login,on',
];
--
required_if:anotherfield,value
The field under validation must be present and not empty if the anotherfield field is equal to any value.
return [
'has_login' => 'sometimes',
'pin' => 'required_if:has_login,on',
];
--
https://laravel.com/docs/5.2/validation
--
Also, if the checkbox has_login is not checked, it will not send as part of the form submission

Resources