Skip to content

Instantly share code, notes, and snippets.

@iammuttaqi
Created November 8, 2023 22:13
Show Gist options
  • Save iammuttaqi/18f715c912a0467a98f2c2389de38263 to your computer and use it in GitHub Desktop.
Save iammuttaqi/18f715c912a0467a98f2c2389de38263 to your computer and use it in GitHub Desktop.
TALL stack tags input (daisy ui as tailwind framework)
<div @tags-update="console.log('tags updated', $event.detail.tags)" x-data>
<div @click.away="clearSearch()" @keydown.escape="clearSearch()" x-data="tagSelect()" x-init="init('parentEl')">
<div @keydown.enter.prevent="addTag(textInput)" class="relative">
<x-input :placeholder="$placeholder" x-model="textInput" x-on:input="search($event.target.value)" x-ref="textInput" />
<div :class="[open ? 'block' : 'hidden']">
<div class="absolute left-0 z-40 mt-2 w-full">
<div class="rounded border border-primary bg-white py-1 text-sm shadow-lg dark:bg-gray-800">
<a class="block cursor-pointer px-4 py-1 text-gray-800 hover:bg-primary hover:text-white" x-on:click.prevent="addTag(textInput)">Add "<span class="font-semibold" x-text="textInput"></span>"</a>
</div>
</div>
</div>
<div class="mt-2">
<template x-for="(tag, index) in tags">
<div class="btn btn-info btn-sm mb-2 mr-2 gap-2">
<span x-text="tag"></span>
<button type="button" x-on:click.prevent="removeTag(index)"><i class="bi bi-x inline-block text-base"></i></button>
</div>
</template>
</div>
</div>
</div>
</div>
@push('scripts')
<script>
function tagSelect() {
return {
open: false,
textInput: '',
tags: @entangle('tags'),
addTag(tag) {
tag = tag.trim()
if (tag != "" && !this.hasTag(tag)) {
this.tags.push(tag)
}
this.clearSearch()
this.$refs.textInput.focus()
this.fireTagsUpdateEvent()
},
fireTagsUpdateEvent() {
this.$el.dispatchEvent(new CustomEvent('tags-update', {
detail: {
tags: this.tags
},
bubbles: true,
}));
},
hasTag(tag) {
var tag = this.tags.find(e => {
return e.toLowerCase() === tag.toLowerCase()
})
return tag != undefined
},
removeTag(index) {
this.tags.splice(index, 1)
this.fireTagsUpdateEvent()
},
search(q) {
if (q.includes(",")) {
q.split(",").forEach(function(val) {
this.addTag(val)
}, this)
}
this.toggleSearch()
},
clearSearch() {
this.textInput = ''
this.toggleSearch()
},
toggleSearch() {
this.open = this.textInput != ''
}
}
}
</script>
@endpush
<?php
namespace App\Http\Livewire\Components;
use Livewire\Attributes\Modelable;
use Livewire\Component;
class Tags extends Component
{
#[Modelable]
public array $tags = [];
public string $label;
public string $placeholder;
public function render()
{
return view('livewire.components.tags');
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment