How to validate multi-row forms in laravel - php

Is it possible to validate multirow forms in laravel. I would like to validate a form which looks like this:
<input name="address[]" class="addr"/>
<input name="address[]" class="addr"/>
I've tried both methods but it doesn't seem to work:
$rule = array('address[]' => 'required'); //still returning error even if all required fields are filled up
$rule = array('address' => 'required'); //nothing happens
For the first one I made sure that there is no hidden address field:
$('.addr').length
The length returned is equal to the number of address fields I have filled out

Yes, use either of these:
$rule = array('address' => 'array');
$rule = array('address' => 'countmin:0');

I just extended the validator class and created a simple rule that checks if there's an empty value in the array:
public function validate_arrayfull($attribute, $value, $parameters){
$is_full = (in_array('', $value)) ? false : true;
return $is_full;
}
And in Validation.php a default error message:
"arrayfull" => "The :attribute contains empty values"
Usage:
$rule = array('address' => 'arrayfull');

Related

Laravel: Using validator's sometimes method when input is an array

I have a form that posts a structure field as an array. The structure array contains definitions of database table columns.
$validator = Validator::make($request->all(), [
'structure' => 'required|array|min:1',
'structure.*.name' => 'required|regex:/^[a-z]+[a-z0-9_]+$/',
'structure.*.type' => 'required|in:integer,decimal,string,text,date,datetime',
'structure.*.length' => 'nullable|numeric|required_if:structure.*.type,decimal',
'structure.*.default' => '',
'structure.*.index' => 'required_if:is_auto_increment,false|boolean',
'structure.*.is_nullable' => 'required_if:is_auto_increment,false|boolean',
'structure.*.is_primary' => 'required_if:is_auto_increment,false|boolean',
'structure.*.is_auto_increment' => 'required_if:structure.type,integer|boolean',
'structure.*.is_unique' => 'required_if:is_auto_increment,false|boolean',
'structure.*.decimal' => 'nullable|numeric|required_if:structure.*.type,decimal|lt:structure.*.length',
]);
Without going into explanation of all the rules, one thing should be made sure that the length field is always null when the type is not string or decimal as you cannot assign a length to columns other than these types. So, I am trying to use the sometimes method on the $validator instance.
$validator->sometimes('structure.*.length', 'in:null', function ($input) {
// how to access the structure type here?
});
My question is inside the closure, how do I make sure that the length is null only for the array element that has the type set to other than string or decimal.
I have tried the dd function and it seems the whole input array is passed to the closure.
$validator->sometimes('structure.*.length', 'in:null', function ($input) {
dd($input);
});
Here is the output of the dd method.
I can use a foreach construct but wouldn't that be inefficient? Checking all the elements for a single element?
How do I check the type only for the array element under consideration?
Is there a Laravel way to do this?
How about thinking opposite? if the Type is String or Decimal, the Length field will become Required.
$validator->sometimes('structure.*.length', 'required', function ($input) {
return $input->type == 'string' or $input->type == 'decimal';
});
This is a great question. I took a look at the API for sometimes(). It seems, what you want to do, is currently not possible with it.
A possible alternative could be to use an After Validation Hook. For example:
$validator->after(function ($validator) {
$attributes = $validator->getData()['structure'];
foreach($attributes as $key => $value) {
if(! in_array($value['type'], ['string', 'decimal']) && ! is_null($value['length'])) {
$validator->errors()->add("structure.{$key}.length", 'Should be null');
}
}
});

CakePHP Validation on input array that should be numeric and at least one is required

