Skip to content

Instantly share code, notes, and snippets.

@JunaidQadirB
Last active August 29, 2022 14:48
Show Gist options
  • Save JunaidQadirB/90690025bf04ec89a831386611c81d25 to your computer and use it in GitHub Desktop.
Save JunaidQadirB/90690025bf04ec89a831386611c81d25 to your computer and use it in GitHub Desktop.
Extended version of Tags example. Implemented using Bootstrap5

This is an extended version of the tags example in the alpine.js repository with `Bootstrap5. My implementation is a bit comprehensive with the following features:

  • It doen't allow duplicate tags
  • Adding duplicate tag would throw a nice error
  • All tags can be cleared at once
  • It will prompt when clearing all tags

Demo

Here's the demo https://imgur.com/KGf95Fa

<html>
<head>
<meta charset="utf-8"/>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta2/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-BmbxuPwQa2lc/FVzBcNJ7UAyJxM6wuqIj61tLrc4wSX0szH/Ev+nYRRuWlolflfl" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine.min.js" defer></script>
</head>
<body>
<div class="row">
<div class="col-12 col-md-6 mx-auto">
<div x-data="Tags()" class="p-3" style="background-color: #e5e5e5">
<template x-for="tag in tags">
<input type="hidden" name="tags[]" :value="tag">
</template>
<div class="form-control">
<div class="bg-white">
<template x-for="tag in tags" :key="tag">
<span class="badge p-1 me-1 my-1 bg-primary text-white">
<span x-text="tag"></span>
<span type="button" class="btn btn-sm p-0 m-0 text-white"
@click="remove(tag)">&times;</span>
</span>
</template>
<input class="border-0 w-auto bg-transparent" style="outline: none;"
placeholder="Add tag..."
@keydown.enter.prevent="add($event)"
@keydown.backspace="removeLast"
x-model="newTag"
/>
<button type="button" class="btn btn-sm btn-danger m-0"
@click="removeAllPrompt=true" x-show="tags.length>0 && !removeAllPrompt">
Remove All
</button>
<div class="btn-toolbar" :class="removeAllPrompt ? 'd-inline-block' : 'd-none' " role="toolbar"
aria-label=""
x-cloak
>
<div class="btn-group btn-group-sm" role="group" aria-label="">
<div class="input-group-text" id="btnGroupAddon">CLear all tags?</div>
<button type="button" class="btn btn-outline-success"
@click="removeAllPrompt=false">No
</button>
<button type="button" class="btn btn-outline-danger"
@click="removeAll">Yes
</button>
</div>
</div>
</div>
</div>
<small class="form-text text-danger" id="tagsHelp"
x-html="error"
></small>
</div>
</div>
</div>
<script>
let Tags = function () {
return {
newTag: '',
tags: [],
error: '',
removeAllPrompt: false,
add(event) {
let newTag = event.target.value;
if (newTag.trim() === ''){
this.error = 'Please enter a tag.';
return;
}
if (!this.tags.includes(newTag)) {
this.error = '';
this.tags.push(newTag.trim());
} else {
this.error = `The tag <strong>${this.newTag}</strong> aready exists.`;
}
this.newTag = ''
this.removeAllPrompt = false;
},
removeLast(event) {
let newTag = event.target.value;
if (newTag.trim() === '') {
this.tags.pop()
}
this.removeAllPrompt = false;
},
remove(tag) {
this.tags = this.tags.filter(i => i !== tag)
this.removeAllPrompt = false;
},
removeAll() {
this.tags = []
this.removeAllPrompt = false;
},
}
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment