Support the ongoing development of Laravel.io →
Input Database Views
Last updated 2 years ago.
0

I overcome this by implementing tagging: https://select2.github.io/examples.html#tags

0

Yeah, that's definitely good for client side, but what is the best way to handle the new data server side?

0

A simple webapp built in Laravel 5 Fundamentals series uses Select2 to add/create article tags. Watch it from episode 21 and it should answer your question.

0

Xum, I've actually watched all these videos, but he only manually adds the tags into the database using Tinker. Never through the web interface (he never creates one). Even still, I have everything setup for tags, the relationships and the pivot table, and in the interface I can add the tags like that to articles, but if I want to make tags from Select2, I have no backend logic to handle the new tag being created (it throws an error when the tag doesn't exist). That's actually what I was asking for direction on. I was wondering if anyone has ever added the backend logic for adding tags to the database on the fly using Select2, or some other method, and if anyone had a good solution for doing so.

0

Actually, thanks to Jammyman1 in the comments section of those videos, he posted a pretty good solution.

The Select 2 options are:

$('#tag_list').select2({
    placeholder: "Select or add tags",
    tags: true,
    tokenSeparators: [",", " "],
    createTag: function(newTag) {
        return {
            id: 'new:' + newTag.term,
            text: newTag.term + ' (new)'
        };
    }
});

And then I added a new function in the controller and called it:

private function syncTags($article, $request)
{
    if ( ! $request->has('tag_list'))
    {
        $article->tags()->detach();
        return;
    }

    $allTagIds = array();

    foreach ($request->tag_list as $tagId)
    {
        if (substr($tagId, 0, 4) == 'new:')
        {
            $newTag = Tag::create(['name' => substr($tagId, 4)]);
            $allTagIds[] = $newTag->id;
            continue;
        }
        $allTagIds[] = $tagId;
    }

    $article->tags()->sync($allTagIds);
}

It seems to have a few small issues that I'm working through, but so far it's done the trick.

0

Yelldon said:

Actually, thanks to Jammyman1 in the comments section of those videos, he posted a pretty good solution.

The Select 2 options are:

$('#tag_list').select2({
   placeholder: "Select or add tags",
   tags: true,
   tokenSeparators: [",", " "],
   createTag: function(newTag) {
       return {
           id: 'new:' + newTag.term,
           text: newTag.term + ' (new)'
       };
   }
});

And then I added a new function in the controller and called it:

private function syncTags($article, $request)
{
   if ( ! $request->has('tag_list'))
   {
       $article->tags()->detach();
       return;
   }

   $allTagIds = array();

   foreach ($request->tag_list as $tagId)
   {
       if (substr($tagId, 0, 4) == 'new:')
       {
           $newTag = Tag::create(['name' => substr($tagId, 4)]);
           $allTagIds[] = $newTag->id;
           continue;
       }
       $allTagIds[] = $tagId;
   }

   $article->tags()->sync($allTagIds);
}

It seems to have a few small issues that I'm working through, but so far it's done the trick.

Where exactly did you add in the second part of the code? Was it inside the existing articles controller, or where?

0

What if I want to use Select2 plugin as single selection and if validation of new value has-error, how can I put that value at the beginning of the select list, or remain selected when retrieved from request::old('tag_id') to data variable?

Now I get old data like so:

var valueID = '{{ Request::old('place_id') }}';
var valueText = '{{ substr(Request::old('place_id'),4) }}';
....
data: [{ id: valueID, text: valueText }],
...

How can I insert data value first in the select list?

Last updated 8 years ago.
0

Hey guys,

This is my solution, which may help someone looking for it.

I tried the above stuff and it was quite buggy so I thought I'd try something a little different. I have included ->user_id because I want my users to use their own tags, but you can remove that bit and rewrite the checks to Tag::where().

private function syncTags($expense, $tags)
    {
        $fresh = [];
        foreach( $tags as $tag )
        {
            if( Tag::find($tag) )
            {
                $fresh[] = $tag;
            }
            elseif( Auth::User()->tags()->where('name',$tag)->exists() )
            {
                $fresh[] = Auth::User()->tags()->where('name',$tag)->latest()->first()->id;
            }
            else
            {
                $t = new Tag;
                $t->user_id = Auth::Id();
                $t->name = $tag;
                $t->save();
    
                $fresh[] = $t->id;
            }
        }
        $expense->tags()->sync( $fresh );
    }

Step 1: Checks if we've been passed an ID
Step 2: If not, check whether we have been passed a name that we already have
Step 3: Finally, if none of those, make a new one and grab its ID

It may look a little bit messy currently and I'm sure this could be tidied up with someone who knows code better than myself

Last updated 8 years ago.
0

Sign in to participate in this thread!

Eventy

Your banner here too?

Yelldon yelldon Joined 2 Mar 2015

Moderators

We'd like to thank these amazing companies for supporting us

Your logo here?

Laravel.io

The Laravel portal for problem solving, knowledge sharing and community building.

© 2024 Laravel.io - All rights reserved.