Customized validation rule on laravel form request validation - laravel

I do have a registration form in my laravel 5.4 application and laravel form request validation is used for server side validation. Some fields in this form are populated dynamically using calculations in javascript which need to be validated against user inputs.
The user input fields in the form are 'quantity', 'rate' and 'discount'.
The populated fields are 'total' and 'bill_amount'.
What i need to validate are :
Check 'total' equal to 'quantity' * 'rate'.
Check 'bill_amount' equal to 'total' - 'rate'
I would prefer laravel form request validation methods for this validation. I have tried to use methods like After Hooks and conditionally adding rule etc. and failed.
In simple words the requirement is : check if a field is equal to product of other two fields, and invalidate if not equal and validate if equal.(using form request validation.)
Thanks in advance!

After a long time I was able to find this solution.
Form request After Hooks can be used to achieve the result:
[I was unable to find this logic before]
public function withValidator($validator)
{
$quanty = $this->request->get("quantity");
$rate = $this->request->get("rate");
$billAmount = $this->request->get("bill_amount");
$validator->after(function ($validator) {
if(($quanty * $rate) != $billAmount) {
$validator->errors()->add('bill_amount', 'Something went wrong with this field!');
}
});
}

Related

Laravel - form validation to pass only if certain field is empty

So I'm building a form and I need specific fields to be empty.
They return an empty string and from other similar questions, I looked for
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class
in Kernel.php which is commented out by default, I believe.
I don't want to change its behavior since it's a global middleware.
I have tried making them nullable, string|sometimes, present|max:0 yet none of these give me the desired result. I want the validation to pass only if the fields are empty.
Any help will be deeply appreciated.
So as I understood, you want for specific field to be required, if the other field in form is empty? To achieve that, you can use required_without property in Request validation like this:
public function rules()
{
return [
'filed_name' => 'required_without:other_field_name',
];
}
public function messages()
{
return [
'filed_name.required_without' => 'filed_name is required.',
];
}
More on validation on official documentation.

Laravel form-data image and text fields validation

//TestRequest.php
public function rules()
{
return [
'name' => 'string|required|min:5',
'tip' => 'string|required|min:5',
'answer' => 'string|required',
'image' => 'file|required|mimes:png,jpg,jpeg'
];
}
//TestController.php
public function put(TestRequest $request)
{
$validated = $request->validated();
}
I'm doing some rest API. I need a form with some text fields and one image upload field but I have a problem with validating it.
When I'm sending the request as 'form-data' in the Postman, Laravel doesn't see in the validation any fields (why?).
When I'm sending the request as application/x-www-form-urlencoded Laravel sees my text fields, but I can't, of course, upload the image.
API will be used by the android APP. How I can solve this? How I can have both validation on text and file inputs?
Using application/x-www-form-urlencoded is the correct way to upload images. According to your second screenshot, you are not sending the file field in Postman, but you are sending it in the first screenshot.
see this
'name' => 'string|required|min:5',
minimum is 5 character but you send test or 4 chars. Laravel validation rule, if it failed it will stop or next validation will not checked.
I think I've found a solution.
Changing method from PUT to POST seems to fix this issue.

Laravel validation - fail when provided with input not defined in rules

Does Laravel validation provide any ways to fail when request contains input keys that are not defined in validation rules? Ex: Validator is instantiated with the following rules: ['name' => 'required', 'email' => 'required|email']. I want validation to fail if $request contains any other keys except name and email (Think of a user POSTing to the route end-point with undesirable data). Is that possible to achieve with simple validation rules?
P.S. I am aware of mass-assignment tricks with Eloquent, however I need to perform strict validation before any data is manipulated / persisted.
No, it's not possible to achieve with simple validation rules but would be easy to add.
All you would need to do is something like the following...
if ( count(request()->except(['name', 'email']) ) > 0) {
return false;
}

Codeigniter Grocery Crud update field?

