7

The requirement was to update user roles. The role can be empty(left blank), one, or more than one as provided in the form field roles[].

Here is the view form:

@foreach ($roles as $role)
  <div class="checkbox">
     <label><input name="roles[]" type="checkbox" value="{{$role->id}}" {{ $user->roles->contains($role->id) ? 'checked' : '' }}>{{$role->name}}</label>
  </div>
@endforeach

The condition inside UserController::update() is:

if ($request->roles) {
    // update user roles
}

Everything works fine except for one case. Sometimes the user has to stay without any role.

if($request->roles), isset($request->roles), and !empty($request->roles) .. are all giving the same old fashioned reply(null, '', true/flase).

Case: when there is one or more role(s) assigned:

  +request: ParameterBag {#41 ▼
    #parameters: array:6 [▼
      "_method" => "PUT"
      "_token" => "a8oIPQFBMbhjanikX8v83qeOcfRE0N4UKTcTQDig"
      "name" => "New User Name"
      "email" => "newuser@testserver.asap"
      "password" => ""
      "roles" => array:2 [▼
        0 => "2"
        1 => "3"
      ]
    ]
  }

Case: when there no role assigned OR need to remove(detach) the previously assigned role:

  +request: ParameterBag {#41 ▼
    #parameters: array:5 [▼
      "_method" => "PUT"
      "_token" => "a8oIPQFBMbhjanikX8v83qeOcfRE0N4UKTcTQDig"
      "name" => "New User Name"
      "email" => "newuser@testserver.asap"
      "password" => ""
    ]
  }

So the question (requirement) is:

How to differentiate when the field value of an HTML Post form has been submitted as empty(unchecked here) or if there was no such a field in the view form? Is there an eloquent* way in Laravel to find/list the form fileds from the Request object?

[PS: Trying another hidden field or do some frontend jQuery will not be appreciated]

Eazy Sam
  • 288
  • 1
  • 2
  • 9
  • 1
    I think isset($request->roles) works fine to check whether there is any role or not submitted from the form – ashok poudel Mar 26 '18 at 07:37
  • have you try ? $request->has('roles') – Yanis-git Mar 26 '18 at 07:38
  • 1
    `$request->has('roles') ` is giving the same result! – Eazy Sam Mar 26 '18 at 07:43
  • `isset($request->roles)` says true or false, how do I know when there was a field but still left empty? @ashokpoudel – Eazy Sam Mar 26 '18 at 07:52
  • Please remember to check an answer as correct so the question is closed and other users can identify the answer as a solution to their problem. Thank you. – Asur Mar 28 '18 at 08:20
  • None of them from the core functions meet the requirement. Not even the server variable `$_POST` contains all form fields. There is a chance that:`$request->filled('roles')` may help for 5.5+ users but not others. Another logic (*i.e, by taking the input value as an array*) helped to to solve my custom requirement and still the question remains. – Eazy Sam Mar 28 '18 at 09:28

5 Answers5

16

You can use the laravel request methods has() or filled(), has checks if the parameter is present and filled checks it's present and filled:

if ($request->has('roles')) {
    //
}

or

if ($request->filled('roles')) {
    //
}

Check Laravel documentation for further details on retrieving input from the request object.

EDIT

Since you are using Laravel 5.2 the following rules apply:

  • The has() method checks the parameter is present and filled.
  • The exists() method checks the parameted is present.

Check the code on the repo for more information.

Asur
  • 3,727
  • 1
  • 26
  • 34
  • 1
    `filled()` is not available for versions below 5.5. I think that is the proper way to do it. Unfortunately I still use Laravel 5.2. `$request->has('roles')` is the same as `isset($request->roles)` – Eazy Sam Mar 26 '18 at 07:59
  • @EazySam I've updated the answer adding the 5.2 information :) – Asur Mar 26 '18 at 08:08
3

For this you have validations, seems that you need the roles field to be required and exists(to map to a certain table)

You just need to make the validator via artisan command and inject it in the controller method, check out the docs.

ex: php artisan make:request MyCustomRequest Then you should have a request file under: App\Http\Requests You need to set the validation rules as described above:

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class MyCustomRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'rules' =>'required|exists:tour_roles_table,id'
        ];
    }
}

Then you can use inject it in your desired method:

class UserController extends Controller {
[...]
    public function update(MyCustomRequest $req)
    {
     [...]
     //at this point validation was successfull, by default Laravel will redirect back with error messages, which can be customized in your request object
    }
[...]
}
BrynJ
  • 8,322
  • 14
  • 65
  • 89
ka_lin
  • 9,329
  • 6
  • 35
  • 56
  • This definitely seems like a job for validation. – ollieread Mar 26 '18 at 07:40
  • In this case roles are optional, so require them via validation would not be the best solution. – Asur Mar 26 '18 at 07:42
  • @Asur Tou can set fields to be optional as well if OP wants via the `sometimes` rule – ka_lin Mar 26 '18 at 07:47
  • `required` and `exist` both don't help ( – Eazy Sam Mar 26 '18 at 07:48
  • Yes of course, but he needs to add logic to the condition so the only way you could do that with validation is checking the `errorsBag`, which IMO would add unnecessary complexity to a pretty simple problem – Asur Mar 26 '18 at 07:52
  • Don't help in what way? – ka_lin Mar 26 '18 at 07:52
  • I think a validation is in order because one can have inconsistent data from the start and would need to validate before persisting the request, this is my opinion – ka_lin Mar 26 '18 at 07:55
  • @ka_lin Don't help to check a condition that: if the form has a field and that was left empty. – Eazy Sam Mar 26 '18 at 08:02
  • If a user doesn't have any roles you should send an empty `roles` parameter to be consistent – ka_lin Mar 26 '18 at 08:15
3

You will need to identify this problem in the design of your application.

How to differentiate when the field value of an HTML Post form has been submitted as empty(unchecked here) or if there was no such a field in the view form? Is there an eloquent* way in Laravel to find/list the form fileds from the Request object?

When does that form should not have a roles[] field? You should have a marker that will tell your application that this form doesn't have a roles[] field.

Something like, when this form is used when an ordinary user is updating his/her profile, he/she will not be able to update his/her roles.

Because your problem is indeed the default behavior of forms, as answered in this question: Submit an HTML form with empty checkboxes

So there will be a different process for forms which DO NOT HAVE have a roles field and different process for forms which DO HAVE a roles field.

To add to your implementation, you can retrieve the roles field like this:

$roles = $request->input('roles', []);

After which you can just use sync to the relationship method of your model.

$user->roles()->sync($roles);
Wreigh
  • 3,215
  • 16
  • 37
0

try if(empty())

$check = request::get('roles');

if(empty($checkbox)){
  //if checkbox have a empty value do ...
}else{
  //if checkbox have not empty value do .. 
}

for more information click http://php.net/manual/en/function.empty.php

Just L
  • 80
  • 1
  • 2
  • 15
0

We were just having issues checking this. We tried everything in this question and nothing worked, but finally we found a solution:

array_key_exists($request->notes)
agm1984
  • 15,500
  • 6
  • 89
  • 113