Skip to content

Commit

Permalink
bootstrap 4 support
Browse files Browse the repository at this point in the history
  • Loading branch information
lekoala committed Nov 18, 2021
1 parent ea88336 commit ec468ec
Show file tree
Hide file tree
Showing 6 changed files with 146 additions and 22 deletions.
96 changes: 96 additions & 0 deletions demo-bs4.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
<!DOCTYPE html>
<html lang="en" class="no-js">

<head>
<title>Bootstrap 4 tags demo</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@4/dist/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/jquery@3/dist/jquery.min.js" type="module"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4/dist/js/bootstrap.bundle.min.js" type="module"></script>
<script type="module">
import Tags from "./tags.min.js";
Tags.init();
</script>
</head>

<body>
<div class="container">
<h1>Demo</h1>
<form class="needs-validation" novalidate method="get" action="https://vercel-dumper.vercel.app/">
<div class="row mb-3 g-3">
<div class="col-md-4 form-group">
<label for="validationTags" class="form-label">Tags</label>
<select class="form-control" id="validationTags" name="tags[]" multiple>
<option disabled hidden value="">Choose a tag...</option>
<option value="1" selected="selected">Apple</option>
<option value="2">Banana</option>
<option value="3">Orange</option>
</select>
<div class="invalid-feedback">Please select a valid tag.</div>
</div>
</div>
<div class="row mb-3 g-3">
<div class="col-md-4 form-group">
<label for="validationTagsClear" class="form-label">Tags (allow clear)</label>
<select class="form-control" id="validationTagsClear" name="tagsClear[]" multiple data-allow-clear="true">
<option disabled hidden value="">Choose a tag...</option>
<option value="1" selected="selected">Apple</option>
<option value="2">Banana</option>
<option value="3">Orange</option>
</select>
<div class="invalid-feedback">Please select a valid tag.</div>
</div>
</div>
<div class="row mb-3 g-3">
<div class="col-md-4 form-group">
<label for="validationTagsThreshold" class="form-label">Tags (allow clear + 0 threshold)</label>
<select class="form-control" id="validationTagsThreshold" name="tagsClearThreshold[]" multiple data-allow-clear="true" data-suggestions-threshold="0">
<option disabled hidden value="">Choose a tag...</option>
<option value="1" selected="selected">Apple</option>
<option value="2">Banana</option>
<option value="3">Orange</option>
</select>
<div class="invalid-feedback">Please select a valid tag.</div>
</div>
</div>
<div class="row mb-3 g-3">
<div class="col-md-4 form-group">
<label for="validationTagsShow" class="form-label">Tags (show all)</label>
<select class="form-control" id="validationTagsShow" name="tags_show[]" multiple data-show-all-suggestions="true">
<option disabled hidden value="">Choose a tag...</option>
<option value="1" selected="selected">Apple</option>
<option value="2">Banana</option>
<option value="3">Orange</option>
<option value="4">Blueberry</option>
<option value="5">Strawberry</option>
<option value="6">Cranberry</option>
<option value="7">Huckleberry</option>
<option value="8">Chokeberry</option>
<option value="9">Elderberry</option>
<option value="10">Gooseberry</option>
<option value="11">Blackberry</option>
<option value="12">Raspberry</option>
<option value="13">Goji berry</option>
<option value="14">Salmon berry</option>
<option value="15">Sumac berry</option>
</select>
<div class="invalid-feedback">Please select a valid tag.</div>
</div>
</div>
<div class="row mb-3 g-3">
<div class="col-md-4 form-group">
<label for="validationTagsNew" class="form-label">Tags (allow new)</label>
<select class="form-control" id="validationTagsNew" name="tags_new[]" multiple data-allow-new="true">
<option disabled hidden value="">Choose a tag...</option>
<option value="1" selected="selected">Apple</option>
<option value="2">Banana</option>
<option value="3">Orange</option>
</select>
<div class="invalid-feedback">Please select a valid tag.</div>
</div>
</div>
<button class="btn btn-primary" type="submit">Submit form</button>
</form>
</div>
</body>

</html>
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "bootstrap5-tags",
"version": "1.1.6",
"version": "1.2.0",
"description": "Replace select[multiple] with nices badges",
"main": "tags",
"scripts": {
Expand All @@ -19,6 +19,7 @@
"select",
"bootstrap",
"bootstrap5",
"bootstrap4",
"es6"
],
"author": "LeKoala",
Expand Down
11 changes: 9 additions & 2 deletions readme.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# bootstrap5-tags
# Tags for Bootstrap 4/5

