nova-multiselect-field icon indicating copy to clipboard operation
nova-multiselect-field copied to clipboard

Recipe: use with spatie/laravel-tags

Open cord opened this issue 3 years ago • 0 comments

UseCase: only pre-defined tags should be selectable no dynamic creation of tags should be possible as with https://novapackages.com/packages/spatie/nova-tags-field


// define type to select from

            $tagType = 'myType';

//(...)

            Multiselect::make(__("Tags"), 'tags')
                ->options(function () use ($tagType) {
                    $query = resolve(config('tags.tag_model', Tag::class))->query();

                    $filter_containing = null;
                    $filter_type = $tagType;
                    $limit = null;

                    if ($filter_containing) {
                        $query->containing($filter_containing);
                    }

                    if ($filter_type) {
                        $query->where('type', $filter_type);
                    }

                    if ($limit) {
                        $query->limit($limit);
                    }

                    $sorted = $query->get()->sortBy(function (Tag $tag) {
                        return strtolower($tag->name);
                    })->values();

                    $tags = $sorted->mapWithKeys(function (Tag $tag, $key) {
                        return [$tag->name => $tag->name];
                    });
                    return $tags;
                })
                ->resolveUsing(function ($tags) {
                    return $tags->pluck('name');
                })
                ->fillUsing(function ($request, $model, $attribute, $requestAttribute) use ($tagType) {
                    $requestValue = $request[$requestAttribute];

                    $tagNames = array_values($requestValue ?? []);
                    $tagNames = array_filter($tagNames); // remove empty values

                    $class = get_class($model);
                    $class::saved(function ($model) use ($tagNames) {
                        $model->syncTagsWithType($tagNames, $tagType ?? null);
                    });
                })
                ->placeholder(__('Add Tags')) // Placeholder text

cord avatar Oct 05 '21 12:10 cord