Guy Incognito
Guy Incognito

Reputation: 500

unchecked checkbox with "Input::old()"

I'm creating a checkbox in a view:

Form::checkbox('test', 'true', Input::old('test', true));

After unchecking the box, submitting the form and being redirected back:

return Redirect::back()->withInput()->withErrors($validation);

The checkbox is still checked - presumably because 'test' doesn't exist in "Input::old" so it is reverting back to the default value.

Any suggestions on how best to achieve this?

Edit:

I've come up with a somewhat hacky way of getting the results I want:

$isChecked = true; // The default state
// Check if the form has been returned "withInput"
if(Input::old())
{
    $isChecked = Input::old('test', false); // If the field has old data available use that, otherwise it is unchecked
}
echo Form::checkbox('test', 'true', $isChecked);

I'll write this into a function for reuse, but it seems a bit painful so any comments/suggestions would be great

Edit 2 Sorry if not clear - to clarify:

  1. Form is loaded with checkbox checked
  2. I uncheck the checkbox and submit the form
  3. The form doesn't validate so I'm returned to the form
  4. The checkbox has re-checked itself - I would expect it to be unchecked, as per the user submitted data

I assume this happens because if a checkbox isn't checked the element isn't included in the post data

Upvotes: 5

Views: 15339

Answers (8)

Kazuya  Gosho
Kazuya Gosho

Reputation: 1195

I had the same problem. I end up with creating this helper function:

function is_checked(string $name, $value, $default) : string
{
    $current_defaults = Input::old() ? old($name, 0) : $default;
    return ($value == $current_defaults) ? 'checked' : '';
}

<input type="checkbox" name="is_acrive" value="1" 
       {{ is_checked('is_active', 1, $user->is_active) }}>

Multiple checkbox version:

function is_checked_multiple(string $name, $value, $defaults) : string
{
    $current_defaults = Input::old() ? old($name, []) : (array)$defaults;
    return in_array($value, $current_defaults) ? 'checked' : '';
}

@foreach ($plans as $plan)
    <input type="checkbox" name="plans[]" value="{{ $plan->id }}" 
           {{ is_checked_multiple('plans', $plan->id, $user->plans->pluck('id') }}>
@endforeach

Upvotes: 0

Elias Mamalias Jr.
Elias Mamalias Jr.

Reputation: 62

I have the same problem..

I fixed it like this

Form::checkbox('test', 'true', Input::old() ? Input::old('test', false) : true);

hope that helps..

Upvotes: 0

GTCrais
GTCrais

Reputation: 2087

I had the same problem. Turns out it was because I followed the instructions on how to post an unchecked checkbox, which said:

echo Form::hidden('name', 0);
echo Form::checkbox('name', 1);

The problem with this is that on form validation fail, if the checkbox was checked, Laravel will repopulate both 'hidden' and 'checkbox' fields with old value, so your hidden field will always be submitting 1 instead of 0. Simple solution is just write HTML for the hidden field instead of using the form helper:

echo '<input type="hidden" name="name" value="0">';
echo Form::checkbox('name', 1);

Upvotes: 10

kablamus
kablamus

Reputation: 931

The checkbox and session mismatch was an error that has been corrected in Laravel 4. The following code should preserve the checkbox on redirect:

echo Form::checkbox('payment_method', 'credit');

For grouped checkboxes, use something like this:

echo Form::checkbox('payment_method[]', 'credit');

That should also work.

**Obviously you will want to replace payment_method and credit with your own attributes.

Upvotes: 2

C-A
C-A

Reputation: 699

My solution to the same problem:

1) Remove the checkbox from validation. Logically, it makes no difference.

2) In my controller update function, I added an if statement that used isset to determine whether the value was sent or not (if not sent, it wasn't checked and therefore false).

if ($validation->passes())
{
    $xxx = $this->xxx->find($id);
    $xxx->update($input);
    if (!isset($input['checkbox_attribute'])) {
        $xxx->checkbox_attribute = false;
    }
    $xxx->save();
    return Redirect::to('xxx.show');
}

Upvotes: 0

ericbae
ericbae

Reputation: 9644

This was a bit confusing for me too. But this is what I did.

In my controller,

Session::flash('test', Input::get('test') ? 'true' : 'false');

And in the view

<?php $test = Session::get('test'); ?>
<input type="checkbox" id="test" name="test" value="true" <?php echo is_null($test) ? 'checked' : ($test == 'true' ? 'checked' : ''); ?> />

So, pretty much using an additional session flash data to get around.

Upvotes: 1

Lucky Soni
Lucky Soni

Reputation: 6888

Why not do something like this:

<?php $last_turnaround = (array) Input::old('turnaround'); ?>

{{ Form::checkbox( 'turnaround', 'normal', in_array('normal', $last_turnaround), array('id' => 'turnaround_normal', 'class' => 'turnaround')) }}

Upvotes: 0

Antonio Carlos Ribeiro
Antonio Carlos Ribeiro

Reputation: 87769

This should is sufficient

echo Form::checkbox('test', 'true', Input::old('test', true));

If Input::old() doesn't exists, it will return true, your default.

Upvotes: 5

Related Questions