Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Save multiple rows to database from dynamic forms in Laravel 5

I'm using jQuery to generate two dynamic fields. Each pair of fields is displayed on the page and can have multiple instances. On submit (not ajax), each pair of fields is saved into the their own table row along with Auth::id().

There are two forms in the HTML code, both values are entered, user clicks 'Add link' then jQuery creates two hidden fields (these are the ones that get submitted) and data entered appears (appended) visually to #link-list. The original fields become empty and the process can repeat...

I'm struggling to create an array that is recognised by eloquent to save the data multiple times.

I get the error 'Undefined index: link' or whichever the second input row is in jQuery.

Blade/HTML:

{!! Form::open(['route' => ['multiple.store'], 'method' => 'post', 'role'=> 'form', 'class' => 'form']) !!}

    <ul id="link-list">
        <!-- append new rows -->
    </ul>

    <div id="newlink" class="form-inline">
        <div class="form-group">
            {!! Form::text('prestore', null, ['placeholder' => 'Store name', 'class' => 'form-control']) !!}
        </div>
        <div class="form-group">
            {!! Form::text('prelink', null, ['placeholder' => 'Link / URL', 'class' => 'form-control']) !!}
        </div>
        <div class="form-group">
            <button class="btn btn-primary submit new-row" type="button">Add store link</button>
        </div>
    </div>

    <br/><br/>

    {!! Form::submit('Submit rows', ['class' => 'btn btn-success submit']) !!}

{!! Form::close() !!}

jQuery/JavaScript

$(document).on('click', '.new-row', function() {
    var store = $('#newlink input[name=prestore]').val();
    var link = $('#newlink input[name=prelink]').val();
    console.log(store, link);
    $('<li class="not-saved">' +
            '<a href="'+link+'">'+store+'</a>' +
            '<input type="hidden" name="rows[][link]" value="' + link + '">' +
            '<input type="hidden" name="rows[][store]" value="' + store + '">' +
        '</li>').appendTo('#link-list').hide().fadeIn(280);
    $('input[name=prestore]').val('');
    $('input[name=prelink]').val('');
});

Controller:

public function store()
{
    $input = Input::all();

    foreach ($input['rows'] as $row) {
        $items = new Multiple([
            'user_id' => Auth::id(),
            'store' => $row['store'],
            'link' => $row['link'],
        ]);
        $items->save();
    }
}
like image 891
Jack Barham Avatar asked Jul 25 '15 17:07

Jack Barham


1 Answers

One problem is in your JavaScript element names:

<input type="hidden" name="rows[][link]" value="' + link + '">
<input type="hidden" name="rows[][store]" value="' + store + '">

This will generate $rows like:

[
    0 => ["link" => "foo"], 
    1 => ["store" => "bar"]
]

But your PHP code expects $rows to be like:

[
    0 => [
        "link" => "foo",
        "store" => "bar"
    ], 
    1 => [
        "link" => "foo",
        "store" => "bar"
    ]
]

One way to generate the expected values is to specify the row keys in your elements:

<input type="hidden" name="rows[0][link]" value="' + link + '">
<input type="hidden" name="rows[0][store]" value="' + store + '">
<input type="hidden" name="rows[1][link]" value="' + link + '">
<input type="hidden" name="rows[1][store]" value="' + store + '">

Obviously this is a bit tricky given the code you've provided, so let me know if you need assistance with that.

like image 142
Ben Claar Avatar answered Oct 21 '22 22:10

Ben Claar