Laravel 4 - Input::old for radio buttons - laravel

I was wondering if some Laravel guys can help out.
I have a form in which i have 2 radio buttons, when the form submits it goes through the validator, if the validator fails it comes back to the form, populates the fields with the input and displays error messages.
I cant seem to do this for radio buttons, if one is clicked when the form is submitted and there was an error, it comes back to the form with everything filled out EXCEPT the radio button that was checked is now empty.
My radio buttons are as follows:
<input type="radio" name="genre" value="M" class="radio" id="male" />
<input type="radio" name="genre" value="F" class="radio" id="female" />
<span class="error">{{ $errors->first('genre') }}</span>
Any help would be greatly appreciated.

You can try this using Laravel's out of the box HTML radio...
Laravel Docs Form checkboxes and Radio
Using blade,
{{ Form::radio('genre', 'M', (Input::old('genre') == 'M'), array('id'=>'male', 'class'=>'radio')) }}
{{ Form::radio('genre', 'F', (Input::old('genre') == 'F'), array('id'=>'female', 'class'=>'radio')) }}
Or just php,
echo Form::radio('genre', 'M', (Input::old('genre') == 'M'), array('id'=>'male', 'class'=>'radio'));
echo Form::radio('genre', 'F', (Input::old('genre') == 'F'), array('id'=>'female', 'class'=>'radio'));

You could do this:
<input type="radio" name="genre" value="M" class="radio" id="male" <?php if(Input::old('genre')== "M") { echo 'checked="checked"'; } ?> >
<input type="radio" name="genre" value="F" class="radio" id="female" <?php if(Input::old('genre')== "F") { echo 'checked="checked"; } ?> >

The bug is known :
- https://github.com/laravel/laravel/issues/2069
- https://github.com/laravel/framework/issues/1564
You have a temporary solution in the second link.

I've just stumbled into this and I don't want to keep repeating such conditions on every form, so I've created a function on my Helper class.
Helper.php:
class Helper {
// other functions
public static function oldRadio($name, $value, $default = false) {
if(empty($name) || empty($value) || !is_bool($default))
return '';
if(null !== Input::old($name)) {
if(Input::old($name) == $value) {
return 'checked';
} else {
return '';
}
} else {
if($default) {
return 'checked';
} else {
return '';
}
}
// Or, short version:
return null !== Input::old($name) ? (Input::old($name) == $value ? 'checked' : '') : ($default ? 'checked' : '');
}
}
So, now on my forms, I just use it like this:
<label>Please select whatever you want</label>
<div class="radio-inline"><label><input type="radio" name="whatever" value="1" required {{ Helper::oldRadio('whatever', '1', true) }}> One</label></div>
<div class="radio-inline"><label><input type="radio" name="whatever" value="2" {{ Helper::oldRadio('whatever', '2') }}> Two</label></div>
<div class="radio-inline"><label><input type="radio" name="whatever" value="3" {{ Helper::oldRadio('whatever', '3') }}> Three</label></div>
Each option passes its name and value to the helper function and the previously selected one will print 'checked'. Additionally, an option can pass 'true' as the third parameter so it gets selected if there was no old input.

Using with the Bootstrap & Automatic checking
Add this code at end of file: app/start/global.php
//...
Form::macro('radio2', function($group ='group-name', $value_model = 'value-model', $label ='label-radio', $value_radio = 'value-radio', $attrs = array())
{
$item = "<div class='radio'>";
$item .= "<label>";
$item .= Form::radio($group, $value_radio, ($value_model == $value_radio) ? true : false, $attrs);
$item .= $label;
$item .= "</label>";
$item .= "</div>";
return $item;
});
In your view.php
{{ Form::radio2('status', Input::old('status'), 'Online', '1', array()) }}
{{ Form::radio2('status', Input::old('status'), 'Offline', '0', array()) }}
Final result:

I tried simply using Input::get() instead of Input::old().... and it's worked!!{{Form::radio('estado','V',(Input::get('estado')=="V"))}}

My approach is a nested shorthand if/else statement with blade syntax. This solution considers also the initial value that is set in the database.
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="sex" id="male" value="male"{!! ((old('sex') == 'male') ? ' checked="checked"' : ((empty(old('sex')) && $user->sex == 'male') ? ' checked="checked"' : '')) !!}/>
<label class="form-check-label" for="male">Männlich</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="sex" id="female" value="female"{!! ((old('sex') == 'female') ? ' checked="checked"' : ((empty(old('sex')) && $user->sex == 'female') ? ' checked="checked"' : '')) !!}/>
<label class="form-check-label" for="female">Weiblich</label>
</div>
Tested with Laravel 5.7.

Related

Found 2 elements with non-unique id (#_ajax_nonce) and (#_wpnonce)

I am developing custom theme from scratch and creates a custom post type and getting this warning while editing custom post type. I also design custom Meta box with two input fields and using nonce in it. Any help removing these warning?
//Custom Metabox
function register_book_meta_box(){
add_meta_box('book_meta_box_id', 'Book Detail','design_book_meta_box','books','advanced','high');
}
add_action('add_meta_boxes','register_book_meta_box');
function design_book_meta_box($post){
wp_nonce_field(basename(__FILE__),'book_cpt_nonce')
?>
<div>
<label for="book-author">Author Name </label>
<input type="text" name="book-author" placeholder="Author Name" value="<?php echo get_post_meta( $post->ID, 'book-author-key', true );?>">
</div>
<div>
<label for="year">Published Year</label>
<input type="number" id="year" name="year" min="1455" max="2020" value="<?php echo get_post_meta( $post->ID, 'book-year-key', true );?>">
<span id="errorMsg" style="display:none;">Published Year Must be range from 1455 - 2020</span>
</div>
<?php
}
function save_book_meta_data($post_id)
{
if(!isset($_POST['book_cpt_nonce']) || !wp_verify_nonce($_POST['book_cpt_nonce'],basename(__FILE__))){
return $post_id;
}
if (array_key_exists('book-author', $_POST)) {
update_post_meta( $post_id,'book-author-key', $_POST['book-author']
);
}
if (array_key_exists('year', $_POST)) {
update_post_meta( $post_id,'book-year-key', $_POST['year']
);
}
}
add_action('save_post', 'save_book_meta_data');

Laravel - old() value of checkbox, in combination with the one loaded from the database

I have this checkbox code:
<div>
<input type="checkbox" id="allowfullscreen" name="allowfullscreen"
{{ $gallery->allowfullscreen == 1 ? 'checked' : '' }}>
</div>
This checks the checkbox based on the value taken from the database. Now, i would like to implement also the old data, in case of a failed submission.
For textboxes i do it like this:
<input id="galname"
type="text"
class="form-control #error('galname') is-invalid #enderror"
name="galname"
value="{{ old('galname') ?? $gallery->galname }}"
required autocomplete="galname" autofocus>
But it does not work this way for checkboxes since they need checked to be printed. The samples I found around here on SO only adress one of the two situations, but didnt find any that address both things for checkboxes.
How can this be done?
The second parameter you give the the old() function is used when the first value is null. So when you do old('name', "test") and no old value for 'name' is found, 'test' is used. So in your case, you could use:
<div>
<input type="checkbox" id="allowfullscreen" name="allowfullscreen"
{{ old('allowfullscreen', $gallery->allowfullscreen) == 1 ? 'checked' : '' }}>
</div>
This is ok even if you use all inputs in one blade template to use with create and update actions.
Will only work for POST request, obviously.
#if(old('published', (old('_token') ? false : ($slider->published ?? false)))) checked #endif
<div class="form-group">
<input class="form-check-input" type="checkbox" id="publish" name="published" value="1" #if(old('published', (old('_token') ? false : ($slider->published ?? false)))) checked #endif>
<label class="form-check-label" for="publish">{{ __('Publié') }}</label>
#include('bo.modules.input-error', ['inputName'=>'published'])
</div>
Using this on request
/**
* Prepare the data for validation.
*
* #return void
*/
protected function prepareForValidation()
{
$this->merge([
'published' => $this->published ? true : false
]);
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'published' => 'required|boolean',
];
}

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);
}

