3

I have a foreach loop that has a checkbox in it. I am not sure how to properly get that from the checkbox in the form over to the validation in the controller. I have the following in my view:

<table class="table">
  <thead>
    <tr>
      <th scope="col">Select</th>
    </tr>
  </thead>
  <tbody>
    @foreach($plans as $plan)
    <tr>
      <td>
        <input type='checkbox' name='Plan {{$plan->{'Plan ID'} }}' class='form-check-input' value='true'
          @if(old($plan->{'Plan ID'},$plan->{'Plan ID'})=="true") checked @endif>
      </td>
      <td> {{$plan->{'Plan ID'} }}</td>
      @endforeach
    </tr>
  </tbody>
</table>

I have the following in my controller:

$data = request()->validate ([
  'current' => '',
  'instructions' => '',
  'Plan 1' => '',
  'Plan 2' => '',
  'Plan 3' => '',
  'Plan 4' => '',
  'Plan 5' => '',
  'Plan 6' => '',
  'Plan 7' => '',
  'Plan 8' => '',
  'Plan 9' => '',
  'Plan 10' => '',
  'Plan 11' => '',
  'Plan 12' => '',
  'Plan 13' => '',
  'Plan 14' => '',
  'Plan 15' => '',
]);

$plansubmission = PlanSubmission::find($id);
//$plansubmission->update($data);

$designs = MedicalDesignsToQuote::find($id);

if($designs==null){
  $design = MedicalDesignsToQuote::create(['id'=>$id]);
  $design->update($data);
}
else{
  $designs->update($data);

I do not want to use an array for the 'name' attribute

Added this to controller:

$validator = Validator::make($request->all(), [
                    "list.*.id" => '', // Object exist validation 
                    "list.*.value" => '',
                    'current' => '',
                    'instructions' => '',
                ]);

$bodyContent = $request->getContent($validator);

$plansubmission = PlanSubmission::find($id);
// $plansubmission->update($data);

$designs = MedicalDesignsToQuote::find($id);

if($designs==null){
  $design = MedicalDesignsToQuote::create(['id'=>$id]);
  // $design->update($data);
  $design->update($validator);
}
else{
  $designs->update($validator);
}

I have the following columns in my table:

id
current
instructions
Plan 1
Plan 2
Plan 3
Plan 4
Plan 5
.....
Plan 50

The user can select any or all of the 50 plan options with a checkbox. If, for example, Plan 5 is selected, the value for this given row within the table will be 'True' for plan 5.

So, to persist the data, I would expect I need to do something like this:

$formData = $request->all();

foreach ($formData['list'] as $planData) {
  MedicalPlanDesignToQuote::updateOrCreate(
    [$planData['id']] => $planData['value']],
  );
}

If I had two columns called id and value, I suppose I could do this:

foreach ($formData['list'] as $planData) {
  MedicalPlanDesignToQuote::updateOrCreate(
    ['id' => $planData['id']],
    ['value' => $planData['value']]
  );
}

Is there anyway I can do this with my table structure?

4
  • what validation you required, at lease one tobe selected? Commented Jan 14, 2020 at 13:18
  • What is your plan column named? right now it seems like you have a space in that. Commented Jan 14, 2020 at 13:19
  • The plan column names are Plan 1, Plan 2, Plan 3.....Plan 15 Commented Jan 14, 2020 at 13:36
  • I think if you move Plan 1, Plan 2 Plan 3 into an array plans => [0 => data, 1 => data], you will have easier way to loop them. And if you don't want plans have more than 15 items, you can just validate the plans with 'array|max:15'. Commented Jan 17, 2020 at 1:34

2 Answers 2

4
+50

First things first:

You have an error in your example. The @endforeach needs to be moved one column down.

Second:

You need to understand, what you are exactly doing here. You deal with an 1-n relationship between some kind of list and the list items. Ergo, you need to build your post/get body accordingly.

An example for a single table row could be:

<tr>
  <td>
    <Input type="hidden" value="{{$plan->{'Plan ID'} }}" name="list[][id]">
    <Input type="checkbox" value="true" name="list[][value]">
  </td>
  <td>
    {{$plan->{'Plan ID'} }}
  </td>
</tr>

Now you are able to iterate over items accordingly, independent from their id.

Now you are able to use request validation as stated here: https://laravel.com/docs/master/validation#validating-arrays

In our case:

"list.*.id" => "...", // Object exist validation 
"list.*.value" => "..."

Now how to pass everything to objects and persist them:

You need to be aware, you can't just pass anything into your objects. Right now you pass a validator. Instead use the validation only vor validation. Laravel will take care of returning a response.

$this->validate($request, [
  'current' => required'',
  'instructions' => 'required',
  "list.*.id" => "required", // Object exist validation 
  "list.*.value" => "required"
]);

Afterwards you get your data from your request object:

$formData = $request->all();

We stored our information in the key 'list' (see html). So you will find it in your request object. There are multiple "plans" stored in our list. Now you need to iterate:

foreach ($formData['list'] as $planData) {
   Plan::updateOrCreate(
       ['id' => $planData['id']],
       ['value' => $planData['value']]
   );
}

Of course you need to also save other objects/create relationships if there are any.

If you want to stay with your table structure (you may should rework it: keyword BCNF), you are still able/need to iterate:

$dataArray = [];

foreach ($formData['list'] as $planData) {
   $dataArray['Plan ' . $planData['id']] = $planData['value'];
}

$dataArray['current'] = $formData['current'];
$dataArray['instructions'] = $formData['instructions'];

// This way do not need to use create
$designs = MedicalDesignsToQuote::updateOrCreate(
    ['id' => $id],
    $dataArray
);

Sign up to request clarification or add additional context in comments.

8 Comments

thanks, i think i'm almost there but now getting this error message: Argument 1 passed to Illuminate\Database\Eloquent\Model::update() must be of the type array, object given, called in . I read thru the Laravel documentation and can't figure out what I'm doing wrong. I'll include what I put in my controller
Your are not able to simply pass the validation into the object. It has an other structure now. You need to rearrange it.
You also can't use ... in der validation string of the controller. Please take a look here how to use validation laravel.com/docs/master/validation (exp. Required|string)
Use $bodyContent = $request->getContent(); to access your the form data. There should be a key 'list' over which you can iterate, create plan objects, set values and create relationships between your objects
Sorry, I guess I just do not understand the concepts here. I am lost. I revised the validation string. Now I see that goes into an object called $validator. But, I have no idea how to get that $validator object into an array where I can then pass this on to my database
|
0

You need to create an Option Group and Option tables to handle all your lists.

For example, you need a Location List and a Restaurant List.

Add a parent of Location List in Option Group and the child in Option and join them in Option.php to handle all your list in the future.

public static function getOfficeLocationList(){
    return Option::where('group_id', config('constants.OPT_GROUP_OFFICE_LOC'))->orderBy('name','ASC')->get();
}

In my example, group_id is the ID of the parent list, in that way you can get all the location option you stored.

In your controller:

 $locationList = Option::getOfficeLocationList();

In your blade:

@foreach($locationList as $item)
    your input checkbox with $item->name and $item->id
@endforeach

That's it: Throw the formData in your validation :)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.