ageans
ageans

Reputation: 559

Inserting a two diminsionale array in database from multiple dynamic fields - Laravel

Using Laravel I created a form where dynamically input fields can be added and remove using jQuery.

I am now trying to insert the data into the database, there I encounter a problem. My database exists of two tables; Tasks and issues. The 'issue' table is linked to the tasks table bij task_id. This task_id should be also sent to the database but I can't get it, wright. See my code below.

Thanks for the help.

IssueController.php

public function store(Request $request, Issue $issue, Task $task)
 {
    ## First method
    // foreach($request->issueInfo as $key => $value) {
    //     Issue::create($value);
    // }
    ## Second method
    foreach ($request->issueInfo as $key => $name) {
        dd($name);
        $names[] = [
            'task_id'    => $task->id,
            'issue_name' => $name,
            'issue_time' => $name,
            'issue_date' => $name,
            'issue_type' => $name,
        ];
    }
    Issue::insert($names);
    return back();
}

web.php

Route::post('/tasks/{task}/issues',    'IssueController@store');

show.blade.php

@extends('layout')
@section('content')
<script>
    $(document).ready(function() {
        var i = 1;
        $('.addmore').click(function(){
            i++;
            $('#dynamicFields').append('<div class="form-group"><label for="issue_name">Issue Name</label><select class="form-control" name="issueInfo['+i+'][issue_name]"><option></option><option value="Error">Error</option><option value="Grammer">Grammer</option><option value="Undefined">Undefined</option><option value="Typpo">Typpo</option><option value="No errors">No errors</option></select></div><div class="form-group"><label for="issue_date" class="label">Issue Date</label><input class="form-control" type="date" name="issueInfo['+i+'][issue_date]"></div><div class="form-group"><label for="issue_time" class="label">Issue Time</label><input class="form-control" type="time" name="issueInfo['+i+'][issue_time]" ></div><div class="form-group"><label for="issue_type" class="label">Issue Type</label><select class="form-control" name="issueInfo['+i+'][issue_type]"><option></option><option value="False45">False45</option><option value="False104">False104</option></select></div><div class="form-group"><button type="button" class="btn btn-danger remove-field">Remove</button></div>');
            });
        // Removing fields
        $('#dynamicFields').on('click', '.remove-field', function(){
            $(this).parents('div').remove(); i--;
        })
    });
</script>
<div class="form-group"><label for="issue_name">Name</label></div>
<head>Testing the creation of multiple fields</head>
<form action="/tasks/{{$task->id}}/issues" method="post" >
    @csrf
    <div id="dynamicFields">
        <div class="form-group">
            <label for="issue_name">Issue Name</label>
            <select class="form-control" name="issueInfo[0][issue_name]">
                <option></option>
                <option value="Error">Error</option>
                <option value="Grammer">Grammer</option>
                <option value="Undefined">Undefined</option>
                <option value="Typpo">Typpo</option>
                <option value="No errors">No errors</option>
            </select>
        </div>
        <div class="form-group">
            <label for="issue_date" class="label">Issue Date</label>
            <input class="form-control" type="date" name="issueInfo[0][issue_date]" value="{{old('issue_date')}}">
        </div>
        <div class="form-group">
            <label for="issue_time" class="label">Issue Time</label>
            <input class="form-control" type="time" name="issueInfo[0][issue_time]" value="{{old('issue_time')}}">
        </div>
        <div class="form-group">
            <label for="issue_type" class="label">Issue Type</label>
            <select class="form-control" name="issueInfo[0][issue_type]">
                <option></option>
                <option value="False45">False45</option>
                <option value="False104">False104</option>
            </select>
        </div>
        <div class="form-group">
            <input type="button" name="submit" id="submit" class="btn btn-primary addmore" value="+" />
        </div>
        <div class="form-group">
            <button type="submit" class="btn btn-primary">New Location</button>
        </div>
    </div>
</form>
@endsection
Output when I do dd($names) in my controller
                array:1 [▼
          0 => array:5 [▼
            "task_id" => 1
            "issue_name" => array:4 [▼
              "issue_name" => "Error"
              "issue_date" => null
              "issue_time" => null
              "issue_type" => null
            ]
            "issue_time" => array:4 [▼
              "issue_name" => "Error"
              "issue_date" => null
              "issue_time" => null
              "issue_type" => null
            ]
            "issue_date" => array:4 [▶]
            "issue_type" => array:4 [▶]
          ]
        ]

Here you can find a link to fiddle

Upvotes: 1

Views: 839

Answers (3)

Nemo
Nemo

Reputation: 513

You should try the following. I adapted your code a bit in the fiddle. Instead of pushing everything in the same array, store every element in a separate array. In the fiddle, you find the adapt code. In your controller, you should do the following. You should also remove Issue $issue because you are not using it.

Fiddle

 public function store(Request $request, Task $task)
    {
        //


        foreach ($request->issue_name as $index  => $name) {

            $task->issues()->create([
                'issue_name' => $name,
                'issue_time' => $request->issue_time[$index],
                'issue_date' => $request->issue_date[$index],
                'issue_type' => $request->issue_type[$index]
            ]);

        }


        return back();
    }

To solve your problem with the remove button. Add to your class row for example "remove-this-field". And adapt your javascript code for the removal of the fields to:

$('#dynamicFields').on('click', '.remove-fields', function(){
   $('.remov-this-field').remove(); i--;
})

Upvotes: 1

Erich
Erich

Reputation: 2616

Use built-in Eloquent methods to your advantage. First, define relationships:

class Task
{
    public function issues()
    {
        return $this->hasMany(Issues::class);
    }
{

class Issue
{
    public function task()
    {
        return $this->belongsTo(Task::class);
    }
{

Next, write a good helper method. Note the create() method already takes an array input, so you don't have to foreach through all the array keys:

class Task
{
    ...

    public function addIssue($issue)
    {
        return $this->issues()->create($issue);
    }
}

Controller logic can be simplified, and this is a good opportunity to do some server-side validation:

public function store(Request $request, Task $task)
{
    $attributes = request()->validate([
        // issue validation rules here
    ]);

    $task->addIssue($attributes);

    return back();
}

Upvotes: 1

N. Djokic
N. Djokic

Reputation: 1036

You could try adding hidden field to your form where you should set value of that field to task_id which then will be passed to Controller when you submit form.
I think after that your First method should work properly.

Upvotes: 0

Related Questions