#can directive issue - laravel

jobs.edit.blade.php can be accessed by registered users
out of them the accountant can access some checkboxes(only visible to him)
The database values are changed(Boolean) according to checkboxes submitted by the accountant.
#can ('isAccountant')
//some code with checkboxes
#endcan
The problem is, when a registered user access jobs.edit.blade.php
and submits(Checkboxes are not visible), all the Boolean values in the database becomes Zero
How can i avoid this situation
jobs.edit.blade.php
#can ('isAccountant')
<div class="row">
<div id="status">
#if ($job->entered_status == '0')
<input type="checkbox" name="entered_status" #if($job->entered_status) checked #endif> Entered <br><br>
#elseif ($job->entered_status == '1')
<input type="checkbox" name="entered_status" checked value="1" disabled> Entered <br><br>
<input type='hidden' name='entered_status' value="1">
#endif
#if ($job->sales_status == '1')
<input type="checkbox" name="despatch_status" checked value="1" disabled> All Despatches Completed <br><br>
<input type="checkbox" name="invoice_status" checked value="1" disabled> All Invoices Completed
<input type='hidden' name='despatch_status' value="1">
<input type='hidden' name='invoice_status' value="1">
#endif
#if ($job->sales_status == '0' && $job->job_status == 'Completed' && $job->despatch_status == '0')
<input type="checkbox" name="despatch_status" #if($job->despatch_status) checked #endif value="1"> All Despatches Completed <br><br>
#endif
#if ($job->sales_status == '0' && $job->job_status == 'Completed' && $job->despatch_status == '1')
<input type="checkbox" name="despatch_status" checked value="1"> All Despatches Completed <br><br>
<input type="checkbox" name="invoice_status" #if($job->invoice_status) checked #endif value="1"> All Invoices Completed <br><br>
#endif
</div>
</div>
#endcan
JobController.php
public function update(Request $request, $id)
{
$job = Job::find($id);
$job->customer_name = $request->customer_name;
$job->company_name = $request->company_name;
$job->job_type = $request->job_type;
$job->job_owner = $request->job_owner;
$job->job_status = $request->job_status;
$job->despatch_status = $request->has('despatch_status');
$job->invoice_status = $request->has('invoice_status');
if ($job->despatch_status == 1 && $job->invoice_status == 1) {
$job->sales_status = 1;
}
$job->entered_status = $request->has('entered_status');
AuthServiceProvider.php
public function boot()
{
$this->registerPolicies();
Gate::define('isAdmin', function ($user) {
return $user->user_type == 'Admin';
});
Gate::define('isDirector', function ($user) {
return $user->user_type == 'Director';
});
Gate::define('isProduction', function ($user) {
return $user->user_type == 'Production';
});
Gate::define('isAccountant', function ($user) {
return $user->user_type == 'Accountant';
});
}
Extended Error
_token
"nzY5y8EW5yupkL3d6aL9bcpZRYmlc5YTN94ee1uI"
_method
"PATCH"
id
"10725"
customer_name
""
company_name
""
job_type
"""
Item:\r\n
Qty:\r\n
Size:\r\n
Paper:\r\n
Print:\r\n
Each:\r\n
Total:
"""
job_owner
"Sam"
job_status
"Pending"
job_delivery_date
""
job_delivery_time
""
pk_pkl
"PKL"
entered_status
"on"
The reason for this is that you are using:
$job->despatch_status = $request->has('despatch_status')
$request->has('despatch_status') is true if the request has the field, and false if the request does not have the field.
The code i can recommend:
This will get the despatch_status from the request, if its true or false (or 1/0) it will get passed to $job->despatch_status.
But if despatch_status is not present in the request, the ->get() will return null, so the ?? operator will then read the value already in the database, so then it wont change.
$job->despatch_status = $request->get('despatch_status') ?? $job->despatch_status;
Based on the comments of the other answer, add this to your RouteServiceProvider:
public function boot()
{
//
parent::boot();
if (!$this->app->runningInConsole()) {
foreach (request()->all() as $key => $value) {
if (is_string($value) && $value === 'on') {
request()->offsetSet($key, true);
}
}
}
}
What this will do is scan all incoming fields, and if they are 'on' they get cast to true.
(the reason we add this to a service provider and not middleware is based on order of execution)

Laravel Pagination Appends Not Keeping Search Data

I've been able to implement the pagination and appends() on my form and it does show the proper values in the url on page 2, though it doesn't actually bring the values back into the form/query, it simply resets the actual data being searched for and displays all.
Here is my form code and the appends.
{{ Form::open(array('class' => 'stdform', 'method' => 'post', 'name' => 'all')) }}
<input type="text" name="srch_lname" class="input-large"
value="{{ Input::old('srch_lname', Session::get('srch_lname')) }}" />
<input type="text" name="srch_fname" class="input-large"
value="{{ Input::old('srch_fname', Session::get('srch_fname')) }}" />
.
.
.
<?php echo $employees->appends(array("srch_lname" => Session::get('srch_lname'),
"srch_fname" => Session::get('srch_fname') ))->links(); ?>
And my Controller
public function getIndex() {
$srch_lname = Session::get('srch_lname');
$srch_fname = Session::get('srch_fname');
$employees = vEmployees::co()->restrictions()
->where('lastname', 'LIKE', $srch_lname . '%')
->where('firstname', 'LIKE', $srch_fname . '%')
->paginate(10);
return View::make('employees.index')
->with('employees', $employees)
->with('title', 'Users');
}
public function postIndex() {
if (Input::has('btnSearch')) {
return Redirect::to('/employees')->with('search', 1)
->with('srch_lname', Input::get('srch_lname'))
->with('srch_fname', Input::get('srch_fname'));
else {
return Redirect::to('/employees');
}
}
Full Form
{{ Form::open(array('class' => 'stdform', 'method' => 'post', 'name' => 'all')) }}
<div class="stepContainer">
<div class="formwiz content">
<h4 class="widgettitle">Search for an Employee</h4>
<p>
<label>Lastname</label>
<span class="field">
<input type="text" name="srch_lname" class="input-large"
value="{{ Input::old('srch_lname', Session::get('srch_lname')) }}" />
</span>
</p>
<p>
<label>Firstname</label>
<span class="field">
<input type="text" name="srch_fname" class="input-large"
value="{{ Input::old('srch_fname', Session::get('srch_fname')) }}" />
</span>
</p>
</div>
</div>
<div class="actionBar" style="text-align: right;">
<button class="btn btn-primary" name="btnSearch" value="1">
Search for Employee(s)
</button>
</div>
{{ Form::close() }}
You need to pass your inputs to the view so that Input::old() has values to work with after the redirect from postIndex to getIndex.
in getIndex(), add to View::make()
->with('input', [ 'srch_lname'=> $srch_lname, 'srch_fname' => $srch_fname ]);
It looks like you do not have the pageSearch value in your pagination query string. Try this.
<?php echo $employees->appends(
array("btnSearch" => "1",
"srch_lname" => Session::get('srch_lname'),
"srch_fname" => Session::get('srch_fname') )
)->links(); ?>
I made a small sample but since I don't have your employees I just used the User model and commented out the filtering, just used as a test to pass and get input values.
Note the change to Input:: from Session, in getIndex() and in the form for $employees->appends(). Use Input instead of Session, I did not see anywhere in your code where you save the filter values in session variables.
I also changed the Redirect::to() to pass the parameters in the URL since it is a get method.
I tested and the filter values are passed to getIndex() and the form fields, also the inputs get properly passed by pagination links.
class EmployeeController extends BaseController
{
public
function getIndex()
{
$srch_lname = Input::get('srch_lname');
$srch_fname = Input::get('srch_fname');
$employees = User::query()
//->where('lastname', 'LIKE', $srch_lname . '%')
//->where('firstname', 'LIKE', $srch_fname . '%')
->paginate(10);
// make input available for page's form fields as old input
Session::flash('_old_input', Input::all());
return View::make('employees')
->with('employees', $employees)
->with('title', 'Users');
}
public
function postIndex()
{
if (Input::has('btnSearch'))
{
return Redirect::to('/employees?search=1&srch_lname=' . urlencode(Input::get('srch_lname')) . '&srch_fname=' . urlencode(Input::get('srch_fname')));
//return Redirect::to('/employees')->with('search', 1)
// ->with('srch_lname', Input::get('srch_lname'))
// ->with('srch_fname', Input::get('srch_fname'));
}
else
{
return Redirect::to('/employees');
}
}
}
Form and ->appends():
{{ Form::open(array('class' => 'stdform', 'method' => 'post', 'name' => 'all')) }}
<div class="stepContainer">
<div class="formwiz content">
<h4 class="widgettitle">Search for an Employee</h4>
<p>
<label>Lastname</label>
<span class="field">
<input type="text" name="srch_lname" class="input-large"
value="{{ Input::old('srch_lname', Session::get('srch_lname')) }}" />
</span>
</p>
<p>
<label>Firstname</label>
<span class="field">
<input type="text" name="srch_fname" class="input-large"
value="{{ Input::old('srch_fname', Session::get('srch_fname')) }}" />
</span>
</p>
</div>
</div>
<div class="actionBar" style="text-align: right;">
<button class="btn btn-primary" name="btnSearch" value="1">
Search for Employee(s)
</button>
</div>
{{ Form::close() }}
<?php echo $employees->appends(array("srch_lname" => Input::get('srch_lname'),
"srch_fname" => Input::get('srch_fname') ))->links(); ?>
I got it working! I continued to do some research and running the search through POST was really a major issue in adding that gap between the search itself and holding the data into the GET method of pagination.
I'll run through everything I did below for anyone in the future having the same issue.
I first created a Route that would direct to a new function in my EmployeesController
Route::get('emp_srch', 'EmployeesController#search');
And created the new function in the Controller
public function search() {
$srch_lname = Input::get('srch_lname');
$srch_fname = Input::get('srch_fname');
$employees = vEmployees::co()->restrictions()
->where('lastname', 'LIKE', $srch_lname . '%')
->where('firstname', 'LIKE', $srch_fname . '%')
->orderBy('lastname')
->orderBy('firstname')
->paginate(10);
Session::flash('_old_input', Input::all());
return View::make('employees.index')
->with('employees', $employees)
->with('title', 'Users')
->with('pagetitle', 'Employees')
}
It's essentially the function I had in the getIndex though rearranging the way the search was functioning I believe was the defining factor in actually getting this to work in my case.
I also changed the url on the form, which directed to my new Route. As well as changing the form so it uses the GET Method and no longer POST.
{{ Form::open(array('url' => 'emp_srch', 'class' => 'stdform', 'method' => 'get')) }}
I do want to thank vladsch and whoacowboy for helping push me in the right direction(s).

Resources