-
-
Notifications
You must be signed in to change notification settings - Fork 86
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
New: Spatie Tags field Livewire component (docs coming)
New: Add support for array field updated(), method naming, (not supported in Livewire by default) New: method fillField() Example use: emitted Event in frontend via AlpineJS or from other Livewire component Fix: field inline property for labels Fix: default value in field, mixed type instead of string Fix: urlencode previous url to comply with :portnumbers Change: set model in create-component stub for conditional fields
- Loading branch information
1 parent
b53dc81
commit c19ecc4
Showing
13 changed files
with
210 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
<x-tall-field-wrapper align="items-center" :inline="$field->inline" :field="$field->name" :label="$field->label" :labelW="$field->labelW" :fieldW="$field->fieldW"> | ||
<x-tall-field-wrapper align="items-center" :inline="$field->inline ?? $inline" :field="$field->name" :label="$field->label" :labelW="$field->labelW" :fieldW="$field->fieldW"> | ||
<x-tall-checkbox :field="$field->key" :id="$field->name" | ||
:label="$field->placeholder ?? $field->label" :help="$field->help" :errorMsg="$field->errorMsg" /> | ||
</x-tall-field-wrapper> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
<x-tall-field-wrapper :inline="$field->inline ?? $inline" :field="$field->name" :label="$field->label" :labelW="$field->labelW" :fieldW="$field->fieldW"> | ||
@livewire('tall-tags', [ | ||
'model' => $model, | ||
'tagType' => $field->tagType, | ||
'field' => $field->name, | ||
'tags' => data_get($form_data, $field->name), | ||
'help' =>$field->help, | ||
'errorMsg' => $field->errorMsg | ||
]) | ||
</x-tall-field-wrapper> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
<div class="bg-grey-lighter w-full"> | ||
@error('search')<p class="error">@lang('fields.tag_error')</p>@enderror | ||
@error($field)<p class="error">{{ $errorMsg ?? $message }}</p>@enderror | ||
<div class="flex flex-1 flex-wrap bg-white border rounded shadow-sm pl-2 pr-4 pt-2 pb-1"> | ||
@foreach ($tags as $i => $tag) | ||
<span | ||
class="tags-input-tag inline-flex leading-4 items-center text-sm bg-blue-300 text-blue-800 rounded py-1 px-2 mr-2 mb-1" | ||
style="user-select: none"> | ||
<span>{{ $tag }}</span> | ||
<button wire:click="removeTag({{$i}})" type="button" | ||
class="pl-1 tags-input-remove text-gray-500 text-lg leading-4 focus:outline-none"> | ||
× | ||
</button> | ||
</span> | ||
@endforeach | ||
<input autofocus wire:model.debounce.500ms="search" wire:keydown.enter.prevent="addFromSearch" name="search" | ||
class="tags-input-text flex-1 outline-none pt-1 pb-1 ml-2" | ||
style="min-width:10rem" placeholder="Add tag..."> | ||
</div> | ||
@if($help)<p class="help py-1">{{ $help }}</p>@endif | ||
<div class="flex items-center py-2"> | ||
@foreach($options as $option) | ||
<button wire:click.prevent="addFromOptions('{{$option}}')" type="button"> | ||
<span class="bg-blue-100 text-blue-800 inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium leading-4 whitespace-no-wrap"> | ||
{{ $option ?? null }} | ||
</span> | ||
</button> | ||
@endforeach | ||
</div> | ||
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
<?php | ||
|
||
namespace Tanthammar\TallForms; | ||
|
||
use Illuminate\Database\Eloquent\Model; | ||
use Illuminate\Support\Str; | ||
use Livewire\Component; | ||
use Spatie\Tags\Tag; | ||
|
||
class TagsField extends Component | ||
{ | ||
|
||
public $model; | ||
public $type; | ||
public $tags; | ||
public $search = ""; | ||
public $options = []; | ||
public $field; | ||
public $help; | ||
public $errorMsg; | ||
|
||
public function mount(string $field, string $tagType = null, Model $model = null, string $tags = null, string $help = null, string $errorMsg = null) | ||
{ | ||
$this->model = $model; | ||
$this->type = $tagType; | ||
$this->tags = filled($this->model) | ||
? $this->getExisting() | ||
: (filled($tags) | ||
? explode(",", $tags) | ||
: [] | ||
); | ||
$this->field = $field; | ||
$this->help = $help; | ||
$this->errorMsg = $errorMsg; | ||
} | ||
|
||
public function getExisting() | ||
{ | ||
$query = filled($this->type) ? $this->model->tagsWithType($this->type) : $this->model->tags; | ||
clock($this->type); | ||
return array_filter( | ||
$query->pluck('name')->unique()->toArray() | ||
); | ||
} | ||
|
||
public function getRules() | ||
{ | ||
return ['search' => 'nullable|string|between:3,40']; | ||
} | ||
|
||
public function updatedSearch() | ||
{ | ||
$slug = Str::slug($this->search, '-'); | ||
if (filled($slug)) { | ||
$this->options = array_filter( | ||
Tag::where("slug", 'like', '%' . $slug . '%') | ||
->where('type', $this->type) | ||
->orderBy("name", 'asc') | ||
->take(10) | ||
->pluck('name') | ||
->unique() | ||
->toArray() | ||
); | ||
} | ||
} | ||
|
||
public function syncTags() | ||
{ | ||
$cleaned = collect(array_sort($this->tags))->unique()->toArray(); | ||
filled($this->model) | ||
? (filled($this->type) ? $this->model->syncTagsWithType($cleaned, $this->type) : $this->model->syncTags($cleaned)) | ||
: $this->emitUp('fillField', [ | ||
'field' => $this->field, | ||
'value' => implode(",", $cleaned) | ||
]); | ||
$this->tags = $cleaned; | ||
$this->search = ""; | ||
|
||
//$this->notify(); | ||
} | ||
|
||
public function addTag($tag) | ||
{ | ||
$tag = Str::of($tag)->trim()->trim(",")->title()->__toString(); | ||
if (!in_array($tag, $this->tags)) { | ||
array_push($this->tags, $tag); | ||
} | ||
$this->syncTags(); | ||
} | ||
|
||
public function removeTag(int $i): void | ||
{ | ||
unset($this->tags[$i]); | ||
$this->search = ""; | ||
//$this->tags = array_values($this->tags); | ||
$this->syncTags(); | ||
} | ||
|
||
public function addFromSearch() | ||
{ | ||
$this->validate($this->getRules()); | ||
$this->addTag($this->search); | ||
$this->search = ""; | ||
} | ||
|
||
public function addFromOptions($option) | ||
{ | ||
//validate that the option has not been modified in frontend | ||
if (in_array($option, $this->options)) { | ||
$this->addTag($option); | ||
} | ||
$this->search = ""; | ||
} | ||
|
||
public function render() | ||
{ | ||
return view('tall-forms::livewire.tags'); | ||
} | ||
} |