0

I'm working with the Laravel framework, using eloquent for interacting with my database.

I have a form which I post to my controller. This form has 'tags' which are added by the user. The user can add as many tags as they want.

I want to POST the tags and then in my controller, insert each tag to a new table row, like so:

        $tag = new Tag;
        $tag->user_id   = Input::get('user_id');
        $tag->tag_name = Input::get('tag_name');
        $tag->save();

How would I handle this? At first I thought put each tag into an array, POST the array, then in the controller i'd cycle through each element, inserting them into the database.

See the code here, this was actually a previous stack overflow question

But after some searching around I came to the conclusion that you cannot POST an array.

So the other way is to POST each array value as a hidden form type. The problem lies in how to tell my controller how many tags (and therefor rows) there are to insert.

I hope this is clear enough, thanks in advance.


EDIT: still having some trouble

EDIT 2: changed code to include 'i' variable in javascript and what the new array looks like when POSTed.

This is what the user generated input tag looks like

$("#tagsbox")
        .append("<div class='displaytag'><i>"+tag+"</i><input type='hidden' name='tags["+i+"]["+user_id+"]' value="+user_id+"><input type='hidden' name='tags["+i+"]["+tag+"]'value="+tag+">")

This is what the POST data looks like after submission

Array
(
[user_id] => 12
[lat] => 50.80589
[lng] => -0.02784
[spot_name] => test spot
[tags] => Array
    (
        [1] => Array
            (
                [12] => 12
                [tag1] => tag1
            )

        [2] => Array
            (
                [12] => 12
                [tag2] => tag2
            )

        [3] => Array
            (
                [12] => 12
                [tag3] => tag3
            )

    )

[location_notes] => some notes
[comments] => some comments
[_token] => Cfsx56FZiEKcVz76mkcZvuBtVG7JQSmdJUffFMfM

)

Controller stayed the same

            //dynamic tags
        $tags = Input::get('tags');
        foreach ((array) $tags as $tagData)
        {
           // validate user_id and tag_name first
           $tag = Tag::create(array_only($tagData, ['user_id', 'tag_name']));
        }

        //create spot
        $spot = new Spot;
        $spot->user_id          = Input::get('user_id');
        $spot->latitude         = Input::get('lat');
        $spot->longitude        = Input::get('lng');
        $spot->spot_name        = Input::get('spot_name');
        $spot->location_notes   = Input::get('location_notes');
        $spot->comments         = Input::get('comments');
        $spot->save();

        return Redirect::route('home')
                        ->with('global', 'Spot successfully tagged. You can edit all your spots on your profile.');

I still manage to get empty values in my database rows where there should be tags. Where am I going wrong?

Community
  • 1
  • 1
bjurtown
  • 163
  • 4
  • 13
  • 1
    why can you not [POST an array?](http://stackoverflow.com/q/9073690/697370) – Jeff Lambert Sep 08 '14 at 20:11
  • just loop `Input::all()`? That should work –  Sep 08 '14 at 20:11
  • @Allendar well, the Input comes with more data. For example: There will only be one user and comment input, yet there could be one, three, ten - any number of tags. I can't really picture how looping through all will work. (apologies for crappy formatting) – bjurtown Sep 08 '14 at 20:19
  • Why not do the loop on all post fields and concat and check for truth? `if (Input::get('comment'.$i)) { ... }` until you've found them all? :) If you're uncertain about the range, you will have to cap it somewhere on a certain loop count tho. –  Sep 08 '14 at 20:24
  • cheers @watcher, that's a really helpful link, i'll be using this method! – bjurtown Sep 08 '14 at 21:01

2 Answers2

5

You can send it as an array:

<input name="tags["+i+"][user_id]"><input name="tags["+i+"][tag_name]">
...
<input name="tags["+i+"][user_id]"><input name="tags["+i+"][tag_name]">

then server side:

$tags = Input::get('tags');
foreach ((array) $tags as $tagData)
{
   // validate user_id and tag_name first
   $tag = Tag::create(array_only($tagData, ['user_id', 'tag_name']));
}
Jarek Tkaczyk
  • 78,987
  • 25
  • 159
  • 157
  • Thanks, I don't know why I didn't come across this method when searching but it's pretty nifty. @watcher actually suggested this before but you took the time out to write as an answer rather than comment haha. Thanks again! – bjurtown Sep 08 '14 at 21:00
  • Hah, just like @watcher did in another question minutes earlier ;) Glad I could help you anyway. – Jarek Tkaczyk Sep 08 '14 at 21:11
  • I'm still having some trouble, could you have a look at the edit for me please? – bjurtown Sep 09 '14 at 10:23
  • 1
    +1 :) @bjurtown Your generated input name has a key of `array` which is unnecessary. Check the name of the input and try changing it to `tags[][tag_name]` from `tags[array][tag_name]` – Jeff Lambert Sep 09 '14 at 10:26
  • i changed it like you said and my row insert is still empty. Also there is only one row inserted into the database even though i made three tags. I've tried fiddling around with the array syntax but nothing has worked for me, I reckon it's something silly i'm not doing. – bjurtown Sep 09 '14 at 10:56
  • 1
    Well, obviously! I forgot about js var (array index you need to apply for each new tag). Check the edit, it will work in the loop, if it's dynamically added, then just update that number when adding new inputs – Jarek Tkaczyk Sep 09 '14 at 11:08
  • @JarekTkaczyk I feel like we're getting closer to a solution but unfortunately my rows are still being populated with empty data. I've updated the code and what the array looks like. Sorry for being such a pain – bjurtown Sep 09 '14 at 14:01
  • Do you set and increment `i` variable? – Jarek Tkaczyk Sep 09 '14 at 14:51
  • @JarekTkaczyk Yep, set it globally like so: window.i=0; – bjurtown Sep 09 '14 at 15:00
  • @JarekTkaczyk it's sorted, mjconnor spotted that I wasn't putting in the array keys being referenced in the controller. My fault for not spotting it – bjurtown Sep 09 '14 at 15:15
1

I am really new at using Laravel, and might be wrong here, but when you using array_only()

    $tags = Input::get('tags');
    foreach ((array) $tags as $tagData)
    {
       // validate user_id and tag_name first
       $tag = Tag::create(array_only($tagData, ['user_id', 'tag_name']));
    }

I don't see 'tag_name' or 'user_id' keys in your POST data tags array.

mjoconnor
  • 13
  • 2