I want to create a rule which should validate from an input array to have atelast one required and that should be numeric. The input array is goal_target[#] where # is handled by back end with unique values.
I create this rule in Model. At-least one required am handling in controller and set the values in data set. Here is controller action:
//Removing initial zeros "0"
$this->request->data['goal_target'] = array_map(function($v) { return ltrim($v, '0'); }, $this->request->data['goal_target']);
//Removing empty values from input array
$this->request->data['goal_target'] = array_filter($this->request->data['goal_target']);
//Creating a data set for passing in model
$this->request->data['Goal']['targets'] = $this->request->data['goal_target'];
$this->Goal->set($this->request->data);
if(!$json_response && $this->Goal->AddValidate())
{
//Adding goal
}
else
{
$json_response['validations'] = $this->Goal->validationErrors;
}
echo json_encode($json_response);
In my modal:
public function AddValidate() {
$validateAdd = array(
'targets'=>array(
'numeric' => array(
'rule' => 'numeric',
'allowEmpty' => true,
'message' => 'Numbers only'
)
)
);
$this->validate = $validateAdd;
return $this->validates();
}
Its not working properly even on numeric values. It always return message Numbers only. What wrong am doing please let me know. Also please tell if i can get the one required also in above rule.

Kohana - rules method throwing error

I have created the following method in order to do the validation on the submitted data.
public function validate_create($array) {
$array = Validation::factory($array)
-> rules('username', $this - > _rules['username']);
return $array;
}
The rules is defined as
protected $_rules = array(
'username' = > array(
'not_empty' = > NULL,
'min_length' = > array(6),
'max_length' = > array(32),
)
);
The code is throwing the following exception when trying to execute the check() method.
ErrorException [ Warning ]: call_user_func_array() expects parameter 1
to be a valid callback, no array or string given
Can any one advice how to solve this issue?
In signup.php the input field for username is defined as
< ?php echo Form::label('user_name','Username')? > < ?php echo
Form::input('username'); ? >
The format for building the Validation object directly is different from that of your $_rules array.
You can see the correct method signature and definition documented here, and it'd probably be a good idea to also read the signature for Validation::rule.
In short, the rules() method wants an list of arrays, where for each inner array the first element is the validation function and the second an array of parameters to pass to it.
e.g.
$rules = array(
array('not_empty', NULL),
array('min_length', array(':value', 6))
);
$v = Validation::factory($values)
->rules('fieldname', $rules);
Note that this is different than the $_rules array (map) format that you are attempting to use where the key is the validation function and the parameters are the values.
Aslo, is there any reason you're building your own validation function instead of using the ORM::rules() method of validation?

Laravel change input value

In laravel, we can get the input value via Input::get('inputname'). I try to change the value by doing this Input::get('inputname') = "new value";. But then, I get the error message saying Can't use function return value in write context.
Is it possible for us change the input value so that when later calling on Input::get('inputname') will get the new amended value?
Thanks.
You can use Input::merge() to replace single items.
Input::merge(['inputname' => 'new value']);
Or use Input::replace() to replace the entire input array.
Input::replace(['inputname' => 'new value']);
Here's a link to the documentation
If you're looking to do this in Laravel 5, you can use the merge() method from the Request class:
class SomeController extends Controller
{
public function someAction( Request $request ) {
// Split a bunch of email addresses
// submitted from a textarea form input
// into an array, and replace the input email
// with this array, instead of the original string.
if ( !empty( $request->input( 'emails' ) ) ) {
$emails = $request->input( 'emails' );
$emails = preg_replace( '/\s+/m', ',', $emails );
$emails = explode( ',', $emails );
// THIS IS KEY!
// Replacing the old input string with
// with an array of emails.
$request->merge( array( 'emails' => $emails ) );
}
// Some default validation rules.
$rules = array();
// Create validator object.
$validator = Validator::make( $request->all(), $rules );
// Validation rules for each email in the array.
$validator->each( 'emails', ['required', 'email', 'min: 6', 'max: 254'] );
if ( $validator->fails() ) {
return back()->withErrors($validator)->withInput();
} else {
// Input validated successfully, proceed further.
}
}
}
If you mean you want to overwrite input data, you can try doing:
Input::merge(array('somedata' => 'SomeNewData'));
Try this,it will help you.
$request->merge(array('someIndex' => "yourValueHere"));
I also found this problem, I can solve it with the following code:
public function(Request $request)
{
$request['inputname'] = 'newValue';
}
Regards
I'm using Laravel 8.
The following is working for me:
$request->attributes->set('name', 'Value');
I used Raham's answer to solve my problem. However, it was nesting the updated data within an array, when I needed it at the same level as other data. I used:
$request->merge('someIndex' => "yourValueHere");
A note other Laravel newbies, I used the merge method to account for an empty checkbox value in a Laravel 7 update form. A deselected checkbox on an update form doesn't return 0, it doesn't set any value in the update request. As a result that value is unchanged in the database. You have to check for a set value and merge a new value if nothing exists. Hope that helps someone.
Just a quick update. If the user doesn't check a box and I need to enter a value in the DB I do something like this in my controller:
if(empty($request->input('checkbox_value'))) {
$request->merge(['checkbox_value' => 0]);
}

Placing proper filed name error print out for validation

I am working on my first form validation. The issue that I am having is error reporting to the use.
I used an array to set up my criteria/rules for the fields:
$validate = new Validation;
$validation = $validate->check($_POST, array(
'FirstName' => array(
'name' => 'First Name',
'required' => 'TRUE'),
'LastName' => array(
'name' => 'Last Name',
'required' => TRUE));
I would like to have an error show that tells the user he/she is missing a required field without show the field name, for example: FirstName is required. I would like to see: First Name is required.
I looped through each array:
public function check($source, $items = array())
foreach($items as $item => $rules){
foreach($rules as $rule => $rule_value){
echo "{$item} {$rule} must be {$rule_value}<br>";
}
}
}
When I echo out the loops I my criteria, however, When I would try to echo out $rule_value [0], I would only get the first letter of that array.
Any suggestions?
I think that you may get rid of the second foreach loop and do something like this:
public function check($source, $items = array())
{
// In your example you have two arrays in $items so the following
// foreach will iterate two times
foreach($items as $item => $values) {
// $item is going to be 'FirstName' on the first iteration
// and 'LastName' on the second iteration
//
// $values are going to be the array that's associated
// with 'FirstName' => array(...) and 'LastName' => array(...)
// i.e. $values = array('name' => '...', 'required' = TRUE/FALSE)
// Therefore, you can easily check if a given $item is required
// and if the $source contains that $item or not:
if ($values['required'] && empty($source[$item])) {
echo "{$values['name']} is required!";
}
// EDIT for your comment - validating the string length
if ( $values['minLength']
&& strlen($source[$item]) < $values['minLength'])
{
echo "{$values['name']} must be at least {$values['minLength']} characters.";
}
}
}
What the code above does is that it goes through all elements of $items and if it finds a required field, it then checks whether the $source has the appropriate value or not (or if it's empty) and echoes an error (you may want to do different validations, this is just to illustrate an example).
Footnote: By the way, I'm not sure how you separate the view and the model but I find it useful not to echo right from the logic functions. So in your check function I'd build up an array/object with all that validation errors and I'd return it to the view - which would take care of displaying the errors. This way, you could control where the errors appear visually as I'm thinking it is perhaps useful to highlight each form field with its error.

Categories