$crud->set_rules('user_password', 'Password', 'trim|required|matches[konfirmpass]');
$crud->set_rules('konfirmpass', 'Konfirmasi Password', 'trim|required');
$crud->callback_edit_field('user_password',array($this,'_user_edit'));
$crud->callback_add_field('user_password',array($this,'_user_edit'));
callback function:
function _user_edit(){
return '<input type="password" name="user_password"/> Confirmation password* : <input type="password" name="konfirmpass"/>';
}
My question is how to update if only "password" not blank?
I've installed CI 2.0.3 and GC 1.1.4 to test because at a glance your code looked fine. As it turns out, it is and your code works. I modified the out of the box employees_management method in the examples controller with GC. Added a user_password column to the database and added your code to the controller.
The code both ensures that the password fields match and that they're not empty when submit.
Empty results in "The Password field is required"
Mismatched results in "The Password field does not match the konfirmpass field."
Perhaps if this isn't working for you, you should post your entire method instead of just the rules and callbacks so we can see if there are any other problems.
Edit
To edit the field, only if the password has been edited you need to add
$crud->callback_before_update( array( $this,'update_password' ) );
function update_password( $post ) {
if( empty( $post['user_password'] ) ) {
unset($post['user_password'], $post['konfirmpass']);
}
return $post;
}
This however may mean that you need to remove the validation for empty password depending on which order the callbacks run (if they're before or after the form validation runs). If they run before the form validation, you'll need to also need to run a call to callback_before_insert() and add your validation rules within the two callbacks. Insert obviously will need the required rule, and update won't.
Edit 2, Clarification of Edit 1
Having looked into it, the validation runs before the callbacks, so you can't set validation rules in the callback functions. To achieve this you'll need to use a function called getState() which allows you to add logic based on the action being performed by the CRUD.
In this case, we only want to make the password field required when we are adding a row, and not required when updating.
So in addition to the above callback update_password(), you will need to wrap your form validation rules in a state check.
if( $crud->getState() == 'insert_validation' ) {
$crud->set_rules('user_password', 'Password', 'trim|required|matches[konfirmpass]');
$crud->set_rules('konfirmpass', 'Konfirmasi Password', 'trim|required');
}
This will add the validation options if the CRUD is inserting.

Disabling validation for specific form (user login)

The problem
I have a login form available on every page (in the right menu). The problem is that when the user is on the register page, the fields from the login form are validated. I have username and password fields in both forms, and both are validated.
Ideas:
Different field names for registration form (register_username, register_password, register_email) and then set normal names before saving.
Different model (but albo using the users table) for login form?
Anyway, I just wonder what is the best way to solve this.
I'm guessing that both forms would submit to different actions, with the registration form submitting to Users->register() and the login form submitting to Users->login().
I would suggest that when you're in the register() action, you could try copying the relevant variable into another associative array and then validating and saving that, rather than validating and saving the $this->data variable.
Your second option is correct. I had encountered this problem before and wrote an article about it at the Bakery: Multiple Forms per page for the same model
The basic idea is to create separate models for each form extending the original model:
class RegisterForm extends User {
}
Then, load these forms in your controller however you please:
$this->loadModel('RegisterForm');
Then call validation as usual:
$this->RegisterForm->save($this->data);
For your particular case, you might not want to create the LoginForm model, and have only the RegisterForm model. This will let you take advantage of whatever magic the AuthComponent has.
HTH.
I haven't tried two forms with the same inputs, but this works for two forms with different inputs. I don't see why it shouldn't work for your needs.
View:
Make sure each submit button has a name value so that $this->params can identify it.
//first form ...
<?php
$profile_options = array('label' => 'edit profile',
'name' => 'form1');
echo $this->Form->end($profile_options);
?>
//second form ...
<?php
$password_options = array('label' => 'edit password',
'name' => 'form2');
echo $this->Form->end($password_options);
?>
Controller action:
Use $this->params to test for each form submission
if(isset($this->params['form']['form1'])){
$this->User->set($this->data); //necessary to specify validation rules
if($this->User->validates(array('fieldList' => array('email')))){
$this->User->saveField('email', $this->data['User']['email']);
}
}
elseif(isset($this->params['form']['form2'])){
//same deal for second form
}
It may be desirable to validate your model only using a subset of the validations specified in your model. For example say you had a User model with fields for first_name, last_name, email and password. In this instance when creating or editing a user you would want to validate all 4 field rules. Yet when a user logs in you would validate just email and password rules. To do this you can pass an options array specifying the fields to validate:
if ($this->User->validates(array('fieldList' => array('email', 'password')))) {
// valid
} else {
// invalid
}

Resources