[![NPM](https://nodei.co/npm/bootstrap5-tags.png?mini=true)](https://nodei.co/npm/bootstrap5-tags/)
[![Downloads](https://img.shields.io/npm/dt/bootstrap5-tags.svg)](https://www.npmjs.com/package/bootstrap5-tags)

## How to use

An ES6 native replacement for `select` using standards Bootstrap 5 styles.
An ES6 native replacement for `select` using standards Bootstrap 5 (and 4) styles.

No additional CSS needed! Supports creation of new tags.

Expand Down Expand Up @@ -69,6 +69,13 @@ You can set accessibility labels when passing options:
- Use arrow down to show dropdown (and arrow up to hide it)
- If you have a really long list of options, a scrollbar will be used

## Bootstrap 4 support

Even if it was not the initial idea to support Bootstrap 4, this component is now compatible with Bootstrap 4 because it only
requires minimal changes.

Check out demo-bs4.html

## Demo

https://codepen.io/lekoalabe/pen/ExWYEqx
Expand Down
52 changes: 36 additions & 16 deletions tags.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Bootstrap 5 tags
* Bootstrap 5 (and 4!) tags
*
* Turns your select[multiple] into nice tags lists
*
Expand All @@ -26,16 +26,16 @@ class Tags {
this.placeholder = this.getPlaceholder();
this.allowNew = selectElement.dataset.allowNew ? true : false;
this.showAllSuggestions = selectElement.dataset.showAllSuggestions ? true : false;
this.badgeStyle= selectElement.dataset.badgeStyle ?? "info";
this.badgeStyle = selectElement.dataset.badgeStyle ?? "primary";
this.allowClear = selectElement.dataset.allowClear ? true : false;
this.suggestionsThreshold = selectElement.dataset.suggestionsThreshold ? parseInt(selectElement.dataset.suggestionsThreshold) : 1;
this.keyboardNavigation = false;
this.clearLabel = opts.clearLabel ?? "Clear";
this.searchLabel = opts.searchLabel ?? "Type a value";

// Create elements
this.holderElement = document.createElement("div");
this.containerElement = document.createElement("div");
this.holderElement = document.createElement("div"); // this is the one holding the fake input and the dropmenu
this.containerElement = document.createElement("div"); // this is the one for the fake input (labels + input)
this.dropElement = document.createElement("ul");
this.searchInput = document.createElement("input");

Expand Down Expand Up @@ -103,6 +103,10 @@ class Tags {
configureHolderElement() {
this.holderElement.classList.add("form-control");
this.holderElement.classList.add("dropdown");
if (this.getBootstrapVersion() === 4) {
// Prevent fixed height due to form-control
this.holderElement.style.height = "auto";
}
}

configureContainerElement() {
Expand Down Expand Up @@ -432,6 +436,18 @@ class Tags {
this.removeItem(lastItem.getAttribute(VALUE_ATTRIBUTE));
}

/**
* @returns {Number}
*/
getBootstrapVersion() {
let ver = 5;
// If we have jQuery and the tooltip plugin for BS4
if (window.jQuery && $.fn.tooltip != undefined && $.fn.tooltip.Constructor != undefined) {
ver = parseInt($.fn.tooltip.Constructor.VERSION.charAt(0));
}
return ver;
}

/**
* @param {string} text
* @param {string} value
Expand All @@ -443,6 +459,8 @@ class Tags {
value = text;
}

const bver = this.getBootstrapVersion();

// Find by label and value
let opt = this.selectElement.querySelector('option[value="' + value + '"]');
if (!opt) {
Expand All @@ -454,25 +472,27 @@ class Tags {
}
}

//Check Bootstrap Version
var bver = "5";
if ($.fn.tooltip != undefined && $.fn.tooltip.Constructor != undefined) {
var ver = $.fn.tooltip.Constructor.VERSION;
bver = ver.charAt(0);
}


// create span
let html = text;
let span = document.createElement("span");
span.classList.add("badge");
span.classList.add("badge-"+this.badgeStyle);
span.classList.add(bver === 5 ? "me-2" : "mr-2");
if (bver === 5) {
//https://getbootstrap.com/docs/5.1/components/badge/
span.classList.add("bg-" + this.badgeStyle);
span.classList.add("me-2");
} else {
// https://getbootstrap.com/docs/4.6/components/badge/
span.classList.add("badge-" + this.badgeStyle);
span.classList.add("mr-2");
}
span.setAttribute(VALUE_ATTRIBUTE, value);

if (this.allowClear) {
var btn = bver === "5" ? '<button type="button" style="font-size:0.65em" class="me-2 btn-close btn-close-white" aria-label="' + this.clearLabel + '"></button>' : '<button type="button" style="font-size:0.65em; padding:0rem !important" class="mr-2 btn btn-sm" aria-label="' + this.clearLabel + '"><i class="fa fa-times"></i></button>';
html = btn + html;
const btn =
bver === 5
? '<button type="button" style="font-size:0.65em" class="me-2 btn-close btn-close-white" aria-label="' + this.clearLabel + '"></button>'
: '<button type="button" style="font-size:1em;float:left;text-shadow:none;color:currentColor;" class="mr-2 close" aria-label="' + this.clearLabel + '"><span aria-hidden="true">&times;</span></button>';
html = btn + html;
}

span.innerHTML = html;
Expand Down
Loading

0 comments on commit ec468ec

Please sign in to comment.