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?

5
  • 1
    why can you not POST an array? Commented Sep 8, 2014 at 20:11
  • just loop Input::all()? That should work Commented Sep 8, 2014 at 20:11
  • @Allendar well, the Input comes with more data. For example: <input blah blah name="user"> <input blah blah name="comment"> <input DYNAMIC name="tag"> <input DYNAMIC name="tag"> 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) Commented Sep 8, 2014 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. Commented Sep 8, 2014 at 20:24
  • cheers @watcher, that's a really helpful link, i'll be using this method! Commented Sep 8, 2014 at 21:01

2 Answers 2

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']));
}
Sign up to request clarification or add additional context in comments.

10 Comments

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!
Hah, just like @watcher did in another question minutes earlier ;) Glad I could help you anyway.
I'm still having some trouble, could you have a look at the edit for me please?
+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]
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
|
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.

2 Comments

mega face-palm. Yeah that's it, the tags are now populating the database. Thanks so much
No problem! I only spotted it because I do that sort of thing all the time.

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.