Update
This commit is contained in:
parent
f7f2c99ee9
commit
a90fdc5562
|
@ -0,0 +1,38 @@
|
|||
################
|
||||
# Stage: Build #
|
||||
################
|
||||
|
||||
FROM python:3.13-slim AS build
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Export poetry dependencies to file
|
||||
RUN pip install --upgrade pip
|
||||
COPY poetry.lock pyproject.toml ./
|
||||
RUN pip install poetry poetry-plugin-export
|
||||
RUN poetry export --without-hashes --format requirements.txt --output /app/requirements.txt
|
||||
|
||||
#####################
|
||||
# Stage: Production #
|
||||
#####################
|
||||
FROM python:3.13-slim AS prod
|
||||
|
||||
# ENV PYTHONPATH=/app
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy requirements from build stage, and install them
|
||||
COPY --from=build /app/requirements.txt .
|
||||
RUN pip install --upgrade pip
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
COPY . .
|
||||
|
||||
# Create a non-root user to run the web server
|
||||
RUN adduser -u 5678 --disabled-password --gecos "" appuser && chown -R appuser /app
|
||||
USER appuser
|
||||
|
||||
# Run server
|
||||
EXPOSE 8001
|
||||
# CMD ["gunicorn", "--bind", "0.0.0.0:8001", "main_package.app:app"]
|
||||
CMD ["uvicorn", "main_package.app:app", "--reload", "--host", "0.0.0.0", "--port", "8001"]
|
|
@ -0,0 +1,5 @@
|
|||
#!/bin/bash
|
||||
|
||||
docker-compose build
|
||||
|
||||
echo "Finish!"
|
|
@ -0,0 +1,9 @@
|
|||
services:
|
||||
api:
|
||||
build: .
|
||||
image: app
|
||||
ports:
|
||||
- "8001:8001"
|
||||
volumes:
|
||||
- .:/app:ro
|
||||
- ./datings.db:/app/datings.db:rw
|
|
@ -0,0 +1,5 @@
|
|||
#!/bin/bash
|
||||
|
||||
docker-compose down
|
||||
|
||||
echo "Finish!"
|
|
@ -0,0 +1,5 @@
|
|||
#!/bin/bash
|
||||
|
||||
docker-compose up
|
||||
|
||||
echo "Finish!"
|
|
@ -5,9 +5,10 @@ import uuid
|
|||
from contextlib import asynccontextmanager
|
||||
|
||||
from fastapi import FastAPI, Request, HTTPException
|
||||
from fastapi.responses import HTMLResponse, JSONResponse, PlainTextResponse
|
||||
from fastapi.responses import HTMLResponse, JSONResponse, PlainTextResponse, FileResponse
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
from fastapi.templating import Jinja2Templates
|
||||
from fastapi_sitemap import SiteMap, URLInfo
|
||||
|
||||
from .database import create_tables, delete_tables
|
||||
from .router import router as datings_router
|
||||
|
@ -44,6 +45,8 @@ app = FastAPI(
|
|||
lifespan=lifespan, docs_url=None, redoc_url=None, openapi_url=settings.OPENAPI_URL
|
||||
)
|
||||
|
||||
favicon_path = "static/assets/img/favicons/favicon.ico"
|
||||
|
||||
templates = Jinja2Templates(directory="templates")
|
||||
|
||||
app.include_router(datings_router)
|
||||
|
@ -70,6 +73,11 @@ async def index(request: Request):
|
|||
return response
|
||||
|
||||
|
||||
@app.get("/favicon.ico", include_in_schema=False)
|
||||
async def favicon():
|
||||
return FileResponse(favicon_path)
|
||||
|
||||
|
||||
@app.get("/robots.txt", response_class=PlainTextResponse)
|
||||
def robots():
|
||||
data = """User-agent: *\nAllow: /\nSitemap: /sitemap.xml"""
|
||||
|
@ -81,5 +89,31 @@ async def http_exception_handler(request, exc):
|
|||
return JSONResponse(status_code=exc.status_code, content={"detail": exc.detail})
|
||||
|
||||
|
||||
sitemap = SiteMap(
|
||||
app=app,
|
||||
base_url="https://lerafoxqueen.ru",
|
||||
static_dirs=["static", "docs"],
|
||||
exclude_patterns=[
|
||||
"^/api/",
|
||||
"^/docs/",
|
||||
"^/datings",
|
||||
"^/api/",
|
||||
"^/admin/",
|
||||
], # optional: exclude patterns
|
||||
include_dynamic=True,
|
||||
changefreq="daily",
|
||||
priority_map={
|
||||
"/": 1.0,
|
||||
},
|
||||
gzip=True, # optional: make a gz version too
|
||||
)
|
||||
|
||||
sitemap.attach() # now GET /sitemap.xml is live
|
||||
|
||||
# @sitemap.source
|
||||
# def extra_urls():
|
||||
# yield URLInfo("https://lerafoxqueen.ru/sitemap.xml")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
uvicorn.run(app, host="127.0.0.1", port=8001)
|
||||
uvicorn.run(app, host="0.0.0.0", port=8001)
|
|
@ -1,5 +1,5 @@
|
|||
[project]
|
||||
name = "LeraFoxQueen"
|
||||
name = "main_package"
|
||||
version = "0.1.0"
|
||||
description = ""
|
||||
authors = [
|
||||
|
@ -13,6 +13,7 @@ dependencies = [
|
|||
"hypercorn (>=0.17.3,<0.18.0)",
|
||||
"unicorn (>=2.1.3,<3.0.0)",
|
||||
"uvicorn (>=0.34.3,<0.35.0)",
|
||||
"gunicorn (>=23.0.0,<24.0.0)",
|
||||
"fastapi (>=0.115.12,<0.116.0)",
|
||||
"aiosqlite (>=0.21.0,<0.22.0)",
|
||||
"sqlalchemy (>=2.0.41,<3.0.0)",
|
||||
|
@ -29,8 +30,13 @@ dependencies = [
|
|||
"sniffio (>=1.3.1,<2.0.0)",
|
||||
"jinja2 (>=3.1.6,<4.0.0)",
|
||||
"pydantic-settings (>=2.9.1,<3.0.0)",
|
||||
"fastapi-sitemap (>=1.0.4,<2.0.0)",
|
||||
]
|
||||
package-mode = false
|
||||
packages = [{include = "main_package"}]
|
||||
|
||||
[tool.poetry.requires-plugins]
|
||||
poetry-plugin-export = ">=1.8"
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core>=2.0.0,<3.0.0"]
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9
|
||||
http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
|
||||
<url>
|
||||
<loc>https://lerafoxqueen.ru/</loc>
|
||||
<priority>1.00</priority>
|
||||
</url>
|
||||
</urlset>
|
18
start.sh
18
start.sh
|
@ -1,12 +1,22 @@
|
|||
#!/bin/sh
|
||||
|
||||
python -m venv .venv
|
||||
source .venv/bin/activate
|
||||
pip install -U pip
|
||||
pip install uvicorn gunicorn hypercorn fastapi certifi poetry poetry-plugin-export
|
||||
poetry self add poetry-plugin-export
|
||||
|
||||
pip show uvicorn | grep -E "Name:|Version:|Location:"
|
||||
pip show gunicorn | grep -E "Name:|Version:|Location:"
|
||||
pip show fastapi | grep -E "Name:|Version:|Location:"
|
||||
|
||||
pyenv local 3.13
|
||||
poetry env activate
|
||||
poetry lock
|
||||
poetry install --no-root
|
||||
|
||||
#hypercorn LeraFoxQueen.main:app --reload --bind 0.0.0.0:8001
|
||||
#poetry run hypercorn LeraFoxQueen/main:app --reload --bind 0.0.0.0:8001
|
||||
#uvicorn LeraFoxQueen.main:app --reload --host 0.0.0.0 --port 8001
|
||||
uvicorn LeraFoxQueen.main:app --reload --host 127.0.0.1 --port 8001
|
||||
#hypercorn main_package.app:app --reload -w $(nproc) --bind 0.0.0.0:8001
|
||||
#poetry run hypercorn main_package/app:app --reload -w $(nproc) --bind 0.0.0.0:8001
|
||||
#uvicorn main_package.app:app --reload --workers $(nproc) --host 0.0.0.0 --port 8001
|
||||
uvicorn main_package.app:app --reload --workers $(nproc) --host 127.0.0.1 --port 8001
|
||||
#gunicorn -b 0.0.0.0:8001 -k uvicorn.workers.UvicornWorker main_package.app:app
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"systemParams": "linux-x64-127",
|
||||
"systemParams": "linux-x64-137",
|
||||
"modulesFolders": [
|
||||
"node_modules"
|
||||
],
|
||||
|
@ -7,13 +7,11 @@
|
|||
"linkedModules": [],
|
||||
"topLevelPatterns": [
|
||||
"@fortawesome/fontawesome-free@^6.7.2",
|
||||
"bootstrap-autocomplete@^2.3.7",
|
||||
"bootstrap@^5.3.6"
|
||||
],
|
||||
"lockfileEntries": {
|
||||
"@fortawesome/fontawesome-free@^6.7.2": "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-6.7.2.tgz#8249de9b7e22fcb3ceb5e66090c30a1d5492b81a",
|
||||
"bootstrap-autocomplete@^2.3.7": "https://registry.yarnpkg.com/bootstrap-autocomplete/-/bootstrap-autocomplete-2.3.7.tgz#d3d0ebfe124f8b0299a99b1ecdf885816bbf29d8",
|
||||
"bootstrap@^5.3.6": "https://registry.yarnpkg.com/bootstrap/-/bootstrap-5.3.6.tgz#fbd91ebaff093f5b191a1c01a8c866d24f9fa6e1"
|
||||
"bootstrap@^5.3.6": "https://registry.yarnpkg.com/bootstrap/-/bootstrap-5.3.7.tgz#8640065036124d961d885d80b5945745e1154d90"
|
||||
},
|
||||
"files": [],
|
||||
"artifacts": {}
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2020 Paolo Casciello, contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
|
@ -1,37 +0,0 @@
|
|||
Bootstrap Autocomplete
|
||||
======================
|
||||
|
||||

|
||||
[](https://cirrus-ci.com/github/xcash/bootstrap-autocomplete)
|
||||
|
||||
Autocomplete plugin for Bootstrap 4.x and 3.x.
|
||||
|
||||
It enhances form `input` and `select` field to provide autocomplete/typeahead capabilities.
|
||||
|
||||
[Documentation](http://bootstrap-autocomplete.rtfd.io/)
|
||||
|
||||
Latest version: 2.3.7 (2020/08/27)
|
||||
|
||||
Version 2.0.0 and up supports Boostrap v4.x and old v3.x out of the box.
|
||||
|
||||
Try the DEMO!
|
||||
=============
|
||||
|
||||
[Bootstrap 4 latest version](https://raw.githack.com/xcash/bootstrap-autocomplete/master/dist/latest/index.html)
|
||||
|
||||
[Bootstrap 3 latest version](https://raw.githack.com/xcash/bootstrap-autocomplete/master/dist/latest/indexV3.html)
|
||||
|
||||
|
||||
Creating DEV Environment
|
||||
========================
|
||||
|
||||
docker-compose build --pull
|
||||
|
||||
The *first time* install all dependencies with yarn
|
||||
|
||||
docker-compose run --rm tools yarn install
|
||||
|
||||
Running DEV Environment
|
||||
=======================
|
||||
|
||||
docker-compose up
|
1
static/node_modules/bootstrap-autocomplete/dist/latest/bootstrap-autocomplete.js
generated
vendored
1
static/node_modules/bootstrap-autocomplete/dist/latest/bootstrap-autocomplete.js
generated
vendored
File diff suppressed because one or more lines are too long
1
static/node_modules/bootstrap-autocomplete/dist/latest/bootstrap-autocomplete.min.js
generated
vendored
1
static/node_modules/bootstrap-autocomplete/dist/latest/bootstrap-autocomplete.min.js
generated
vendored
File diff suppressed because one or more lines are too long
|
@ -1,350 +0,0 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Bootstrap AutoComplete Demo Bootstrap 4</title>
|
||||
|
||||
<!-- Required meta tags -->
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
|
||||
<link rel="stylesheet" href="//stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1 class="border-bottom">Bootstrap Autocomplete (for Bootstrap version 4)</h1>
|
||||
<p>
|
||||
This page acts like a Demo page and a Testing page.
|
||||
</p>
|
||||
<form>
|
||||
<fieldset>
|
||||
<legend class="border-bottom">AJAX</legend>
|
||||
<div class="form-row mb-3">
|
||||
<label class="col-lg-3">
|
||||
Basic (<a href="testdata/test-list.json">list of strings</a>)
|
||||
</label>
|
||||
<div class="col-lg-9">
|
||||
<input class="form-control basicAutoComplete" type="text" autocomplete="off">
|
||||
Selected item: <code class="basicAutoCompleteSelected"></code><br>
|
||||
Custom value: <code class="basicAutoCompleteCustom"></code>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row mb-3">
|
||||
<label class="col-lg-3">
|
||||
Basic (<a href="testdata/test-list.json">list of strings</a> - custom <code>search</code> parameter)
|
||||
</label>
|
||||
<div class="col-lg-9">
|
||||
<input class="form-control basicAutoCompleteQParameter" type="text" autocomplete="off">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row mb-3">
|
||||
<label class="col-lg-3">
|
||||
Advanced (<a href="testdata/test-dict.json">complex object</a>)
|
||||
</label>
|
||||
<div class="col-lg-9">
|
||||
<input class="form-control advancedAutoComplete" type="text" autocomplete="off" placeholder="type to search...">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row mb-3">
|
||||
<label class="col-lg-3">
|
||||
Advanced (<a href="testdata/test-dict.json">complex object</a> - custom formatting)
|
||||
</label>
|
||||
<div class="col-lg-9">
|
||||
<input class="form-control advanced2AutoComplete" type="text" autocomplete="off">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row mb-3">
|
||||
<label class="col-lg-3">
|
||||
Show dropdown programmatically.
|
||||
</label>
|
||||
<div class="col-lg-7">
|
||||
<input class="form-control basicAutoCompleteShowDropdown" data-url="testdata/test-list.json" type="text" autocomplete="off">
|
||||
</div>
|
||||
<div class="col-lg-2">
|
||||
<button type="button" class="btn btn-block btn-outline-secondary basicAutoCompleteShowBtn">
|
||||
Show
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend class="border-bottom">
|
||||
<code><select></code> as Autocomplete
|
||||
</legend>
|
||||
<div class="row">
|
||||
<div class="col-lg-9 offset-lg-3">
|
||||
<p>
|
||||
Selects are a subtype of autocomplete where the selected value is restricted to
|
||||
server-provided results. User <b>must</b> select one of those.
|
||||
</p>
|
||||
<p>
|
||||
Bootstrap-Autocomplete provides a smarter select rendered as a standard
|
||||
autocomplete <b>text</b> field. It substitutes the field with an
|
||||
<code><input type="search"></code> and creates a <i>shadow</i> hidden field with
|
||||
the selected value (and the original name).
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row mb-3">
|
||||
<label class="col-lg-3">
|
||||
Simple (<a href="testdata/test-select-simple.json">list of { value, strings }</a>)
|
||||
</label>
|
||||
<div class="col-lg-9">
|
||||
<select class="form-control basicAutoSelect" name="simple_select"
|
||||
placeholder="type to search..."
|
||||
data-url="testdata/test-select-simple.json" autocomplete="off"></select>
|
||||
<code class="basicAutoSelectSelected"></code>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row mb-3">
|
||||
<label class="col-lg-3">
|
||||
Default Selected (<a href="testdata/test-select-simple.json">list of { value, strings }</a>)
|
||||
</label>
|
||||
<div class="col-lg-9">
|
||||
<select class="form-control defaultAutoSelect" id="dAS" name="default_select"
|
||||
data-url="testdata/test-select-simple.json"
|
||||
data-default-value="3" data-default-text="Docker"
|
||||
autocomplete="off"></select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row mb-3">
|
||||
<label class="col-lg-3">
|
||||
No results (<a href="testdata/test-empty.json">empty list</a>)
|
||||
</label>
|
||||
<div class="col-lg-9">
|
||||
<select class="form-control emptyAutoSelect" name="empty_select"
|
||||
data-url="testdata/test-empty.json"
|
||||
data-noresults-text="Nothing to see here."
|
||||
autocomplete="off"></select>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend class="border-bottom">
|
||||
In Bootstrap modal
|
||||
</legend>
|
||||
<div class="row">
|
||||
<div class="col-lg-9 offset-lg-3">
|
||||
<button type="button" class="btn btn-primary" autocomplete="off"
|
||||
data-toggle="modal" data-target="#testModal">
|
||||
Open Test Modal
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>Javascript API</legend>
|
||||
<div class="form-row mb-3">
|
||||
<label class="col-lg-3">
|
||||
Change selected value programmatically
|
||||
</label>
|
||||
<div class="col-lg-9">
|
||||
<select class="form-control changeAutoSelect" name="change_select"
|
||||
data-url="testdata/test-select-simple.json"
|
||||
data-noresults-text="Nothing to see here."
|
||||
data-default-value="x123" data-default-text="Default text before change"
|
||||
autocomplete="off"></select>
|
||||
<br>
|
||||
<button type="button" class="btn btn-outline-secondary btnChangeAutoSelect" autocomplete="off"
|
||||
data-value="1" data-text="Selected Value 1">
|
||||
Set a different selected value
|
||||
</button>
|
||||
<button type="button" class="btn btn-outline-secondary btnChangeAutoSelect" autocomplete="off"
|
||||
data-value="2" data-text="Selected Value 2">
|
||||
Set a different selected value 2
|
||||
</button>
|
||||
<button type="button" class="btn btn-outline-secondary btnClearAutoSelect">
|
||||
Clear Value
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>Events</legend>
|
||||
<div class="form-row mb-3">
|
||||
<label class="col-lg-3">
|
||||
Events in text field
|
||||
</label>
|
||||
<div class="col-lg-9">
|
||||
<input class="form-control eventsAutoComplete" type="text" autocomplete="off">
|
||||
<br>
|
||||
<code><pre id="eventsCodeContainer"></pre></code>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="modal fade" id="testModal" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<h4 class="modal-title">Modal title</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<select class="form-control basicModalAutoSelect" name="simple_select"
|
||||
placeholder="type to search..."
|
||||
data-url="testdata/test-select-simple.json" autocomplete="off"></select>
|
||||
<code class="basicModalAutoSelectSelected"></code>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
||||
</div>
|
||||
</div><!-- /.modal-content -->
|
||||
</div><!-- /.modal-dialog -->
|
||||
</div><!-- /.modal -->
|
||||
|
||||
<script src="//code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
|
||||
<script src="//cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
|
||||
<script src="//stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js" integrity="sha384-B4gt1jrGC7Jh4AgTPSdUtOBvfO8shuf57BaghqFfPlYxofvL8/KUEfYiJOMMV+rV" crossorigin="anonymous"></script>
|
||||
<script src="bootstrap-autocomplete.js"></script>
|
||||
<script>
|
||||
$(function () {
|
||||
// Basic
|
||||
$('.basicAutoComplete').autoComplete({
|
||||
resolverSettings: {
|
||||
url: 'testdata/test-list.json'
|
||||
}
|
||||
});
|
||||
|
||||
$('.basicAutoComplete').on('change', function (e) {
|
||||
console.log('change');
|
||||
});
|
||||
|
||||
$('.basicAutoComplete').on('autocomplete.select', function (evt, item) {
|
||||
$('.basicAutoCompleteSelected').html(JSON.stringify(item));
|
||||
$('.basicAutoCompleteCustom').html('');
|
||||
});
|
||||
|
||||
$('.basicAutoComplete').on('autocomplete.freevalue', function (evt, value) {
|
||||
$('.basicAutoCompleteCustom').html(JSON.stringify(value));
|
||||
$('.basicAutoCompleteSelected').html('');
|
||||
});
|
||||
|
||||
$('.basicAutoCompleteShowDropdown').autoComplete({
|
||||
minLength: 0,
|
||||
});
|
||||
|
||||
$('.basicAutoCompleteShowBtn').on('click', function () {
|
||||
console.log('click');
|
||||
$('.basicAutoCompleteShowDropdown').autoComplete('show');
|
||||
});
|
||||
|
||||
$('.basicAutoCompleteQParameter').autoComplete({
|
||||
resolverSettings: {
|
||||
url: 'testdata/test-list.json',
|
||||
queryKey: 'search'
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// Advanced 1
|
||||
$('.advancedAutoComplete').autoComplete({
|
||||
resolver: 'custom',
|
||||
events: {
|
||||
search: function (qry, callback) {
|
||||
// let's do a custom ajax call
|
||||
$.ajax(
|
||||
'testdata/test-dict.json',
|
||||
{
|
||||
data: { 'qry': qry}
|
||||
}
|
||||
).done(function (res) {
|
||||
callback(res.results)
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Advanced 2
|
||||
$('.advanced2AutoComplete').autoComplete({
|
||||
resolver: 'custom',
|
||||
formatResult: function (item) {
|
||||
return {
|
||||
value: item.id,
|
||||
text: "[" + item.id + "] " + item.text,
|
||||
html: [
|
||||
$('<img>').attr('src', item.icon).css("height", 18), ' ',
|
||||
item.text
|
||||
]
|
||||
};
|
||||
},
|
||||
events: {
|
||||
search: function (qry, callback) {
|
||||
// let's do a custom ajax call
|
||||
$.ajax(
|
||||
'testdata/test-dict.json',
|
||||
{
|
||||
data: { 'qry': qry}
|
||||
}
|
||||
).done(function (res) {
|
||||
callback(res.results)
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Basic Select
|
||||
$('.basicAutoSelect').autoComplete();
|
||||
$('.basicAutoSelect').on('autocomplete.select', function (evt, item) {
|
||||
console.log('select', item);
|
||||
$('.basicAutoSelectSelected').html(item?JSON.stringify(item):'null');
|
||||
|
||||
});
|
||||
|
||||
// Default Select
|
||||
$('.defaultAutoSelect').autoComplete();
|
||||
$('#dAS').on('autocomplete.select', function (e, i) {
|
||||
console.log('selected');
|
||||
});
|
||||
|
||||
// Empty Select
|
||||
$('.emptyAutoSelect').autoComplete();
|
||||
|
||||
// Modal
|
||||
$('.basicModalAutoSelect').autoComplete();
|
||||
$('.basicModalAutoSelect').on('autocomplete.select', function (evt, item) {
|
||||
console.log('select');
|
||||
$('.basicModalAutoSelectSelected').html(JSON.stringify(item));
|
||||
});
|
||||
|
||||
// Change default value programmatically.
|
||||
// Let's simulate a real world example.
|
||||
// Some point in time we initialize the autocomplete with a default value (defined by markup)
|
||||
$('.changeAutoSelect').autoComplete();
|
||||
// user then clicks on some button and we need to change that default value
|
||||
$('.btnChangeAutoSelect').on('click', function () {
|
||||
var e = $(this);
|
||||
$('.changeAutoSelect').autoComplete('set', { value: e.data('value'), text: e.data('text')});
|
||||
});
|
||||
// clear current value
|
||||
$('.btnClearAutoSelect').on('click', function () {
|
||||
var e = $(this);
|
||||
// $('.changeAutoSelect').autoComplete('set', null);
|
||||
$('.changeAutoSelect').autoComplete('clear');
|
||||
|
||||
});
|
||||
|
||||
// Events
|
||||
var eventsCodeContainer = $('#eventsCodeContainer');
|
||||
|
||||
$('.eventsAutoComplete').autoComplete({
|
||||
resolverSettings: {
|
||||
url: 'testdata/test-list.json'
|
||||
}
|
||||
});
|
||||
$('.eventsAutoComplete').on('change', function() {
|
||||
console.log('eventsAutoComplete change');
|
||||
eventsCodeContainer.text(eventsCodeContainer.text() + 'fired change. value: ' + $(this).val() + '\n');
|
||||
});
|
||||
$('.eventsAutoComplete').on('autocomplete.select', function(evt, item) {
|
||||
console.log('eventsAutoComplete autocomplete.select');
|
||||
eventsCodeContainer.text(eventsCodeContainer.text() + 'fired autocomplete.select. item: ' + item + ' value: ' + $(this).val() + '\n');
|
||||
});
|
||||
$('.eventsAutoComplete').on('autocomplete.freevalue', function(evt, item) {
|
||||
console.log('eventsAutoComplete autocomplete.freevalue');
|
||||
eventsCodeContainer.text(eventsCodeContainer.text() + 'fired autocomplete.freevalue. item: ' + item + ' value: ' + $(this).val() + '\n');
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,259 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Bootstrap AutoComplete Demo</title>
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link href="//netdna.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1 class="page-header">Bootstrap Autocomplete</h1>
|
||||
<p>
|
||||
This page acts like a Demo page and a Testing page.
|
||||
</p>
|
||||
<form class="form-horizontal">
|
||||
<fieldset>
|
||||
<legend>AJAX</legend>
|
||||
<div class="form-group">
|
||||
<label class="col-lg-3 control-label">
|
||||
Basic (<a href="testdata/test-list.json">list of strings</a>)
|
||||
</label>
|
||||
<div class="col-lg-9">
|
||||
<input class="form-control basicAutoComplete" type="text" autocomplete="off">
|
||||
Selected item: <code class="basicAutoCompleteSelected"></code><br>
|
||||
Custom value: <code class="basicAutoCompleteCustom"></code>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-lg-3 control-label">
|
||||
Advanced (<a href="testdata/test-dict.json">complex object</a>)
|
||||
</label>
|
||||
<div class="col-lg-9">
|
||||
<input class="form-control advancedAutoComplete" type="text" autocomplete="off" placeholder="type to search...">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-lg-3 control-label">
|
||||
Advanced (<a href="testdata/test-dict.json">complex object</a> - custom formatting)
|
||||
</label>
|
||||
<div class="col-lg-9">
|
||||
<input class="form-control advanced2AutoComplete" type="text" autocomplete="off">
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend><code><select></code> as Autocomplete</legend>
|
||||
<div class="row">
|
||||
<div class="col-lg-9 col-lg-offset-3">
|
||||
<p>
|
||||
Selects are a subtype of autocomplete where the selected value is restricted to
|
||||
server-provided results. User <b>must</b> select one of those.
|
||||
</p>
|
||||
<p>
|
||||
Bootstrap-Autocomplete provides a smarter select rendered as a standard
|
||||
autocomplete <b>text</b> field. It substitutes the field with an
|
||||
<code><input type="text"></code and creates a <i>shadow</i> hidden field with
|
||||
the selected value (and the original name).
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-lg-3 control-label">
|
||||
Simple (<a href="testdata/test-select-simple.json">list of { value, strings }</a>)
|
||||
</label>
|
||||
<div class="col-lg-9">
|
||||
<select class="form-control basicAutoSelect" name="simple_select"
|
||||
placeholder="type to search..."
|
||||
data-url="testdata/test-select-simple.json" autocomplete="off"></select>
|
||||
<code class="basicAutoSelectSelected"></code>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-lg-3 control-label">
|
||||
Default Selected (<a href="testdata/test-select-simple.json">list of { value, strings }</a>)
|
||||
</label>
|
||||
<div class="col-lg-9">
|
||||
<select class="form-control defaultAutoSelect" id="dAS" name="default_select"
|
||||
data-url="testdata/test-select-simple.json"
|
||||
data-default-value="3" data-default-text="Docker"
|
||||
autocomplete="off"></select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-lg-3 control-label">
|
||||
No results (<a href="testdata/test-empty.json">empty list</a>)
|
||||
</label>
|
||||
<div class="col-lg-9">
|
||||
<select class="form-control emptyAutoSelect" name="empty_select"
|
||||
data-url="testdata/test-empty.json"
|
||||
data-noresults-text="Nothing to see here."
|
||||
autocomplete="off"></select>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>In Bootstrap modal</legend>
|
||||
<div class="row">
|
||||
<div class="col-lg-9 col-lg-offset-3">
|
||||
<button type="button" class="btn btn-primary" autocomplete="off"
|
||||
data-toggle="modal" data-target="#testModal">
|
||||
Open Test Modal
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>Javascript API</legend>
|
||||
<div class="form-group">
|
||||
<label class="col-lg-3 control-label">
|
||||
Change selected value programmatically
|
||||
</label>
|
||||
<div class="col-lg-9">
|
||||
<select class="form-control changeAutoSelect" name="change_select"
|
||||
data-url="testdata/test-select-simple.json"
|
||||
data-noresults-text="Nothing to see here."
|
||||
data-default-value="x123" data-default-text="Default text before change"
|
||||
autocomplete="off"></select>
|
||||
<br>
|
||||
<button type="button" class="btn btn-default btnChangeAutoSelect" autocomplete="off"
|
||||
data-value="1" data-text="Selected Value 1">
|
||||
Set a different selected value
|
||||
</button>
|
||||
<button type="button" class="btn btn-default btnChangeAutoSelect" autocomplete="off"
|
||||
data-value="2" data-text="Selected Value 2">
|
||||
Set a different selected value 2
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="modal fade" id="testModal" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<h4 class="modal-title">Modal title</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<select class="form-control basicModalAutoSelect" name="simple_select"
|
||||
placeholder="type to search..."
|
||||
data-url="testdata/test-select-simple.json" autocomplete="off"></select>
|
||||
<code class="basicModalAutoSelectSelected"></code>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
||||
</div>
|
||||
</div><!-- /.modal-content -->
|
||||
</div><!-- /.modal-dialog -->
|
||||
</div><!-- /.modal -->
|
||||
|
||||
<script src="//ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
|
||||
<script src="//netdna.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
|
||||
<script src="bootstrap-autocomplete.js"></script>
|
||||
<script>
|
||||
$(function () {
|
||||
// Basic
|
||||
$('.basicAutoComplete').autoComplete({
|
||||
resolverSettings: {
|
||||
url: 'testdata/test-list.json'
|
||||
}
|
||||
});
|
||||
|
||||
$('.basicAutoComplete').on('change', function (e) {
|
||||
console.log('change');
|
||||
});
|
||||
|
||||
$('.basicAutoComplete').on('autocomplete.select', function (evt, item) {
|
||||
$('.basicAutoCompleteSelected').html(JSON.stringify(item));
|
||||
$('.basicAutoCompleteCustom').html('');
|
||||
});
|
||||
|
||||
$('.basicAutoComplete').on('autocomplete.freevalue', function (evt, value) {
|
||||
$('.basicAutoCompleteCustom').html(JSON.stringify(value));
|
||||
$('.basicAutoCompleteSelected').html('');
|
||||
});
|
||||
|
||||
// Advanced 1
|
||||
$('.advancedAutoComplete').autoComplete({
|
||||
resolver: 'custom',
|
||||
events: {
|
||||
search: function (qry, callback) {
|
||||
// let's do a custom ajax call
|
||||
$.ajax(
|
||||
'testdata/test-dict.json',
|
||||
{
|
||||
data: { 'qry': qry}
|
||||
}
|
||||
).done(function (res) {
|
||||
callback(res.results)
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Advanced 2
|
||||
$('.advanced2AutoComplete').autoComplete({
|
||||
resolver: 'custom',
|
||||
formatResult: function (item) {
|
||||
return {
|
||||
value: item.id,
|
||||
text: "[" + item.id + "] " + item.text,
|
||||
html: [
|
||||
$('<img>').attr('src', item.icon).css("height", 18), ' ',
|
||||
item.text
|
||||
]
|
||||
};
|
||||
},
|
||||
events: {
|
||||
search: function (qry, callback) {
|
||||
// let's do a custom ajax call
|
||||
$.ajax(
|
||||
'testdata/test-dict.json',
|
||||
{
|
||||
data: { 'qry': qry}
|
||||
}
|
||||
).done(function (res) {
|
||||
callback(res.results)
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Basic Select
|
||||
$('.basicAutoSelect').autoComplete();
|
||||
$('.basicAutoSelect').on('autocomplete.select', function (evt, item) {
|
||||
console.log('select');
|
||||
$('.basicAutoSelectSelected').html(JSON.stringify(item));
|
||||
});
|
||||
|
||||
// Default Select
|
||||
$('.defaultAutoSelect').autoComplete();
|
||||
$('#dAS').on('autocomplete.select', function (e, i) {
|
||||
console.log('selected');
|
||||
});
|
||||
|
||||
// Empty Select
|
||||
$('.emptyAutoSelect').autoComplete();
|
||||
|
||||
// Modal
|
||||
$('.basicModalAutoSelect').autoComplete();
|
||||
$('.basicModalAutoSelect').on('autocomplete.select', function (evt, item) {
|
||||
console.log('select');
|
||||
$('.basicModalAutoSelectSelected').html(JSON.stringify(item));
|
||||
});
|
||||
|
||||
// Change default value programmatically.
|
||||
// Let's simulate a real world example.
|
||||
// Some point in time we initialize the autocomplete with a default value (defined by markup)
|
||||
$('.changeAutoSelect').autoComplete();
|
||||
// user then clicks on some button and we need to change that default value
|
||||
$('.btnChangeAutoSelect').on('click', function () {
|
||||
var e = $(this);
|
||||
$('.changeAutoSelect').autoComplete('set', { value: e.data('value'), text: e.data('text')});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
16
static/node_modules/bootstrap-autocomplete/dist/latest/testdata/test-dict.json
generated
vendored
16
static/node_modules/bootstrap-autocomplete/dist/latest/testdata/test-dict.json
generated
vendored
|
@ -1,16 +0,0 @@
|
|||
{
|
||||
"results": [
|
||||
{
|
||||
"id": 1, "text": "Google Cloud Platform",
|
||||
"icon": "https://pbs.twimg.com/profile_images/966440541859688448/PoHJY3K8_400x400.jpg"
|
||||
},
|
||||
{
|
||||
"id": 2, "text": "Amazon AWS",
|
||||
"icon": "http://photos3.meetupstatic.com/photos/event/5/d/e/0/highres_263124032.jpeg"
|
||||
},
|
||||
{
|
||||
"id": 3, "text": "Docker",
|
||||
"icon": "https://www.docker.com/sites/default/files/legal/small_v.png"
|
||||
}
|
||||
]
|
||||
}
|
1
static/node_modules/bootstrap-autocomplete/dist/latest/testdata/test-empty.json
generated
vendored
1
static/node_modules/bootstrap-autocomplete/dist/latest/testdata/test-empty.json
generated
vendored
|
@ -1 +0,0 @@
|
|||
[]
|
60
static/node_modules/bootstrap-autocomplete/dist/latest/testdata/test-issue-10.html
generated
vendored
60
static/node_modules/bootstrap-autocomplete/dist/latest/testdata/test-issue-10.html
generated
vendored
|
@ -1,60 +0,0 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Bootstrap AutoComplete Test Issue 10</title>
|
||||
|
||||
<!-- Required meta tags -->
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" integrity="sha384-9gVQ4dYFwwWSjIDZnLEWnxCjeSWFphJiwGPXr1jddIhOegiu1FwO5qRGvFXOdJZ4" crossorigin="anonymous">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1 class="border-bottom">Bootstrap Autocomplete test issue 10</h1>
|
||||
<p>
|
||||
Testing page for <a href="https://github.com/xcash/bootstrap-autocomplete/issues/10">issue #10</a>
|
||||
</p>
|
||||
<form action="//example.com" method="GET" target="_blank">
|
||||
<input class="form-control basicAutoComplete" name="q" type="text" autocomplete="off">
|
||||
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js" integrity="sha384-cs/chFZiN24E4KMATLdqdvsezGxaGsi4hLGOzlXwp5UZB1LY//20VyM2taTB4QvJ" crossorigin="anonymous"></script>
|
||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js" integrity="sha384-uefMccjFJAIv6A+rW+L4AHf99KvxDjWSu1z9VI8SKNVmz4sk7buKt/6v9KI65qnm" crossorigin="anonymous"></script>
|
||||
<script src="../bootstrap-autocomplete.js"></script>
|
||||
<script>
|
||||
$(function () {
|
||||
// Basic
|
||||
$('.basicAutoComplete').autoComplete({
|
||||
resolverSettings: {
|
||||
url: 'test-list.json'
|
||||
}
|
||||
});
|
||||
|
||||
// Events
|
||||
var eventsCodeContainer = $('#eventsCodeContainer');
|
||||
|
||||
$('.eventsAutoComplete').autoComplete({
|
||||
resolverSettings: {
|
||||
url: 'testdata/test-list.json'
|
||||
}
|
||||
});
|
||||
$('.eventsAutoComplete').on('change', function() {
|
||||
console.log('eventsAutoComplete change');
|
||||
eventsCodeContainer.text(eventsCodeContainer.text() + 'fired change. value: ' + $(this).val() + '\n');
|
||||
});
|
||||
$('.eventsAutoComplete').on('autocomplete.select', function(evt, item) {
|
||||
console.log('eventsAutoComplete autocomplete.select');
|
||||
eventsCodeContainer.text(eventsCodeContainer.text() + 'fired autocomplete.select. item: ' + item + ' value: ' + $(this).val() + '\n');
|
||||
});
|
||||
$('.eventsAutoComplete').on('autocomplete.freevalue', function(evt, item) {
|
||||
console.log('eventsAutoComplete autocomplete.freevalue');
|
||||
eventsCodeContainer.text(eventsCodeContainer.text() + 'fired autocomplete.freevalue. item: ' + item + ' value: ' + $(this).val() + '\n');
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
308
static/node_modules/bootstrap-autocomplete/dist/latest/testdata/test-issue-20.html
generated
vendored
308
static/node_modules/bootstrap-autocomplete/dist/latest/testdata/test-issue-20.html
generated
vendored
|
@ -1,308 +0,0 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Bootstrap AutoComplete Demo Bootstrap 4</title>
|
||||
|
||||
<!-- Required meta tags -->
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" integrity="sha384-9gVQ4dYFwwWSjIDZnLEWnxCjeSWFphJiwGPXr1jddIhOegiu1FwO5qRGvFXOdJZ4" crossorigin="anonymous">
|
||||
<style type="text/css">
|
||||
.dropdown-menu {
|
||||
overflow: scroll;
|
||||
max-width: 400px;
|
||||
max-height: 120px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1 class="border-bottom">Bootstrap Autocomplete (for Bootstrap version 4)</h1>
|
||||
<p>
|
||||
This page acts like a Demo page and a Testing page. Here we are testing issue #20, solving a bug in which a scrollable dropdown inside a modal was closed when clicking on the scrollbar.
|
||||
</p>
|
||||
<form>
|
||||
<fieldset>
|
||||
<legend class="border-bottom">AJAX</legend>
|
||||
<div class="form-row mb-3">
|
||||
<label class="col-lg-3">
|
||||
Basic (<a href="test-list.json">list of strings</a>)
|
||||
</label>
|
||||
<div class="col-lg-9">
|
||||
<input class="form-control basicAutoComplete" type="text" autocomplete="off">
|
||||
Selected item: <code class="basicAutoCompleteSelected"></code><br>
|
||||
Custom value: <code class="basicAutoCompleteCustom"></code>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row mb-3">
|
||||
<label class="col-lg-3">
|
||||
Advanced (<a href="test-dict.json">complex object</a>)
|
||||
</label>
|
||||
<div class="col-lg-9">
|
||||
<input class="form-control advancedAutoComplete" type="text" autocomplete="off" placeholder="type to search...">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row mb-3">
|
||||
<label class="col-lg-3">
|
||||
Advanced (<a href="test-dict.json">complex object</a> - custom formatting)
|
||||
</label>
|
||||
<div class="col-lg-9">
|
||||
<input class="form-control advanced2AutoComplete" type="text" autocomplete="off">
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend class="border-bottom">
|
||||
<code><select></code> as Autocomplete
|
||||
</legend>
|
||||
<div class="row">
|
||||
<div class="col-lg-9 offset-lg-3">
|
||||
<p>
|
||||
Selects are a subtype of autocomplete where the selected value is restricted to
|
||||
server-provided results. User <b>must</b> select one of those.
|
||||
</p>
|
||||
<p>
|
||||
Bootstrap-Autocomplete provides a smarter select rendered as a standard
|
||||
autocomplete <b>text</b> field. It substitutes the field with an
|
||||
<code><input type="text"></code and creates a <i>shadow</i> hidden field with
|
||||
the selected value (and the original name).
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row mb-3">
|
||||
<label class="col-lg-3">
|
||||
Simple (<a href="test-select-simple.json">list of { value, strings }</a>)
|
||||
</label>
|
||||
<div class="col-lg-9">
|
||||
<select class="form-control basicAutoSelect" name="simple_select"
|
||||
placeholder="type to search..."
|
||||
data-url="test-select-simple.json" autocomplete="off"></select>
|
||||
<code class="basicAutoSelectSelected"></code>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row mb-3">
|
||||
<label class="col-lg-3">
|
||||
Default Selected (<a href="test-select-simple.json">list of { value, strings }</a>)
|
||||
</label>
|
||||
<div class="col-lg-9">
|
||||
<select class="form-control defaultAutoSelect" id="dAS" name="default_select"
|
||||
data-url="test-select-simple.json"
|
||||
data-default-value="3" data-default-text="Docker"
|
||||
autocomplete="off"></select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row mb-3">
|
||||
<label class="col-lg-3">
|
||||
No results (<a href="test-empty.json">empty list</a>)
|
||||
</label>
|
||||
<div class="col-lg-9">
|
||||
<select class="form-control emptyAutoSelect" name="empty_select"
|
||||
data-url="test-empty.json"
|
||||
data-noresults-text="Nothing to see here."
|
||||
autocomplete="off"></select>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend class="border-bottom">
|
||||
In Bootstrap modal
|
||||
</legend>
|
||||
<div class="row">
|
||||
<div class="col-lg-9 offset-lg-3">
|
||||
<button type="button" class="btn btn-primary" autocomplete="off"
|
||||
data-toggle="modal" data-target="#testModal">
|
||||
Open Test Modal
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>Javascript API</legend>
|
||||
<div class="form-row mb-3">
|
||||
<label class="col-lg-3">
|
||||
Change selected value programmatically
|
||||
</label>
|
||||
<div class="col-lg-9">
|
||||
<select class="form-control changeAutoSelect" name="change_select"
|
||||
data-url="test-select-simple.json"
|
||||
data-noresults-text="Nothing to see here."
|
||||
data-default-value="x123" data-default-text="Default text before change"
|
||||
autocomplete="off"></select>
|
||||
<br>
|
||||
<button type="button" class="btn btn-outline-secondary btnChangeAutoSelect" autocomplete="off"
|
||||
data-value="1" data-text="Selected Value 1">
|
||||
Set a different selected value
|
||||
</button>
|
||||
<button type="button" class="btn btn-outline-secondary btnChangeAutoSelect" autocomplete="off"
|
||||
data-value="2" data-text="Selected Value 2">
|
||||
Set a different selected value 2
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>Events</legend>
|
||||
<div class="form-row mb-3">
|
||||
<label class="col-lg-3">
|
||||
Events in text field
|
||||
</label>
|
||||
<div class="col-lg-9">
|
||||
<input class="form-control eventsAutoComplete" type="text" autocomplete="off">
|
||||
<br>
|
||||
<code><pre id="eventsCodeContainer"></pre></code>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="modal fade" id="testModal" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<h4 class="modal-title">Modal title</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<select class="form-control basicModalAutoSelect" name="simple_select"
|
||||
placeholder="type to search..."
|
||||
data-url="test-select-simple.json" autocomplete="off"></select>
|
||||
<code class="basicModalAutoSelectSelected"></code>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
||||
</div>
|
||||
</div><!-- /.modal-content -->
|
||||
</div><!-- /.modal-dialog -->
|
||||
</div><!-- /.modal -->
|
||||
|
||||
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js" integrity="sha384-cs/chFZiN24E4KMATLdqdvsezGxaGsi4hLGOzlXwp5UZB1LY//20VyM2taTB4QvJ" crossorigin="anonymous"></script>
|
||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js" integrity="sha384-uefMccjFJAIv6A+rW+L4AHf99KvxDjWSu1z9VI8SKNVmz4sk7buKt/6v9KI65qnm" crossorigin="anonymous"></script>
|
||||
<script src="../bootstrap-autocomplete.js"></script>
|
||||
<script>
|
||||
$(function () {
|
||||
// Basic
|
||||
$('.basicAutoComplete').autoComplete({
|
||||
resolverSettings: {
|
||||
url: 'test-list.json'
|
||||
}
|
||||
});
|
||||
|
||||
$('.basicAutoComplete').on('change', function (e) {
|
||||
console.log('change');
|
||||
});
|
||||
|
||||
$('.basicAutoComplete').on('autocomplete.select', function (evt, item) {
|
||||
$('.basicAutoCompleteSelected').html(JSON.stringify(item));
|
||||
$('.basicAutoCompleteCustom').html('');
|
||||
});
|
||||
|
||||
$('.basicAutoComplete').on('autocomplete.freevalue', function (evt, value) {
|
||||
$('.basicAutoCompleteCustom').html(JSON.stringify(value));
|
||||
$('.basicAutoCompleteSelected').html('');
|
||||
});
|
||||
|
||||
// Advanced 1
|
||||
$('.advancedAutoComplete').autoComplete({
|
||||
resolver: 'custom',
|
||||
events: {
|
||||
search: function (qry, callback) {
|
||||
// let's do a custom ajax call
|
||||
$.ajax(
|
||||
'test-dict.json',
|
||||
{
|
||||
data: { 'qry': qry}
|
||||
}
|
||||
).done(function (res) {
|
||||
callback(res.results)
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Advanced 2
|
||||
$('.advanced2AutoComplete').autoComplete({
|
||||
resolver: 'custom',
|
||||
formatResult: function (item) {
|
||||
return {
|
||||
value: item.id,
|
||||
text: "[" + item.id + "] " + item.text,
|
||||
html: [
|
||||
$('<img>').attr('src', item.icon).css("height", 18), ' ',
|
||||
item.text
|
||||
]
|
||||
};
|
||||
},
|
||||
events: {
|
||||
search: function (qry, callback) {
|
||||
// let's do a custom ajax call
|
||||
$.ajax(
|
||||
'test-dict.json',
|
||||
{
|
||||
data: { 'qry': qry}
|
||||
}
|
||||
).done(function (res) {
|
||||
callback(res.results)
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Basic Select
|
||||
$('.basicAutoSelect').autoComplete();
|
||||
$('.basicAutoSelect').on('autocomplete.select', function (evt, item) {
|
||||
console.log('select');
|
||||
$('.basicAutoSelectSelected').html(JSON.stringify(item));
|
||||
});
|
||||
|
||||
// Default Select
|
||||
$('.defaultAutoSelect').autoComplete();
|
||||
$('#dAS').on('autocomplete.select', function (e, i) {
|
||||
console.log('selected');
|
||||
});
|
||||
|
||||
// Empty Select
|
||||
$('.emptyAutoSelect').autoComplete();
|
||||
|
||||
// Modal
|
||||
$('.basicModalAutoSelect').autoComplete();
|
||||
$('.basicModalAutoSelect').on('autocomplete.select', function (evt, item) {
|
||||
console.log('select');
|
||||
$('.basicModalAutoSelectSelected').html(JSON.stringify(item));
|
||||
});
|
||||
|
||||
// Change default value programmatically.
|
||||
// Let's simulate a real world example.
|
||||
// Some point in time we initialize the autocomplete with a default value (defined by markup)
|
||||
$('.changeAutoSelect').autoComplete();
|
||||
// user then clicks on some button and we need to change that default value
|
||||
$('.btnChangeAutoSelect').on('click', function () {
|
||||
var e = $(this);
|
||||
$('.changeAutoSelect').autoComplete('set', { value: e.data('value'), text: e.data('text')});
|
||||
});
|
||||
|
||||
// Events
|
||||
var eventsCodeContainer = $('#eventsCodeContainer');
|
||||
|
||||
$('.eventsAutoComplete').autoComplete({
|
||||
resolverSettings: {
|
||||
url: 'test-list.json'
|
||||
}
|
||||
});
|
||||
$('.eventsAutoComplete').on('change', function() {
|
||||
console.log('eventsAutoComplete change');
|
||||
eventsCodeContainer.text(eventsCodeContainer.text() + 'fired change. value: ' + $(this).val() + '\n');
|
||||
});
|
||||
$('.eventsAutoComplete').on('autocomplete.select', function(evt, item) {
|
||||
console.log('eventsAutoComplete autocomplete.select');
|
||||
eventsCodeContainer.text(eventsCodeContainer.text() + 'fired autocomplete.select. item: ' + item + ' value: ' + $(this).val() + '\n');
|
||||
});
|
||||
$('.eventsAutoComplete').on('autocomplete.freevalue', function(evt, item) {
|
||||
console.log('eventsAutoComplete autocomplete.freevalue');
|
||||
eventsCodeContainer.text(eventsCodeContainer.text() + 'fired autocomplete.freevalue. item: ' + item + ' value: ' + $(this).val() + '\n');
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
56
static/node_modules/bootstrap-autocomplete/dist/latest/testdata/test-issue-35.html
generated
vendored
56
static/node_modules/bootstrap-autocomplete/dist/latest/testdata/test-issue-35.html
generated
vendored
|
@ -1,56 +0,0 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Bootstrap AutoComplete Test Issue 35</title>
|
||||
|
||||
<!-- Required meta tags -->
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" integrity="sha384-9gVQ4dYFwwWSjIDZnLEWnxCjeSWFphJiwGPXr1jddIhOegiu1FwO5qRGvFXOdJZ4" crossorigin="anonymous">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1 class="border-bottom">Bootstrap Autocomplete test issue 35</h1>
|
||||
<p>
|
||||
Testing page for <a href="https://github.com/xcash/bootstrap-autocomplete/issues/35">issue #35</a>
|
||||
</p>
|
||||
<form action="//httpbin.org" method="GET" target="_blank">
|
||||
<input class="form-control basicAutoComplete" name="q" type="text" autocomplete="off">
|
||||
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js" integrity="sha384-cs/chFZiN24E4KMATLdqdvsezGxaGsi4hLGOzlXwp5UZB1LY//20VyM2taTB4QvJ" crossorigin="anonymous"></script>
|
||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js" integrity="sha384-uefMccjFJAIv6A+rW+L4AHf99KvxDjWSu1z9VI8SKNVmz4sk7buKt/6v9KI65qnm" crossorigin="anonymous"></script>
|
||||
<script src="../bootstrap-autocomplete.js"></script>
|
||||
<script>
|
||||
$(function () {
|
||||
// Basic
|
||||
$('.basicAutoComplete').autoComplete({
|
||||
minLength: 0,
|
||||
resolverSettings: {
|
||||
url: 'test-list.json'
|
||||
},
|
||||
events: {
|
||||
search: () => {
|
||||
console.log('basicAutoComplete search');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Events
|
||||
$('.basicAutoComplete').on('change', function() {
|
||||
console.log('basicAutoComplete change');
|
||||
});
|
||||
$('.basicAutoComplete').on('autocomplete.select', function(evt, item) {
|
||||
console.log('basicAutoComplete autocomplete.select');
|
||||
});
|
||||
$('.basicAutoComplete').on('autocomplete.freevalue', function(evt, item) {
|
||||
console.log('basicAutoComplete autocomplete.freevalue');
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
51
static/node_modules/bootstrap-autocomplete/dist/latest/testdata/test-issue-59.html
generated
vendored
51
static/node_modules/bootstrap-autocomplete/dist/latest/testdata/test-issue-59.html
generated
vendored
|
@ -1,51 +0,0 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Bootstrap AutoComplete Test Issue 35</title>
|
||||
|
||||
<!-- Required meta tags -->
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1 class="border-bottom">Bootstrap Autocomplete test issue 59</h1>
|
||||
<p>
|
||||
Testing page for <a href="https://github.com/xcash/bootstrap-autocomplete/issues/59">issue #59</a>
|
||||
</p>
|
||||
<form action="//httpbin.org/anything" method="GET" target="_blank">
|
||||
<input class="form-control basicAutoComplete" name="q" type="text" autocomplete="off">
|
||||
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
|
||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
|
||||
<script src="../bootstrap-autocomplete.js"></script>
|
||||
<script>
|
||||
$(function () {
|
||||
// Basic
|
||||
$('.basicAutoComplete').autoComplete({
|
||||
resolverSettings: {
|
||||
url: 'test-list.json'
|
||||
},
|
||||
// preventEnter: true
|
||||
});
|
||||
|
||||
// Events
|
||||
$('.basicAutoComplete').on('change', function() {
|
||||
console.log('basicAutoComplete change');
|
||||
});
|
||||
$('.basicAutoComplete').on('autocomplete.select', function(evt, item) {
|
||||
console.log('basicAutoComplete autocomplete.select');
|
||||
});
|
||||
$('.basicAutoComplete').on('autocomplete.freevalue', function(evt, item) {
|
||||
console.log('basicAutoComplete autocomplete.freevalue');
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
70
static/node_modules/bootstrap-autocomplete/dist/latest/testdata/test-issue-80.html
generated
vendored
70
static/node_modules/bootstrap-autocomplete/dist/latest/testdata/test-issue-80.html
generated
vendored
|
@ -1,70 +0,0 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Bootstrap AutoComplete Test Issue 80</title>
|
||||
|
||||
<!-- Required meta tags -->
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1 class="border-bottom">Bootstrap Autocomplete test issue 80</h1>
|
||||
<p>
|
||||
Testing page for <a href="https://github.com/xcash/bootstrap-autocomplete/issues/80">issue #80</a>
|
||||
</p>
|
||||
<form action="//httpbin.org/anything" method="GET" target="_blank">
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<input class="form-control basicAutoComplete" name="q" type="text" autocomplete="off">
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<script src="http://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
|
||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js" integrity="sha384-B4gt1jrGC7Jh4AgTPSdUtOBvfO8shuf57BaghqFfPlYxofvL8/KUEfYiJOMMV+rV" crossorigin="anonymous"></script>
|
||||
<script src="../bootstrap-autocomplete.js"></script>
|
||||
<script>
|
||||
$(function () {
|
||||
var cbNR = $('#returnNoResults');
|
||||
|
||||
var results = [];
|
||||
for (var i=111; i<99999; i++) {
|
||||
results.push(i.toString());
|
||||
}
|
||||
|
||||
$('.basicAutoComplete').autoComplete({
|
||||
resolver: 'custom',
|
||||
// noResultsText: '',
|
||||
events: {
|
||||
search: function (qry, callback) {
|
||||
var res = results.filter( (v) => {
|
||||
if (v.indexOf(qry) > -1) {
|
||||
return v;
|
||||
}
|
||||
})
|
||||
callback(res);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Events
|
||||
$('.basicAutoComplete').on('change', function() {
|
||||
console.log('basicAutoComplete change');
|
||||
});
|
||||
$('.basicAutoComplete').on('autocomplete.select', function(evt, item) {
|
||||
console.log('basicAutoComplete autocomplete.select');
|
||||
});
|
||||
$('.basicAutoComplete').on('autocomplete.freevalue', function(evt, item) {
|
||||
console.log('basicAutoComplete autocomplete.freevalue');
|
||||
});
|
||||
|
||||
$('.basicAutoComplete').focus();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
66
static/node_modules/bootstrap-autocomplete/dist/latest/testdata/test-issue-83.html
generated
vendored
66
static/node_modules/bootstrap-autocomplete/dist/latest/testdata/test-issue-83.html
generated
vendored
|
@ -1,66 +0,0 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Bootstrap AutoComplete Test Issue 83</title>
|
||||
|
||||
<!-- Required meta tags -->
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1 class="border-bottom">Bootstrap Autocomplete test issue 83</h1>
|
||||
<p>
|
||||
Testing page for <a href="https://github.com/xcash/bootstrap-autocomplete/issues/83">issue #83</a>
|
||||
</p>
|
||||
<form action="//httpbin.org/anything" method="GET" target="_blank">
|
||||
<input class="form-control basicAutoComplete" name="q" type="text" autocomplete="off">
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<script src="http://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
|
||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js" integrity="sha384-B4gt1jrGC7Jh4AgTPSdUtOBvfO8shuf57BaghqFfPlYxofvL8/KUEfYiJOMMV+rV" crossorigin="anonymous"></script>
|
||||
<script src="../bootstrap-autocomplete.js"></script>
|
||||
<script>
|
||||
$(function () {
|
||||
var cbNR = $('#returnNoResults');
|
||||
var results = [
|
||||
"abc",
|
||||
"abcd",
|
||||
"abcde"
|
||||
]
|
||||
|
||||
$('.basicAutoComplete').autoComplete({
|
||||
resolver: 'custom',
|
||||
// noResultsText: '',
|
||||
events: {
|
||||
search: function (qry, callback) {
|
||||
var res = results.filter( (v) => {
|
||||
if (v.indexOf(qry) > -1) {
|
||||
return v;
|
||||
}
|
||||
})
|
||||
callback(res);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Events
|
||||
$('.basicAutoComplete').on('change', function() {
|
||||
console.log('basicAutoComplete change');
|
||||
});
|
||||
$('.basicAutoComplete').on('autocomplete.select', function(evt, item) {
|
||||
console.log('basicAutoComplete autocomplete.select');
|
||||
});
|
||||
$('.basicAutoComplete').on('autocomplete.freevalue', function(evt, item) {
|
||||
console.log('basicAutoComplete autocomplete.freevalue');
|
||||
});
|
||||
|
||||
$('.basicAutoComplete').focus();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,6 +0,0 @@
|
|||
[
|
||||
"Google Cloud Platform",
|
||||
"Amazon AWS",
|
||||
"Docker",
|
||||
"Digital Ocean"
|
||||
]
|
|
@ -1,6 +0,0 @@
|
|||
[
|
||||
{ "value": 1, "text": "Google Cloud Platform" },
|
||||
{ "value": 2, "text": "Amazon AWS" },
|
||||
{ "value": 3, "text": "Docker" },
|
||||
{ "value": 4, "text": "Digital Ocean" }
|
||||
]
|
|
@ -1,42 +0,0 @@
|
|||
{
|
||||
"name": "bootstrap-autocomplete",
|
||||
"version": "2.3.7",
|
||||
"description": "Autocomplete for Bootstrap version 4.",
|
||||
"keywords": [
|
||||
"bootstrap",
|
||||
"autocomplete",
|
||||
"bootstrap-autocomplete",
|
||||
"typeahead",
|
||||
"suggest"
|
||||
],
|
||||
"main": "./dist/latest/bootstrap-autocomplete.js",
|
||||
"repository": "git+https://github.com/xcash/bootstrap-autocomplete.git",
|
||||
"author": "Paolo Casciello <paolo.casciello@scalebox.it>",
|
||||
"license": "MIT",
|
||||
"files": [
|
||||
"dist/*",
|
||||
"src/*"
|
||||
],
|
||||
"scripts": {
|
||||
"test": "gulp test"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bootstrap": "^4.2.1",
|
||||
"@types/jquery": "^3.3.29",
|
||||
"ansi-colors": "^4.1.1",
|
||||
"browser-sync": "^2.26.3",
|
||||
"del": "^5.1.0",
|
||||
"fancy-log": "^1.3.3",
|
||||
"gulp": "^4.0.0",
|
||||
"gulp-plumber": "^1.2.1",
|
||||
"gulp-rename": "^2.0.0",
|
||||
"gulp-size": "^3.0.0",
|
||||
"gulp-tslint": "^8.1.4",
|
||||
"gulp-uglify": "^3.0.1",
|
||||
"ts-loader": "^6.2.2",
|
||||
"tslint": "^6.1.0",
|
||||
"typescript": "^3.3.3",
|
||||
"webpack-stream": "^5.2.1"
|
||||
},
|
||||
"dependencies": {}
|
||||
}
|
|
@ -1,230 +0,0 @@
|
|||
/*
|
||||
* Dropdown class. Manages the dropdown drawing
|
||||
*/
|
||||
export class DropdownV3 {
|
||||
protected _$el: JQuery;
|
||||
protected _dd: JQuery;
|
||||
protected initialized: boolean = false;
|
||||
protected shown: boolean = false;
|
||||
protected items: any[] = [];
|
||||
protected formatItem: (item: any) => any;
|
||||
protected searchText: string;
|
||||
protected autoSelect: boolean;
|
||||
protected mouseover: boolean;
|
||||
protected ddMouseover: boolean = false;
|
||||
protected noResultsText: string;
|
||||
|
||||
constructor(e: JQuery, formatItemCbk: (item: any) => any, autoSelect: boolean, noResultsText: string) {
|
||||
this._$el = e;
|
||||
this.formatItem = formatItemCbk;
|
||||
this.autoSelect = autoSelect;
|
||||
this.noResultsText = noResultsText;
|
||||
|
||||
// initialize it in lazy mode to deal with glitches like modals
|
||||
// this.init();
|
||||
}
|
||||
|
||||
protected init(): void {
|
||||
// Initialize dropdown
|
||||
const pos: any = $.extend({}, this._$el.position(), {
|
||||
height: this._$el[0].offsetHeight
|
||||
});
|
||||
|
||||
// create element
|
||||
this._dd = $('<ul />');
|
||||
// add our class and basic dropdown-menu class
|
||||
this._dd.addClass('bootstrap-autocomplete dropdown-menu');
|
||||
|
||||
this._dd.insertAfter(this._$el);
|
||||
this._dd.css({ top: pos.top + this._$el.outerHeight(), left: pos.left, width: this._$el.outerWidth() });
|
||||
|
||||
// click event on items
|
||||
this._dd.on('click', 'li', (evt: JQueryEventObject) => {
|
||||
// console.log('clicked', evt.currentTarget);
|
||||
// console.log($(evt.currentTarget));
|
||||
const item: any = $(evt.currentTarget).data('item');
|
||||
this.itemSelectedLaunchEvent(item);
|
||||
});
|
||||
|
||||
this._dd.on('keyup', (evt: JQueryEventObject) => {
|
||||
if (this.shown) {
|
||||
switch (evt.which) {
|
||||
case 27:
|
||||
// ESC
|
||||
this.hide();
|
||||
this._$el.focus();
|
||||
break;
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
this._dd.on('mouseenter', (evt: JQueryEventObject) => {
|
||||
this.ddMouseover = true;
|
||||
});
|
||||
|
||||
this._dd.on('mouseleave', (evt: JQueryEventObject) => {
|
||||
this.ddMouseover = false;
|
||||
});
|
||||
|
||||
this._dd.on('mouseenter', 'li', (evt: JQueryEventObject) => {
|
||||
if (this.haveResults) {
|
||||
$(evt.currentTarget).closest('ul').find('li.active').removeClass('active');
|
||||
$(evt.currentTarget).addClass('active');
|
||||
this.mouseover = true;
|
||||
}
|
||||
});
|
||||
|
||||
this._dd.on('mouseleave', 'li', (evt: JQueryEventObject) => {
|
||||
this.mouseover = false;
|
||||
});
|
||||
|
||||
this.initialized = true;
|
||||
|
||||
}
|
||||
|
||||
private checkInitialized(): void {
|
||||
// Lazy init
|
||||
if (!this.initialized) {
|
||||
// if not already initialized
|
||||
this.init();
|
||||
}
|
||||
}
|
||||
|
||||
get isMouseOver(): boolean {
|
||||
return this.mouseover;
|
||||
}
|
||||
|
||||
get isDdMouseOver(): boolean {
|
||||
return this.ddMouseover;
|
||||
}
|
||||
|
||||
get haveResults(): boolean {
|
||||
return (this.items.length > 0);
|
||||
}
|
||||
|
||||
public focusNextItem(reversed?: boolean) {
|
||||
if (this.haveResults) {
|
||||
// get selected
|
||||
const currElem: JQuery = this._dd.find('li.active');
|
||||
let nextElem: JQuery = reversed ? currElem.prev() : currElem.next();
|
||||
|
||||
if (nextElem.length === 0) {
|
||||
// first
|
||||
nextElem = reversed ? this._dd.find('li').last() : this._dd.find('li').first();
|
||||
}
|
||||
|
||||
currElem.removeClass('active');
|
||||
nextElem.addClass('active');
|
||||
}
|
||||
}
|
||||
|
||||
public focusPreviousItem() {
|
||||
this.focusNextItem(true);
|
||||
}
|
||||
|
||||
public selectFocusItem() {
|
||||
this._dd.find('li.active').trigger('click');
|
||||
}
|
||||
|
||||
get isItemFocused(): boolean {
|
||||
if (this.isShown() && (this._dd.find('li.active').length > 0)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public show(): void {
|
||||
if (!this.shown) {
|
||||
this._dd.dropdown().show();
|
||||
this.shown = true;
|
||||
}
|
||||
}
|
||||
|
||||
public isShown(): boolean {
|
||||
return this.shown;
|
||||
}
|
||||
|
||||
public hide(): void {
|
||||
if (this.shown) {
|
||||
this._dd.dropdown().hide();
|
||||
this.shown = false;
|
||||
}
|
||||
}
|
||||
|
||||
public updateItems(items: any[], searchText: string) {
|
||||
// console.log('updateItems', items);
|
||||
this.items = items;
|
||||
this.searchText = searchText;
|
||||
this.refreshItemList();
|
||||
}
|
||||
|
||||
private showMatchedText(text: string, qry: string): string {
|
||||
const startIndex: number = text.toLowerCase().indexOf(qry.toLowerCase());
|
||||
if (startIndex > -1) {
|
||||
const endIndex: number = startIndex + qry.length;
|
||||
|
||||
return text.slice(0, startIndex) + '<b>'
|
||||
+ text.slice(startIndex, endIndex) + '</b>'
|
||||
+ text.slice(endIndex);
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
protected refreshItemList() {
|
||||
this.checkInitialized();
|
||||
this._dd.empty();
|
||||
const liList: JQuery[] = [];
|
||||
if (this.items.length > 0) {
|
||||
this.items.forEach(item => {
|
||||
let itemFormatted: any = this.formatItem(item);
|
||||
if (typeof itemFormatted === 'string') {
|
||||
itemFormatted = { text: itemFormatted }
|
||||
}
|
||||
let itemText: string;
|
||||
let itemHtml: any;
|
||||
|
||||
itemText = this.showMatchedText(itemFormatted.text, this.searchText);
|
||||
if (itemFormatted.html !== undefined) {
|
||||
itemHtml = itemFormatted.html;
|
||||
} else {
|
||||
itemHtml = itemText;
|
||||
}
|
||||
|
||||
const disabledItem = itemFormatted.disabled;
|
||||
|
||||
const li = $('<li >');
|
||||
li.append(
|
||||
$('<a>').attr('href', '#!').html(itemHtml)
|
||||
)
|
||||
.data('item', item);
|
||||
|
||||
if (disabledItem) {
|
||||
li.addClass('disabled');
|
||||
}
|
||||
|
||||
liList.push(li);
|
||||
});
|
||||
} else {
|
||||
// No results
|
||||
const li = $('<li >');
|
||||
li.append(
|
||||
$('<a>').attr('href', '#!').html(this.noResultsText)
|
||||
)
|
||||
.addClass('disabled');
|
||||
|
||||
liList.push(li);
|
||||
}
|
||||
|
||||
|
||||
this._dd.append(liList);
|
||||
}
|
||||
|
||||
protected itemSelectedLaunchEvent(item: any): void {
|
||||
// launch selected event
|
||||
// console.log('itemSelectedLaunchEvent', item);
|
||||
this._$el.trigger('autocomplete.select', item)
|
||||
}
|
||||
|
||||
}
|
|
@ -1,247 +0,0 @@
|
|||
/*
|
||||
* Dropdown class. Manages the dropdown drawing
|
||||
*/
|
||||
|
||||
export class DropdownV4 {
|
||||
// For Bootstrap 4 new dropdown syntax
|
||||
protected _$el: JQuery;
|
||||
// dropdown element
|
||||
protected _dd: JQuery;
|
||||
protected initialized: boolean = false;
|
||||
protected shown: boolean = false;
|
||||
protected items: any[] = [];
|
||||
protected formatItem: (item: any) => any;
|
||||
protected searchText: string;
|
||||
protected autoSelect: boolean;
|
||||
protected mouseover: boolean;
|
||||
protected ddMouseover: boolean = false;
|
||||
protected noResultsText: string;
|
||||
|
||||
constructor(e: JQuery, formatItemCbk: (item: any) => any, autoSelect: boolean, noResultsText: string) {
|
||||
this._$el = e;
|
||||
this.formatItem = formatItemCbk;
|
||||
this.autoSelect = autoSelect;
|
||||
this.noResultsText = noResultsText;
|
||||
|
||||
// initialize it in lazy mode to deal with glitches like modals
|
||||
// this.init();
|
||||
}
|
||||
|
||||
protected getElPos(): any {
|
||||
const pos: any = $.extend({}, this._$el.position(), {
|
||||
height: this._$el[0].offsetHeight
|
||||
});
|
||||
return pos;
|
||||
}
|
||||
protected init(): void {
|
||||
// Initialize dropdown
|
||||
const pos = this.getElPos();
|
||||
|
||||
// create element
|
||||
this._dd = $('<div />');
|
||||
// add our class and basic dropdown-menu class
|
||||
this._dd.addClass('bootstrap-autocomplete dropdown-menu');
|
||||
|
||||
this._dd.insertAfter(this._$el);
|
||||
this._dd.css({ top: pos.top + this._$el.outerHeight(), left: pos.left, width: this._$el.outerWidth() });
|
||||
|
||||
// click event on items
|
||||
this._dd.on('click', '.dropdown-item', (evt: JQueryEventObject) => {
|
||||
// console.log('clicked', evt.currentTarget);
|
||||
// console.log($(evt.currentTarget));
|
||||
const item: any = $(evt.currentTarget).data('item');
|
||||
this.itemSelectedLaunchEvent(item);
|
||||
// stop default event on mouse click.
|
||||
evt.preventDefault();
|
||||
});
|
||||
|
||||
this._dd.on('keyup', (evt: JQueryEventObject) => {
|
||||
if (this.shown) {
|
||||
switch (evt.which) {
|
||||
case 27:
|
||||
// ESC
|
||||
this.hide();
|
||||
this._$el.focus();
|
||||
break;
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
this._dd.on('mouseenter', (evt: JQueryEventObject) => {
|
||||
this.ddMouseover = true;
|
||||
});
|
||||
|
||||
this._dd.on('mouseleave', (evt: JQueryEventObject) => {
|
||||
this.ddMouseover = false;
|
||||
});
|
||||
|
||||
this._dd.on('mouseenter', '.dropdown-item', (evt: JQueryEventObject) => {
|
||||
if (this.haveResults) {
|
||||
$(evt.currentTarget).closest('div').find('.dropdown-item.active').removeClass('active');
|
||||
$(evt.currentTarget).addClass('active');
|
||||
this.mouseover = true;
|
||||
}
|
||||
});
|
||||
|
||||
this._dd.on('mouseleave', '.dropdown-item', (evt: JQueryEventObject) => {
|
||||
this.mouseover = false;
|
||||
});
|
||||
|
||||
this.initialized = true;
|
||||
|
||||
}
|
||||
|
||||
private checkInitialized(): void {
|
||||
// Lazy init
|
||||
if (!this.initialized) {
|
||||
// if not already initialized
|
||||
this.init();
|
||||
}
|
||||
}
|
||||
|
||||
get isMouseOver(): boolean {
|
||||
return this.mouseover;
|
||||
}
|
||||
|
||||
get isDdMouseOver(): boolean {
|
||||
return this.ddMouseover;
|
||||
}
|
||||
|
||||
get haveResults(): boolean {
|
||||
return (this.items.length > 0);
|
||||
}
|
||||
|
||||
public focusNextItem(reversed?: boolean) {
|
||||
if (this.haveResults) {
|
||||
// get selected
|
||||
const currElem: JQuery = this._dd.find('.dropdown-item.active');
|
||||
let nextElem: JQuery = reversed ? currElem.prev() : currElem.next();
|
||||
|
||||
if (nextElem.length === 0) {
|
||||
// first
|
||||
nextElem = reversed ? this._dd.find('.dropdown-item').last() : this._dd.find('.dropdown-item').first();
|
||||
}
|
||||
|
||||
currElem.removeClass('active');
|
||||
nextElem.addClass('active');
|
||||
}
|
||||
}
|
||||
|
||||
public focusPreviousItem() {
|
||||
this.focusNextItem(true);
|
||||
}
|
||||
|
||||
public selectFocusItem() {
|
||||
this._dd.find('.dropdown-item.active').trigger('click');
|
||||
}
|
||||
|
||||
get isItemFocused(): boolean {
|
||||
if (this._dd && this.isShown() && (this._dd.find('.dropdown-item.active').length > 0)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public show(): void {
|
||||
if (!this.shown) {
|
||||
const pos = this.getElPos();
|
||||
// this._dd.css({ top: pos.top + this._$el.outerHeight(), left: pos.left, width: this._$el.outerWidth() });
|
||||
this._dd.addClass('show');
|
||||
this.shown = true;
|
||||
this._$el.trigger('autocomplete.dd.shown');
|
||||
}
|
||||
}
|
||||
|
||||
public isShown(): boolean {
|
||||
return this.shown;
|
||||
}
|
||||
|
||||
public hide(): void {
|
||||
if (this.shown) {
|
||||
this._dd.removeClass('show');
|
||||
this.shown = false;
|
||||
this._$el.trigger('autocomplete.dd.hidden');
|
||||
}
|
||||
}
|
||||
|
||||
public updateItems(items: any[], searchText: string) {
|
||||
// console.log('updateItems', items);
|
||||
this.items = items;
|
||||
this.searchText = searchText;
|
||||
this.refreshItemList();
|
||||
}
|
||||
|
||||
private showMatchedText(text: string, qry: string): string {
|
||||
const startIndex: number = text.toLowerCase().indexOf(qry.toLowerCase());
|
||||
if (startIndex > -1) {
|
||||
const endIndex: number = startIndex + qry.length;
|
||||
|
||||
return text.slice(0, startIndex) + '<b>'
|
||||
+ text.slice(startIndex, endIndex) + '</b>'
|
||||
+ text.slice(endIndex);
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
protected refreshItemList() {
|
||||
this.checkInitialized();
|
||||
this._dd.empty();
|
||||
const liList: JQuery[] = [];
|
||||
if (this.items.length > 0) {
|
||||
this.items.forEach(item => {
|
||||
let itemFormatted: any = this.formatItem(item);
|
||||
if (typeof itemFormatted === 'string') {
|
||||
itemFormatted = { text: itemFormatted }
|
||||
}
|
||||
let itemText: string;
|
||||
let itemHtml: any;
|
||||
|
||||
itemText = this.showMatchedText(itemFormatted.text, this.searchText);
|
||||
if (itemFormatted.html !== undefined) {
|
||||
itemHtml = itemFormatted.html;
|
||||
} else {
|
||||
itemHtml = itemText;
|
||||
}
|
||||
|
||||
const disabledItem = itemFormatted.disabled;
|
||||
|
||||
const li = $('<a >');
|
||||
li.addClass('dropdown-item')
|
||||
.css({ 'overflow': 'hidden', 'text-overflow': 'ellipsis' })
|
||||
.html(itemHtml)
|
||||
.data('item', item);
|
||||
|
||||
if (disabledItem) {
|
||||
li.addClass('disabled');
|
||||
}
|
||||
liList.push(li);
|
||||
});
|
||||
this._dd.append(liList);
|
||||
this.show();
|
||||
} else {
|
||||
// No results
|
||||
if (this.noResultsText === '') {
|
||||
// hide the dropdown
|
||||
this.hide();
|
||||
} else {
|
||||
// show no results message
|
||||
const li = $('<a >');
|
||||
li.addClass('dropdown-item disabled')
|
||||
.html(this.noResultsText);
|
||||
|
||||
liList.push(li);
|
||||
this._dd.append(liList);
|
||||
this.show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected itemSelectedLaunchEvent(item: any): void {
|
||||
// launch selected event
|
||||
// console.log('itemSelectedLaunchEvent', item);
|
||||
this._$el.trigger('autocomplete.select', item)
|
||||
}
|
||||
|
||||
}
|
|
@ -1,350 +0,0 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Bootstrap AutoComplete Demo Bootstrap 4</title>
|
||||
|
||||
<!-- Required meta tags -->
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
|
||||
<link rel="stylesheet" href="//stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1 class="border-bottom">Bootstrap Autocomplete (for Bootstrap version 4)</h1>
|
||||
<p>
|
||||
This page acts like a Demo page and a Testing page.
|
||||
</p>
|
||||
<form>
|
||||
<fieldset>
|
||||
<legend class="border-bottom">AJAX</legend>
|
||||
<div class="form-row mb-3">
|
||||
<label class="col-lg-3">
|
||||
Basic (<a href="testdata/test-list.json">list of strings</a>)
|
||||
</label>
|
||||
<div class="col-lg-9">
|
||||
<input class="form-control basicAutoComplete" type="text" autocomplete="off">
|
||||
Selected item: <code class="basicAutoCompleteSelected"></code><br>
|
||||
Custom value: <code class="basicAutoCompleteCustom"></code>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row mb-3">
|
||||
<label class="col-lg-3">
|
||||
Basic (<a href="testdata/test-list.json">list of strings</a> - custom <code>search</code> parameter)
|
||||
</label>
|
||||
<div class="col-lg-9">
|
||||
<input class="form-control basicAutoCompleteQParameter" type="text" autocomplete="off">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row mb-3">
|
||||
<label class="col-lg-3">
|
||||
Advanced (<a href="testdata/test-dict.json">complex object</a>)
|
||||
</label>
|
||||
<div class="col-lg-9">
|
||||
<input class="form-control advancedAutoComplete" type="text" autocomplete="off" placeholder="type to search...">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row mb-3">
|
||||
<label class="col-lg-3">
|
||||
Advanced (<a href="testdata/test-dict.json">complex object</a> - custom formatting)
|
||||
</label>
|
||||
<div class="col-lg-9">
|
||||
<input class="form-control advanced2AutoComplete" type="text" autocomplete="off">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row mb-3">
|
||||
<label class="col-lg-3">
|
||||
Show dropdown programmatically.
|
||||
</label>
|
||||
<div class="col-lg-7">
|
||||
<input class="form-control basicAutoCompleteShowDropdown" data-url="testdata/test-list.json" type="text" autocomplete="off">
|
||||
</div>
|
||||
<div class="col-lg-2">
|
||||
<button type="button" class="btn btn-block btn-outline-secondary basicAutoCompleteShowBtn">
|
||||
Show
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend class="border-bottom">
|
||||
<code><select></code> as Autocomplete
|
||||
</legend>
|
||||
<div class="row">
|
||||
<div class="col-lg-9 offset-lg-3">
|
||||
<p>
|
||||
Selects are a subtype of autocomplete where the selected value is restricted to
|
||||
server-provided results. User <b>must</b> select one of those.
|
||||
</p>
|
||||
<p>
|
||||
Bootstrap-Autocomplete provides a smarter select rendered as a standard
|
||||
autocomplete <b>text</b> field. It substitutes the field with an
|
||||
<code><input type="search"></code> and creates a <i>shadow</i> hidden field with
|
||||
the selected value (and the original name).
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row mb-3">
|
||||
<label class="col-lg-3">
|
||||
Simple (<a href="testdata/test-select-simple.json">list of { value, strings }</a>)
|
||||
</label>
|
||||
<div class="col-lg-9">
|
||||
<select class="form-control basicAutoSelect" name="simple_select"
|
||||
placeholder="type to search..."
|
||||
data-url="testdata/test-select-simple.json" autocomplete="off"></select>
|
||||
<code class="basicAutoSelectSelected"></code>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row mb-3">
|
||||
<label class="col-lg-3">
|
||||
Default Selected (<a href="testdata/test-select-simple.json">list of { value, strings }</a>)
|
||||
</label>
|
||||
<div class="col-lg-9">
|
||||
<select class="form-control defaultAutoSelect" id="dAS" name="default_select"
|
||||
data-url="testdata/test-select-simple.json"
|
||||
data-default-value="3" data-default-text="Docker"
|
||||
autocomplete="off"></select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row mb-3">
|
||||
<label class="col-lg-3">
|
||||
No results (<a href="testdata/test-empty.json">empty list</a>)
|
||||
</label>
|
||||
<div class="col-lg-9">
|
||||
<select class="form-control emptyAutoSelect" name="empty_select"
|
||||
data-url="testdata/test-empty.json"
|
||||
data-noresults-text="Nothing to see here."
|
||||
autocomplete="off"></select>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend class="border-bottom">
|
||||
In Bootstrap modal
|
||||
</legend>
|
||||
<div class="row">
|
||||
<div class="col-lg-9 offset-lg-3">
|
||||
<button type="button" class="btn btn-primary" autocomplete="off"
|
||||
data-toggle="modal" data-target="#testModal">
|
||||
Open Test Modal
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>Javascript API</legend>
|
||||
<div class="form-row mb-3">
|
||||
<label class="col-lg-3">
|
||||
Change selected value programmatically
|
||||
</label>
|
||||
<div class="col-lg-9">
|
||||
<select class="form-control changeAutoSelect" name="change_select"
|
||||
data-url="testdata/test-select-simple.json"
|
||||
data-noresults-text="Nothing to see here."
|
||||
data-default-value="x123" data-default-text="Default text before change"
|
||||
autocomplete="off"></select>
|
||||
<br>
|
||||
<button type="button" class="btn btn-outline-secondary btnChangeAutoSelect" autocomplete="off"
|
||||
data-value="1" data-text="Selected Value 1">
|
||||
Set a different selected value
|
||||
</button>
|
||||
<button type="button" class="btn btn-outline-secondary btnChangeAutoSelect" autocomplete="off"
|
||||
data-value="2" data-text="Selected Value 2">
|
||||
Set a different selected value 2
|
||||
</button>
|
||||
<button type="button" class="btn btn-outline-secondary btnClearAutoSelect">
|
||||
Clear Value
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>Events</legend>
|
||||
<div class="form-row mb-3">
|
||||
<label class="col-lg-3">
|
||||
Events in text field
|
||||
</label>
|
||||
<div class="col-lg-9">
|
||||
<input class="form-control eventsAutoComplete" type="text" autocomplete="off">
|
||||
<br>
|
||||
<code><pre id="eventsCodeContainer"></pre></code>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="modal fade" id="testModal" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<h4 class="modal-title">Modal title</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<select class="form-control basicModalAutoSelect" name="simple_select"
|
||||
placeholder="type to search..."
|
||||
data-url="testdata/test-select-simple.json" autocomplete="off"></select>
|
||||
<code class="basicModalAutoSelectSelected"></code>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
||||
</div>
|
||||
</div><!-- /.modal-content -->
|
||||
</div><!-- /.modal-dialog -->
|
||||
</div><!-- /.modal -->
|
||||
|
||||
<script src="//code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
|
||||
<script src="//cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
|
||||
<script src="//stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js" integrity="sha384-B4gt1jrGC7Jh4AgTPSdUtOBvfO8shuf57BaghqFfPlYxofvL8/KUEfYiJOMMV+rV" crossorigin="anonymous"></script>
|
||||
<script src="bootstrap-autocomplete.js"></script>
|
||||
<script>
|
||||
$(function () {
|
||||
// Basic
|
||||
$('.basicAutoComplete').autoComplete({
|
||||
resolverSettings: {
|
||||
url: 'testdata/test-list.json'
|
||||
}
|
||||
});
|
||||
|
||||
$('.basicAutoComplete').on('change', function (e) {
|
||||
console.log('change');
|
||||
});
|
||||
|
||||
$('.basicAutoComplete').on('autocomplete.select', function (evt, item) {
|
||||
$('.basicAutoCompleteSelected').html(JSON.stringify(item));
|
||||
$('.basicAutoCompleteCustom').html('');
|
||||
});
|
||||
|
||||
$('.basicAutoComplete').on('autocomplete.freevalue', function (evt, value) {
|
||||
$('.basicAutoCompleteCustom').html(JSON.stringify(value));
|
||||
$('.basicAutoCompleteSelected').html('');
|
||||
});
|
||||
|
||||
$('.basicAutoCompleteShowDropdown').autoComplete({
|
||||
minLength: 0,
|
||||
});
|
||||
|
||||
$('.basicAutoCompleteShowBtn').on('click', function () {
|
||||
console.log('click');
|
||||
$('.basicAutoCompleteShowDropdown').autoComplete('show');
|
||||
});
|
||||
|
||||
$('.basicAutoCompleteQParameter').autoComplete({
|
||||
resolverSettings: {
|
||||
url: 'testdata/test-list.json',
|
||||
queryKey: 'search'
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// Advanced 1
|
||||
$('.advancedAutoComplete').autoComplete({
|
||||
resolver: 'custom',
|
||||
events: {
|
||||
search: function (qry, callback) {
|
||||
// let's do a custom ajax call
|
||||
$.ajax(
|
||||
'testdata/test-dict.json',
|
||||
{
|
||||
data: { 'qry': qry}
|
||||
}
|
||||
).done(function (res) {
|
||||
callback(res.results)
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Advanced 2
|
||||
$('.advanced2AutoComplete').autoComplete({
|
||||
resolver: 'custom',
|
||||
formatResult: function (item) {
|
||||
return {
|
||||
value: item.id,
|
||||
text: "[" + item.id + "] " + item.text,
|
||||
html: [
|
||||
$('<img>').attr('src', item.icon).css("height", 18), ' ',
|
||||
item.text
|
||||
]
|
||||
};
|
||||
},
|
||||
events: {
|
||||
search: function (qry, callback) {
|
||||
// let's do a custom ajax call
|
||||
$.ajax(
|
||||
'testdata/test-dict.json',
|
||||
{
|
||||
data: { 'qry': qry}
|
||||
}
|
||||
).done(function (res) {
|
||||
callback(res.results)
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Basic Select
|
||||
$('.basicAutoSelect').autoComplete();
|
||||
$('.basicAutoSelect').on('autocomplete.select', function (evt, item) {
|
||||
console.log('select', item);
|
||||
$('.basicAutoSelectSelected').html(item?JSON.stringify(item):'null');
|
||||
|
||||
});
|
||||
|
||||
// Default Select
|
||||
$('.defaultAutoSelect').autoComplete();
|
||||
$('#dAS').on('autocomplete.select', function (e, i) {
|
||||
console.log('selected');
|
||||
});
|
||||
|
||||
// Empty Select
|
||||
$('.emptyAutoSelect').autoComplete();
|
||||
|
||||
// Modal
|
||||
$('.basicModalAutoSelect').autoComplete();
|
||||
$('.basicModalAutoSelect').on('autocomplete.select', function (evt, item) {
|
||||
console.log('select');
|
||||
$('.basicModalAutoSelectSelected').html(JSON.stringify(item));
|
||||
});
|
||||
|
||||
// Change default value programmatically.
|
||||
// Let's simulate a real world example.
|
||||
// Some point in time we initialize the autocomplete with a default value (defined by markup)
|
||||
$('.changeAutoSelect').autoComplete();
|
||||
// user then clicks on some button and we need to change that default value
|
||||
$('.btnChangeAutoSelect').on('click', function () {
|
||||
var e = $(this);
|
||||
$('.changeAutoSelect').autoComplete('set', { value: e.data('value'), text: e.data('text')});
|
||||
});
|
||||
// clear current value
|
||||
$('.btnClearAutoSelect').on('click', function () {
|
||||
var e = $(this);
|
||||
// $('.changeAutoSelect').autoComplete('set', null);
|
||||
$('.changeAutoSelect').autoComplete('clear');
|
||||
|
||||
});
|
||||
|
||||
// Events
|
||||
var eventsCodeContainer = $('#eventsCodeContainer');
|
||||
|
||||
$('.eventsAutoComplete').autoComplete({
|
||||
resolverSettings: {
|
||||
url: 'testdata/test-list.json'
|
||||
}
|
||||
});
|
||||
$('.eventsAutoComplete').on('change', function() {
|
||||
console.log('eventsAutoComplete change');
|
||||
eventsCodeContainer.text(eventsCodeContainer.text() + 'fired change. value: ' + $(this).val() + '\n');
|
||||
});
|
||||
$('.eventsAutoComplete').on('autocomplete.select', function(evt, item) {
|
||||
console.log('eventsAutoComplete autocomplete.select');
|
||||
eventsCodeContainer.text(eventsCodeContainer.text() + 'fired autocomplete.select. item: ' + item + ' value: ' + $(this).val() + '\n');
|
||||
});
|
||||
$('.eventsAutoComplete').on('autocomplete.freevalue', function(evt, item) {
|
||||
console.log('eventsAutoComplete autocomplete.freevalue');
|
||||
eventsCodeContainer.text(eventsCodeContainer.text() + 'fired autocomplete.freevalue. item: ' + item + ' value: ' + $(this).val() + '\n');
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,259 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Bootstrap AutoComplete Demo</title>
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link href="//netdna.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1 class="page-header">Bootstrap Autocomplete</h1>
|
||||
<p>
|
||||
This page acts like a Demo page and a Testing page.
|
||||
</p>
|
||||
<form class="form-horizontal">
|
||||
<fieldset>
|
||||
<legend>AJAX</legend>
|
||||
<div class="form-group">
|
||||
<label class="col-lg-3 control-label">
|
||||
Basic (<a href="testdata/test-list.json">list of strings</a>)
|
||||
</label>
|
||||
<div class="col-lg-9">
|
||||
<input class="form-control basicAutoComplete" type="text" autocomplete="off">
|
||||
Selected item: <code class="basicAutoCompleteSelected"></code><br>
|
||||
Custom value: <code class="basicAutoCompleteCustom"></code>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-lg-3 control-label">
|
||||
Advanced (<a href="testdata/test-dict.json">complex object</a>)
|
||||
</label>
|
||||
<div class="col-lg-9">
|
||||
<input class="form-control advancedAutoComplete" type="text" autocomplete="off" placeholder="type to search...">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-lg-3 control-label">
|
||||
Advanced (<a href="testdata/test-dict.json">complex object</a> - custom formatting)
|
||||
</label>
|
||||
<div class="col-lg-9">
|
||||
<input class="form-control advanced2AutoComplete" type="text" autocomplete="off">
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend><code><select></code> as Autocomplete</legend>
|
||||
<div class="row">
|
||||
<div class="col-lg-9 col-lg-offset-3">
|
||||
<p>
|
||||
Selects are a subtype of autocomplete where the selected value is restricted to
|
||||
server-provided results. User <b>must</b> select one of those.
|
||||
</p>
|
||||
<p>
|
||||
Bootstrap-Autocomplete provides a smarter select rendered as a standard
|
||||
autocomplete <b>text</b> field. It substitutes the field with an
|
||||
<code><input type="text"></code and creates a <i>shadow</i> hidden field with
|
||||
the selected value (and the original name).
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-lg-3 control-label">
|
||||
Simple (<a href="testdata/test-select-simple.json">list of { value, strings }</a>)
|
||||
</label>
|
||||
<div class="col-lg-9">
|
||||
<select class="form-control basicAutoSelect" name="simple_select"
|
||||
placeholder="type to search..."
|
||||
data-url="testdata/test-select-simple.json" autocomplete="off"></select>
|
||||
<code class="basicAutoSelectSelected"></code>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-lg-3 control-label">
|
||||
Default Selected (<a href="testdata/test-select-simple.json">list of { value, strings }</a>)
|
||||
</label>
|
||||
<div class="col-lg-9">
|
||||
<select class="form-control defaultAutoSelect" id="dAS" name="default_select"
|
||||
data-url="testdata/test-select-simple.json"
|
||||
data-default-value="3" data-default-text="Docker"
|
||||
autocomplete="off"></select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-lg-3 control-label">
|
||||
No results (<a href="testdata/test-empty.json">empty list</a>)
|
||||
</label>
|
||||
<div class="col-lg-9">
|
||||
<select class="form-control emptyAutoSelect" name="empty_select"
|
||||
data-url="testdata/test-empty.json"
|
||||
data-noresults-text="Nothing to see here."
|
||||
autocomplete="off"></select>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>In Bootstrap modal</legend>
|
||||
<div class="row">
|
||||
<div class="col-lg-9 col-lg-offset-3">
|
||||
<button type="button" class="btn btn-primary" autocomplete="off"
|
||||
data-toggle="modal" data-target="#testModal">
|
||||
Open Test Modal
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>Javascript API</legend>
|
||||
<div class="form-group">
|
||||
<label class="col-lg-3 control-label">
|
||||
Change selected value programmatically
|
||||
</label>
|
||||
<div class="col-lg-9">
|
||||
<select class="form-control changeAutoSelect" name="change_select"
|
||||
data-url="testdata/test-select-simple.json"
|
||||
data-noresults-text="Nothing to see here."
|
||||
data-default-value="x123" data-default-text="Default text before change"
|
||||
autocomplete="off"></select>
|
||||
<br>
|
||||
<button type="button" class="btn btn-default btnChangeAutoSelect" autocomplete="off"
|
||||
data-value="1" data-text="Selected Value 1">
|
||||
Set a different selected value
|
||||
</button>
|
||||
<button type="button" class="btn btn-default btnChangeAutoSelect" autocomplete="off"
|
||||
data-value="2" data-text="Selected Value 2">
|
||||
Set a different selected value 2
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="modal fade" id="testModal" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<h4 class="modal-title">Modal title</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<select class="form-control basicModalAutoSelect" name="simple_select"
|
||||
placeholder="type to search..."
|
||||
data-url="testdata/test-select-simple.json" autocomplete="off"></select>
|
||||
<code class="basicModalAutoSelectSelected"></code>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
||||
</div>
|
||||
</div><!-- /.modal-content -->
|
||||
</div><!-- /.modal-dialog -->
|
||||
</div><!-- /.modal -->
|
||||
|
||||
<script src="//ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
|
||||
<script src="//netdna.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
|
||||
<script src="bootstrap-autocomplete.js"></script>
|
||||
<script>
|
||||
$(function () {
|
||||
// Basic
|
||||
$('.basicAutoComplete').autoComplete({
|
||||
resolverSettings: {
|
||||
url: 'testdata/test-list.json'
|
||||
}
|
||||
});
|
||||
|
||||
$('.basicAutoComplete').on('change', function (e) {
|
||||
console.log('change');
|
||||
});
|
||||
|
||||
$('.basicAutoComplete').on('autocomplete.select', function (evt, item) {
|
||||
$('.basicAutoCompleteSelected').html(JSON.stringify(item));
|
||||
$('.basicAutoCompleteCustom').html('');
|
||||
});
|
||||
|
||||
$('.basicAutoComplete').on('autocomplete.freevalue', function (evt, value) {
|
||||
$('.basicAutoCompleteCustom').html(JSON.stringify(value));
|
||||
$('.basicAutoCompleteSelected').html('');
|
||||
});
|
||||
|
||||
// Advanced 1
|
||||
$('.advancedAutoComplete').autoComplete({
|
||||
resolver: 'custom',
|
||||
events: {
|
||||
search: function (qry, callback) {
|
||||
// let's do a custom ajax call
|
||||
$.ajax(
|
||||
'testdata/test-dict.json',
|
||||
{
|
||||
data: { 'qry': qry}
|
||||
}
|
||||
).done(function (res) {
|
||||
callback(res.results)
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Advanced 2
|
||||
$('.advanced2AutoComplete').autoComplete({
|
||||
resolver: 'custom',
|
||||
formatResult: function (item) {
|
||||
return {
|
||||
value: item.id,
|
||||
text: "[" + item.id + "] " + item.text,
|
||||
html: [
|
||||
$('<img>').attr('src', item.icon).css("height", 18), ' ',
|
||||
item.text
|
||||
]
|
||||
};
|
||||
},
|
||||
events: {
|
||||
search: function (qry, callback) {
|
||||
// let's do a custom ajax call
|
||||
$.ajax(
|
||||
'testdata/test-dict.json',
|
||||
{
|
||||
data: { 'qry': qry}
|
||||
}
|
||||
).done(function (res) {
|
||||
callback(res.results)
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Basic Select
|
||||
$('.basicAutoSelect').autoComplete();
|
||||
$('.basicAutoSelect').on('autocomplete.select', function (evt, item) {
|
||||
console.log('select');
|
||||
$('.basicAutoSelectSelected').html(JSON.stringify(item));
|
||||
});
|
||||
|
||||
// Default Select
|
||||
$('.defaultAutoSelect').autoComplete();
|
||||
$('#dAS').on('autocomplete.select', function (e, i) {
|
||||
console.log('selected');
|
||||
});
|
||||
|
||||
// Empty Select
|
||||
$('.emptyAutoSelect').autoComplete();
|
||||
|
||||
// Modal
|
||||
$('.basicModalAutoSelect').autoComplete();
|
||||
$('.basicModalAutoSelect').on('autocomplete.select', function (evt, item) {
|
||||
console.log('select');
|
||||
$('.basicModalAutoSelectSelected').html(JSON.stringify(item));
|
||||
});
|
||||
|
||||
// Change default value programmatically.
|
||||
// Let's simulate a real world example.
|
||||
// Some point in time we initialize the autocomplete with a default value (defined by markup)
|
||||
$('.changeAutoSelect').autoComplete();
|
||||
// user then clicks on some button and we need to change that default value
|
||||
$('.btnChangeAutoSelect').on('click', function () {
|
||||
var e = $(this);
|
||||
$('.changeAutoSelect').autoComplete('set', { value: e.data('value'), text: e.data('text')});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,484 +0,0 @@
|
|||
/* =============================================================
|
||||
* bootstrap-autocomplete.js v2.3.4
|
||||
* https://github.com/xcash/bootstrap-autocomplete
|
||||
* =============================================================
|
||||
* Forked from bootstrap3-typeahead.js v3.1.0
|
||||
* https://github.com/bassjobsen/Bootstrap-3-Typeahead
|
||||
* =============================================================
|
||||
* Original written by @mdo and @fat
|
||||
* =============================================================
|
||||
* Copyright 2018-2020 Paolo Casciello @xcash666 and contributors
|
||||
*
|
||||
* Licensed under the MIT License (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ============================================================ */
|
||||
import { AjaxResolver, BaseResolver } from './resolvers';
|
||||
import { DropdownV3 } from './dropdownV3';
|
||||
import { DropdownV4 } from './dropdownV4';
|
||||
|
||||
|
||||
export interface AutoCompleteSettings {
|
||||
resolver: string,
|
||||
resolverSettings: any,
|
||||
minLength: number,
|
||||
valueKey: string,
|
||||
formatResult: (item: any) => {},
|
||||
autoSelect: boolean,
|
||||
noResultsText: string,
|
||||
bootstrapVersion: string,
|
||||
preventEnter: boolean,
|
||||
events: {
|
||||
typed: (newValue: string, el: JQuery<HTMLElement>) => string,
|
||||
searchPre: (searchText: string, el: JQuery<HTMLElement>) => string,
|
||||
search: (searchText: string, cbk: (results: any) => void, el: JQuery<HTMLElement>) => void,
|
||||
searchPost: (results: any, el: JQuery<HTMLElement>) => any,
|
||||
select: () => void,
|
||||
focus: () => void,
|
||||
}
|
||||
}
|
||||
|
||||
export class AutoComplete {
|
||||
public static NAME: string = 'autoComplete';
|
||||
|
||||
private _el: Element;
|
||||
private _$el: JQuery<HTMLElement>;
|
||||
private _dd: DropdownV3 | DropdownV4;
|
||||
private _searchText: string;
|
||||
private _selectedItem: any = null;
|
||||
private _defaultValue: any = null;
|
||||
private _defaultText: string = null;
|
||||
private _isSelectElement: boolean = false;
|
||||
private _selectHiddenField: JQuery;
|
||||
|
||||
private _settings: AutoCompleteSettings = {
|
||||
resolver: 'ajax',
|
||||
resolverSettings: {},
|
||||
minLength: 3,
|
||||
valueKey: 'value',
|
||||
formatResult: this.defaultFormatResult,
|
||||
autoSelect: true,
|
||||
noResultsText: 'No results',
|
||||
bootstrapVersion: 'auto',
|
||||
preventEnter: false,
|
||||
events: {
|
||||
typed: null,
|
||||
searchPre: null,
|
||||
search: null,
|
||||
searchPost: null,
|
||||
select: null,
|
||||
focus: null,
|
||||
}
|
||||
}
|
||||
|
||||
private resolver: BaseResolver;
|
||||
|
||||
constructor(element: HTMLElement, options?: {}) {
|
||||
this._el = element;
|
||||
this._$el = $(this._el) as JQuery<HTMLElement>;
|
||||
|
||||
// element type
|
||||
if (this._$el.is('select')) {
|
||||
this._isSelectElement = true;
|
||||
}
|
||||
// inline data attributes
|
||||
this.manageInlineDataAttributes();
|
||||
// constructor options
|
||||
if (typeof options === 'object') {
|
||||
this._settings = $.extend(true, {}, this.getSettings(), options) as AutoCompleteSettings;
|
||||
}
|
||||
if (this._isSelectElement) {
|
||||
this.convertSelectToText();
|
||||
}
|
||||
|
||||
// console.log('initializing', this._settings);
|
||||
|
||||
this.init();
|
||||
}
|
||||
|
||||
private manageInlineDataAttributes() {
|
||||
// updates settings with data-* attributes
|
||||
const s = this.getSettings();
|
||||
if (this._$el.data('url')) {
|
||||
s.resolverSettings.url = this._$el.data('url');
|
||||
}
|
||||
if (this._$el.data('default-value')) {
|
||||
this._defaultValue = this._$el.data('default-value');
|
||||
}
|
||||
if (this._$el.data('default-text')) {
|
||||
this._defaultText = this._$el.data('default-text');
|
||||
}
|
||||
if (this._$el.data('noresults-text') !== undefined) {
|
||||
s.noResultsText = this._$el.data('noresults-text');
|
||||
}
|
||||
}
|
||||
|
||||
private getSettings(): AutoCompleteSettings {
|
||||
return this._settings;
|
||||
}
|
||||
|
||||
private getBootstrapVersion(): number[] {
|
||||
let versionArray: number[];
|
||||
if (this._settings.bootstrapVersion === 'auto') {
|
||||
// @ts-ignore
|
||||
const versionString = $.fn.button.Constructor.VERSION;
|
||||
versionArray = versionString.split('.').map(parseInt);
|
||||
} else if (this._settings.bootstrapVersion === '4') {
|
||||
versionArray = [4];
|
||||
} else if (this._settings.bootstrapVersion === '3') {
|
||||
versionArray = [3];
|
||||
} else {
|
||||
// tslint:disable-next-line: no-console
|
||||
console.error(`INVALID value for \'bootstrapVersion\' settings property: ${this._settings.bootstrapVersion} defaulting to 4`);
|
||||
versionArray = [4];
|
||||
}
|
||||
return versionArray;
|
||||
}
|
||||
|
||||
private convertSelectToText() {
|
||||
// create hidden field
|
||||
|
||||
const hidField: JQuery = $('<input>');
|
||||
hidField.attr('type', 'hidden');
|
||||
hidField.attr('name', this._$el.attr('name'));
|
||||
if (this._defaultValue) {
|
||||
hidField.val(this._defaultValue);
|
||||
}
|
||||
this._selectHiddenField = hidField;
|
||||
|
||||
hidField.insertAfter(this._$el);
|
||||
|
||||
// create search input element
|
||||
const searchField: JQuery = $('<input>');
|
||||
// copy all attributes
|
||||
searchField.attr('type', 'search');
|
||||
searchField.attr('name', this._$el.attr('name') + '_text');
|
||||
searchField.attr('id', this._$el.attr('id'));
|
||||
searchField.attr('disabled', this._$el.attr('disabled'));
|
||||
searchField.attr('placeholder', this._$el.attr('placeholder'));
|
||||
searchField.attr('autocomplete', 'off');
|
||||
searchField.addClass(this._$el.attr('class'));
|
||||
if (this._defaultText) {
|
||||
searchField.val(this._defaultText);
|
||||
}
|
||||
|
||||
const requiredAttribute: string = this._$el.attr('required');
|
||||
if (requiredAttribute) {
|
||||
searchField.attr('required', requiredAttribute);
|
||||
}
|
||||
|
||||
// attach class
|
||||
searchField.data(AutoComplete.NAME, this);
|
||||
|
||||
// replace original with searchField
|
||||
this._$el.replaceWith(searchField);
|
||||
this._$el = searchField;
|
||||
this._el = searchField.get(0);
|
||||
}
|
||||
|
||||
private init(): void {
|
||||
// bind default events
|
||||
this.bindDefaultEventListeners();
|
||||
// RESOLVER
|
||||
if (this._settings.resolver === 'ajax') {
|
||||
// configure default resolver
|
||||
this.resolver = new AjaxResolver(this._settings.resolverSettings);
|
||||
}
|
||||
// Dropdown
|
||||
if (this.getBootstrapVersion()[0] === 4) {
|
||||
// v4
|
||||
this._dd = new DropdownV4(this._$el, this._settings.formatResult,
|
||||
this._settings.autoSelect, this._settings.noResultsText
|
||||
);
|
||||
} else {
|
||||
this._dd = new DropdownV3(this._$el, this._settings.formatResult,
|
||||
this._settings.autoSelect, this._settings.noResultsText
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private bindDefaultEventListeners(): void {
|
||||
this._$el.on('keydown', (evt: JQueryEventObject) => {
|
||||
// console.log('keydown', evt.which, evt);
|
||||
switch (evt.which) {
|
||||
case 9: // TAB
|
||||
// if (this._settings.autoSelect) {
|
||||
// // if autoSelect enabled selects on blur the currently selected item
|
||||
// this._dd.selectFocusItem();
|
||||
// }
|
||||
if (this._dd.isItemFocused) {
|
||||
this._dd.selectFocusItem();
|
||||
} else if (!this._selectedItem) {
|
||||
// if we haven't selected an item (thus firing the corresponding event) we fire the free value
|
||||
// related to issue #71
|
||||
if (this._$el.val() !== '') {
|
||||
this._$el.trigger('autocomplete.freevalue', this._$el.val());
|
||||
}
|
||||
}
|
||||
this._dd.hide();
|
||||
break;
|
||||
case 13: // ENTER
|
||||
if (this._dd.isItemFocused) {
|
||||
this._dd.selectFocusItem();
|
||||
} else if (!this._selectedItem) {
|
||||
if (this._$el.val() !== '') {
|
||||
this._$el.trigger('autocomplete.freevalue', this._$el.val());
|
||||
}
|
||||
}
|
||||
this._dd.hide();
|
||||
if (this._settings.preventEnter) {
|
||||
// console.log('preventDefault');
|
||||
evt.preventDefault();
|
||||
}
|
||||
break;
|
||||
case 40:
|
||||
// arrow DOWN (here for usability - issue #80)
|
||||
this._dd.focusNextItem();
|
||||
break;
|
||||
case 38: // up arrow (here for usability - issue #80)
|
||||
this._dd.focusPreviousItem();
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
this._$el.on('keyup', (evt: JQueryEventObject) => {
|
||||
// console.log('keyup', evt.which, evt);
|
||||
// check key
|
||||
switch (evt.which) {
|
||||
case 16: // shift
|
||||
case 17: // ctrl
|
||||
case 18: // alt
|
||||
case 39: // right
|
||||
case 37: // left
|
||||
case 36: // home
|
||||
case 35: // end
|
||||
break;
|
||||
case 13:
|
||||
// ENTER
|
||||
this._dd.hide();
|
||||
break;
|
||||
case 27:
|
||||
// ESC
|
||||
this._dd.hide();
|
||||
break;
|
||||
case 40:
|
||||
// arrow DOWN
|
||||
// this._dd.focusNextItem();
|
||||
break;
|
||||
case 38: // up arrow
|
||||
// this._dd.focusPreviousItem();
|
||||
break;
|
||||
default:
|
||||
// reset selectedItem as we modified input value (related to issue #71)
|
||||
this._selectedItem = null;
|
||||
const newValue = this._$el.val() as string;
|
||||
this.handlerTyped(newValue);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
this._$el.on('blur', (evt: JQueryEventObject) => {
|
||||
// console.log(evt);
|
||||
if (!this._dd.isMouseOver && this._dd.isDdMouseOver && this._dd.isShown()) {
|
||||
// Firefox Workaround
|
||||
setTimeout(() => { this._$el.focus(); });
|
||||
// Other browsers
|
||||
this._$el.focus();
|
||||
} else if (!this._dd.isMouseOver) {
|
||||
if (this._isSelectElement) {
|
||||
// if it's a select element
|
||||
if (this._dd.isItemFocused) {
|
||||
this._dd.selectFocusItem();
|
||||
} else if ((this._selectedItem !== null) && (this._$el.val() !== '')) {
|
||||
// reselect it
|
||||
this._$el.trigger('autocomplete.select', this._selectedItem);
|
||||
} else if ((this._$el.val() !== '') && (this._defaultValue !== null)) {
|
||||
// select Default
|
||||
this._$el.val(this._defaultText);
|
||||
this._selectHiddenField.val(this._defaultValue);
|
||||
this._selectedItem = null;
|
||||
this._$el.trigger('autocomplete.select', this._selectedItem);
|
||||
} else {
|
||||
// empty the values
|
||||
this._$el.val('');
|
||||
this._selectHiddenField.val('');
|
||||
this._selectedItem = null;
|
||||
this._$el.trigger('autocomplete.select', this._selectedItem);
|
||||
}
|
||||
} else {
|
||||
// It's a text element, we accept custom value.
|
||||
// Developers may subscribe to `autocomplete.freevalue` to get notified of this
|
||||
if (this._selectedItem === null) {
|
||||
this._$el.trigger('autocomplete.freevalue', this._$el.val());
|
||||
}
|
||||
}
|
||||
|
||||
this._dd.hide();
|
||||
}
|
||||
});
|
||||
|
||||
// selected event
|
||||
// @ts-ignore - Ignoring TS type checking
|
||||
this._$el.on('autocomplete.select', (evt: JQueryEventObject, item: any) => {
|
||||
this._selectedItem = item;
|
||||
this.itemSelectedDefaultHandler(item);
|
||||
});
|
||||
|
||||
// Paste event
|
||||
// The event occurs before the value is pasted. safe behaviour should be triggering `keyup`
|
||||
this._$el.on('paste', (evt: JQueryEventObject) => {
|
||||
setTimeout(() => {
|
||||
this._$el.trigger('keyup', evt);
|
||||
}, 0)
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private handlerTyped(newValue: string): void {
|
||||
// field value changed
|
||||
|
||||
// custom handler may change newValue
|
||||
if (this._settings.events.typed !== null) {
|
||||
newValue = this._settings.events.typed(newValue, this._$el);
|
||||
if (!newValue) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// if value >= minLength, start autocomplete
|
||||
if (newValue.length >= this._settings.minLength) {
|
||||
this._searchText = newValue;
|
||||
this.handlerPreSearch();
|
||||
} else {
|
||||
this._dd.hide();
|
||||
}
|
||||
}
|
||||
|
||||
private handlerPreSearch(): void {
|
||||
// do nothing, start search
|
||||
|
||||
// custom handler may change newValue
|
||||
if (this._settings.events.searchPre !== null) {
|
||||
const newValue: string = this._settings.events.searchPre(this._searchText, this._$el);
|
||||
if (!newValue)
|
||||
return;
|
||||
this._searchText = newValue;
|
||||
}
|
||||
|
||||
this.handlerDoSearch();
|
||||
}
|
||||
|
||||
private handlerDoSearch(): void {
|
||||
// custom handler may change newValue
|
||||
if (this._settings.events.search !== null) {
|
||||
this._settings.events.search(this._searchText, (results: any) => {
|
||||
this.postSearchCallback(results);
|
||||
}, this._$el);
|
||||
} else {
|
||||
// Default behaviour
|
||||
// search using current resolver
|
||||
if (this.resolver) {
|
||||
this.resolver.search(this._searchText, (results: any) => {
|
||||
this.postSearchCallback(results);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private postSearchCallback(results: any): void {
|
||||
// console.log('callback called', results);
|
||||
|
||||
// custom handler may change newValue
|
||||
if (this._settings.events.searchPost) {
|
||||
results = this._settings.events.searchPost(results, this._$el);
|
||||
if ((typeof results === 'boolean') && !results)
|
||||
return;
|
||||
}
|
||||
|
||||
this.handlerStartShow(results);
|
||||
}
|
||||
|
||||
private handlerStartShow(results: any[]): void {
|
||||
// console.log("defaultEventStartShow", results);
|
||||
// for every result, draw it
|
||||
this._dd.updateItems(results, this._searchText);
|
||||
}
|
||||
|
||||
protected itemSelectedDefaultHandler(item: any): void {
|
||||
// this is a coerce check (!=) to cover null or undefined
|
||||
if (item != null) {
|
||||
// default behaviour is set elment's .val()
|
||||
let itemFormatted: any = this._settings.formatResult(item);
|
||||
if (typeof itemFormatted === 'string') {
|
||||
itemFormatted = { text: itemFormatted }
|
||||
}
|
||||
this._$el.val(itemFormatted.text);
|
||||
// if the element is a select
|
||||
if (this._isSelectElement) {
|
||||
this._selectHiddenField.val(itemFormatted.value);
|
||||
}
|
||||
} else {
|
||||
// item is null -> clear the value
|
||||
this._$el.val('');
|
||||
if (this._isSelectElement) {
|
||||
this._selectHiddenField.val('');
|
||||
}
|
||||
}
|
||||
// save selected item
|
||||
this._selectedItem = item;
|
||||
// and hide
|
||||
this._dd.hide();
|
||||
}
|
||||
|
||||
private defaultFormatResult(item: any): {} {
|
||||
if (typeof item === 'string') {
|
||||
return { text: item };
|
||||
} else if (item.text) {
|
||||
return item;
|
||||
} else {
|
||||
// return a toString of the item as last resort
|
||||
// console.error('No default formatter for item', item);
|
||||
return { text: item.toString() }
|
||||
}
|
||||
}
|
||||
|
||||
public manageAPI(APICmd: any, params: any) {
|
||||
// manages public API
|
||||
if (APICmd === 'set') {
|
||||
this.itemSelectedDefaultHandler(params);
|
||||
} else if (APICmd === 'clear') {
|
||||
// shortcut
|
||||
this.itemSelectedDefaultHandler(null);
|
||||
} else if (APICmd === 'show') {
|
||||
// shortcut
|
||||
this._$el.trigger('keyup');
|
||||
} else if (APICmd === 'updateResolver') {
|
||||
// update resolver
|
||||
this.resolver = new AjaxResolver(params);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
(($: JQueryStatic, window: any, document: any) => {
|
||||
// @ts-ignore
|
||||
$.fn[AutoComplete.NAME] = function (optionsOrAPI: any, optionalParams: any) {
|
||||
return this.each(function () {
|
||||
let pluginClass: AutoComplete;
|
||||
|
||||
pluginClass = $(this).data(AutoComplete.NAME);
|
||||
|
||||
if (!pluginClass) {
|
||||
pluginClass = new AutoComplete(this, optionsOrAPI);
|
||||
$(this).data(AutoComplete.NAME, pluginClass);
|
||||
}
|
||||
|
||||
pluginClass.manageAPI(optionsOrAPI, optionalParams);
|
||||
});
|
||||
};
|
||||
})(jQuery, window, document);
|
|
@ -1,89 +0,0 @@
|
|||
export class BaseResolver {
|
||||
protected results: any[];
|
||||
|
||||
protected _settings: any;
|
||||
|
||||
constructor(options: any) {
|
||||
this._settings = $.extend(true, {}, this.getDefaults(), options);
|
||||
}
|
||||
|
||||
protected getDefaults(): {} {
|
||||
return {};
|
||||
}
|
||||
|
||||
protected getResults(limit?: number, start?: number, end?: number): any[] {
|
||||
|
||||
return this.results;
|
||||
}
|
||||
|
||||
public search(q: string, cbk: (results: any[]) => void): void {
|
||||
cbk(this.getResults());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// tslint:disable-next-line: max-classes-per-file
|
||||
export class AjaxResolver extends BaseResolver {
|
||||
protected jqXHR: JQueryXHR;
|
||||
protected requestTID: number;
|
||||
|
||||
constructor(options: any) {
|
||||
super(options);
|
||||
|
||||
// console.log('resolver settings', this._settings);
|
||||
}
|
||||
|
||||
protected getDefaults(): {} {
|
||||
return {
|
||||
url: '',
|
||||
method: 'get',
|
||||
queryKey: 'q',
|
||||
extraData: {},
|
||||
timeout: undefined,
|
||||
requestThrottling: 500
|
||||
};
|
||||
}
|
||||
|
||||
public search(q: string, cbk: (results: any[]) => void): void {
|
||||
if (this.jqXHR != null) {
|
||||
this.jqXHR.abort();
|
||||
}
|
||||
|
||||
const data: {
|
||||
[key: string]: any
|
||||
} = {};
|
||||
data[this._settings.queryKey] = q;
|
||||
$.extend(data, this._settings.extraData);
|
||||
|
||||
// request throttling
|
||||
if (this.requestTID) {
|
||||
window.clearTimeout(this.requestTID);
|
||||
}
|
||||
this.requestTID = window.setTimeout(() => {
|
||||
this.jqXHR = $.ajax(
|
||||
this._settings.url,
|
||||
{
|
||||
method: this._settings.method,
|
||||
data,
|
||||
timeout: this._settings.timeout
|
||||
}
|
||||
);
|
||||
|
||||
this.jqXHR.done((result) => {
|
||||
cbk(result);
|
||||
});
|
||||
|
||||
this.jqXHR.fail((err) => {
|
||||
// console.log(err);
|
||||
// this._settings.fail && this._settings.fail(err);
|
||||
this._settings?.fail(err);
|
||||
});
|
||||
|
||||
this.jqXHR.always(() => {
|
||||
this.jqXHR = null;
|
||||
});
|
||||
|
||||
}, this._settings.requestThrottling);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
{
|
||||
"results": [
|
||||
{
|
||||
"id": 1, "text": "Google Cloud Platform",
|
||||
"icon": "https://pbs.twimg.com/profile_images/966440541859688448/PoHJY3K8_400x400.jpg"
|
||||
},
|
||||
{
|
||||
"id": 2, "text": "Amazon AWS",
|
||||
"icon": "http://photos3.meetupstatic.com/photos/event/5/d/e/0/highres_263124032.jpeg"
|
||||
},
|
||||
{
|
||||
"id": 3, "text": "Docker",
|
||||
"icon": "https://www.docker.com/sites/default/files/legal/small_v.png"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
[]
|
|
@ -1,60 +0,0 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Bootstrap AutoComplete Test Issue 10</title>
|
||||
|
||||
<!-- Required meta tags -->
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" integrity="sha384-9gVQ4dYFwwWSjIDZnLEWnxCjeSWFphJiwGPXr1jddIhOegiu1FwO5qRGvFXOdJZ4" crossorigin="anonymous">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1 class="border-bottom">Bootstrap Autocomplete test issue 10</h1>
|
||||
<p>
|
||||
Testing page for <a href="https://github.com/xcash/bootstrap-autocomplete/issues/10">issue #10</a>
|
||||
</p>
|
||||
<form action="//example.com" method="GET" target="_blank">
|
||||
<input class="form-control basicAutoComplete" name="q" type="text" autocomplete="off">
|
||||
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js" integrity="sha384-cs/chFZiN24E4KMATLdqdvsezGxaGsi4hLGOzlXwp5UZB1LY//20VyM2taTB4QvJ" crossorigin="anonymous"></script>
|
||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js" integrity="sha384-uefMccjFJAIv6A+rW+L4AHf99KvxDjWSu1z9VI8SKNVmz4sk7buKt/6v9KI65qnm" crossorigin="anonymous"></script>
|
||||
<script src="../bootstrap-autocomplete.js"></script>
|
||||
<script>
|
||||
$(function () {
|
||||
// Basic
|
||||
$('.basicAutoComplete').autoComplete({
|
||||
resolverSettings: {
|
||||
url: 'test-list.json'
|
||||
}
|
||||
});
|
||||
|
||||
// Events
|
||||
var eventsCodeContainer = $('#eventsCodeContainer');
|
||||
|
||||
$('.eventsAutoComplete').autoComplete({
|
||||
resolverSettings: {
|
||||
url: 'testdata/test-list.json'
|
||||
}
|
||||
});
|
||||
$('.eventsAutoComplete').on('change', function() {
|
||||
console.log('eventsAutoComplete change');
|
||||
eventsCodeContainer.text(eventsCodeContainer.text() + 'fired change. value: ' + $(this).val() + '\n');
|
||||
});
|
||||
$('.eventsAutoComplete').on('autocomplete.select', function(evt, item) {
|
||||
console.log('eventsAutoComplete autocomplete.select');
|
||||
eventsCodeContainer.text(eventsCodeContainer.text() + 'fired autocomplete.select. item: ' + item + ' value: ' + $(this).val() + '\n');
|
||||
});
|
||||
$('.eventsAutoComplete').on('autocomplete.freevalue', function(evt, item) {
|
||||
console.log('eventsAutoComplete autocomplete.freevalue');
|
||||
eventsCodeContainer.text(eventsCodeContainer.text() + 'fired autocomplete.freevalue. item: ' + item + ' value: ' + $(this).val() + '\n');
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,308 +0,0 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Bootstrap AutoComplete Demo Bootstrap 4</title>
|
||||
|
||||
<!-- Required meta tags -->
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" integrity="sha384-9gVQ4dYFwwWSjIDZnLEWnxCjeSWFphJiwGPXr1jddIhOegiu1FwO5qRGvFXOdJZ4" crossorigin="anonymous">
|
||||
<style type="text/css">
|
||||
.dropdown-menu {
|
||||
overflow: scroll;
|
||||
max-width: 400px;
|
||||
max-height: 120px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1 class="border-bottom">Bootstrap Autocomplete (for Bootstrap version 4)</h1>
|
||||
<p>
|
||||
This page acts like a Demo page and a Testing page. Here we are testing issue #20, solving a bug in which a scrollable dropdown inside a modal was closed when clicking on the scrollbar.
|
||||
</p>
|
||||
<form>
|
||||
<fieldset>
|
||||
<legend class="border-bottom">AJAX</legend>
|
||||
<div class="form-row mb-3">
|
||||
<label class="col-lg-3">
|
||||
Basic (<a href="test-list.json">list of strings</a>)
|
||||
</label>
|
||||
<div class="col-lg-9">
|
||||
<input class="form-control basicAutoComplete" type="text" autocomplete="off">
|
||||
Selected item: <code class="basicAutoCompleteSelected"></code><br>
|
||||
Custom value: <code class="basicAutoCompleteCustom"></code>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row mb-3">
|
||||
<label class="col-lg-3">
|
||||
Advanced (<a href="test-dict.json">complex object</a>)
|
||||
</label>
|
||||
<div class="col-lg-9">
|
||||
<input class="form-control advancedAutoComplete" type="text" autocomplete="off" placeholder="type to search...">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row mb-3">
|
||||
<label class="col-lg-3">
|
||||
Advanced (<a href="test-dict.json">complex object</a> - custom formatting)
|
||||
</label>
|
||||
<div class="col-lg-9">
|
||||
<input class="form-control advanced2AutoComplete" type="text" autocomplete="off">
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend class="border-bottom">
|
||||
<code><select></code> as Autocomplete
|
||||
</legend>
|
||||
<div class="row">
|
||||
<div class="col-lg-9 offset-lg-3">
|
||||
<p>
|
||||
Selects are a subtype of autocomplete where the selected value is restricted to
|
||||
server-provided results. User <b>must</b> select one of those.
|
||||
</p>
|
||||
<p>
|
||||
Bootstrap-Autocomplete provides a smarter select rendered as a standard
|
||||
autocomplete <b>text</b> field. It substitutes the field with an
|
||||
<code><input type="text"></code and creates a <i>shadow</i> hidden field with
|
||||
the selected value (and the original name).
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row mb-3">
|
||||
<label class="col-lg-3">
|
||||
Simple (<a href="test-select-simple.json">list of { value, strings }</a>)
|
||||
</label>
|
||||
<div class="col-lg-9">
|
||||
<select class="form-control basicAutoSelect" name="simple_select"
|
||||
placeholder="type to search..."
|
||||
data-url="test-select-simple.json" autocomplete="off"></select>
|
||||
<code class="basicAutoSelectSelected"></code>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row mb-3">
|
||||
<label class="col-lg-3">
|
||||
Default Selected (<a href="test-select-simple.json">list of { value, strings }</a>)
|
||||
</label>
|
||||
<div class="col-lg-9">
|
||||
<select class="form-control defaultAutoSelect" id="dAS" name="default_select"
|
||||
data-url="test-select-simple.json"
|
||||
data-default-value="3" data-default-text="Docker"
|
||||
autocomplete="off"></select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row mb-3">
|
||||
<label class="col-lg-3">
|
||||
No results (<a href="test-empty.json">empty list</a>)
|
||||
</label>
|
||||
<div class="col-lg-9">
|
||||
<select class="form-control emptyAutoSelect" name="empty_select"
|
||||
data-url="test-empty.json"
|
||||
data-noresults-text="Nothing to see here."
|
||||
autocomplete="off"></select>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend class="border-bottom">
|
||||
In Bootstrap modal
|
||||
</legend>
|
||||
<div class="row">
|
||||
<div class="col-lg-9 offset-lg-3">
|
||||
<button type="button" class="btn btn-primary" autocomplete="off"
|
||||
data-toggle="modal" data-target="#testModal">
|
||||
Open Test Modal
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>Javascript API</legend>
|
||||
<div class="form-row mb-3">
|
||||
<label class="col-lg-3">
|
||||
Change selected value programmatically
|
||||
</label>
|
||||
<div class="col-lg-9">
|
||||
<select class="form-control changeAutoSelect" name="change_select"
|
||||
data-url="test-select-simple.json"
|
||||
data-noresults-text="Nothing to see here."
|
||||
data-default-value="x123" data-default-text="Default text before change"
|
||||
autocomplete="off"></select>
|
||||
<br>
|
||||
<button type="button" class="btn btn-outline-secondary btnChangeAutoSelect" autocomplete="off"
|
||||
data-value="1" data-text="Selected Value 1">
|
||||
Set a different selected value
|
||||
</button>
|
||||
<button type="button" class="btn btn-outline-secondary btnChangeAutoSelect" autocomplete="off"
|
||||
data-value="2" data-text="Selected Value 2">
|
||||
Set a different selected value 2
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>Events</legend>
|
||||
<div class="form-row mb-3">
|
||||
<label class="col-lg-3">
|
||||
Events in text field
|
||||
</label>
|
||||
<div class="col-lg-9">
|
||||
<input class="form-control eventsAutoComplete" type="text" autocomplete="off">
|
||||
<br>
|
||||
<code><pre id="eventsCodeContainer"></pre></code>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="modal fade" id="testModal" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<h4 class="modal-title">Modal title</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<select class="form-control basicModalAutoSelect" name="simple_select"
|
||||
placeholder="type to search..."
|
||||
data-url="test-select-simple.json" autocomplete="off"></select>
|
||||
<code class="basicModalAutoSelectSelected"></code>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
||||
</div>
|
||||
</div><!-- /.modal-content -->
|
||||
</div><!-- /.modal-dialog -->
|
||||
</div><!-- /.modal -->
|
||||
|
||||
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js" integrity="sha384-cs/chFZiN24E4KMATLdqdvsezGxaGsi4hLGOzlXwp5UZB1LY//20VyM2taTB4QvJ" crossorigin="anonymous"></script>
|
||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js" integrity="sha384-uefMccjFJAIv6A+rW+L4AHf99KvxDjWSu1z9VI8SKNVmz4sk7buKt/6v9KI65qnm" crossorigin="anonymous"></script>
|
||||
<script src="../bootstrap-autocomplete.js"></script>
|
||||
<script>
|
||||
$(function () {
|
||||
// Basic
|
||||
$('.basicAutoComplete').autoComplete({
|
||||
resolverSettings: {
|
||||
url: 'test-list.json'
|
||||
}
|
||||
});
|
||||
|
||||
$('.basicAutoComplete').on('change', function (e) {
|
||||
console.log('change');
|
||||
});
|
||||
|
||||
$('.basicAutoComplete').on('autocomplete.select', function (evt, item) {
|
||||
$('.basicAutoCompleteSelected').html(JSON.stringify(item));
|
||||
$('.basicAutoCompleteCustom').html('');
|
||||
});
|
||||
|
||||
$('.basicAutoComplete').on('autocomplete.freevalue', function (evt, value) {
|
||||
$('.basicAutoCompleteCustom').html(JSON.stringify(value));
|
||||
$('.basicAutoCompleteSelected').html('');
|
||||
});
|
||||
|
||||
// Advanced 1
|
||||
$('.advancedAutoComplete').autoComplete({
|
||||
resolver: 'custom',
|
||||
events: {
|
||||
search: function (qry, callback) {
|
||||
// let's do a custom ajax call
|
||||
$.ajax(
|
||||
'test-dict.json',
|
||||
{
|
||||
data: { 'qry': qry}
|
||||
}
|
||||
).done(function (res) {
|
||||
callback(res.results)
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Advanced 2
|
||||
$('.advanced2AutoComplete').autoComplete({
|
||||
resolver: 'custom',
|
||||
formatResult: function (item) {
|
||||
return {
|
||||
value: item.id,
|
||||
text: "[" + item.id + "] " + item.text,
|
||||
html: [
|
||||
$('<img>').attr('src', item.icon).css("height", 18), ' ',
|
||||
item.text
|
||||
]
|
||||
};
|
||||
},
|
||||
events: {
|
||||
search: function (qry, callback) {
|
||||
// let's do a custom ajax call
|
||||
$.ajax(
|
||||
'test-dict.json',
|
||||
{
|
||||
data: { 'qry': qry}
|
||||
}
|
||||
).done(function (res) {
|
||||
callback(res.results)
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Basic Select
|
||||
$('.basicAutoSelect').autoComplete();
|
||||
$('.basicAutoSelect').on('autocomplete.select', function (evt, item) {
|
||||
console.log('select');
|
||||
$('.basicAutoSelectSelected').html(JSON.stringify(item));
|
||||
});
|
||||
|
||||
// Default Select
|
||||
$('.defaultAutoSelect').autoComplete();
|
||||
$('#dAS').on('autocomplete.select', function (e, i) {
|
||||
console.log('selected');
|
||||
});
|
||||
|
||||
// Empty Select
|
||||
$('.emptyAutoSelect').autoComplete();
|
||||
|
||||
// Modal
|
||||
$('.basicModalAutoSelect').autoComplete();
|
||||
$('.basicModalAutoSelect').on('autocomplete.select', function (evt, item) {
|
||||
console.log('select');
|
||||
$('.basicModalAutoSelectSelected').html(JSON.stringify(item));
|
||||
});
|
||||
|
||||
// Change default value programmatically.
|
||||
// Let's simulate a real world example.
|
||||
// Some point in time we initialize the autocomplete with a default value (defined by markup)
|
||||
$('.changeAutoSelect').autoComplete();
|
||||
// user then clicks on some button and we need to change that default value
|
||||
$('.btnChangeAutoSelect').on('click', function () {
|
||||
var e = $(this);
|
||||
$('.changeAutoSelect').autoComplete('set', { value: e.data('value'), text: e.data('text')});
|
||||
});
|
||||
|
||||
// Events
|
||||
var eventsCodeContainer = $('#eventsCodeContainer');
|
||||
|
||||
$('.eventsAutoComplete').autoComplete({
|
||||
resolverSettings: {
|
||||
url: 'test-list.json'
|
||||
}
|
||||
});
|
||||
$('.eventsAutoComplete').on('change', function() {
|
||||
console.log('eventsAutoComplete change');
|
||||
eventsCodeContainer.text(eventsCodeContainer.text() + 'fired change. value: ' + $(this).val() + '\n');
|
||||
});
|
||||
$('.eventsAutoComplete').on('autocomplete.select', function(evt, item) {
|
||||
console.log('eventsAutoComplete autocomplete.select');
|
||||
eventsCodeContainer.text(eventsCodeContainer.text() + 'fired autocomplete.select. item: ' + item + ' value: ' + $(this).val() + '\n');
|
||||
});
|
||||
$('.eventsAutoComplete').on('autocomplete.freevalue', function(evt, item) {
|
||||
console.log('eventsAutoComplete autocomplete.freevalue');
|
||||
eventsCodeContainer.text(eventsCodeContainer.text() + 'fired autocomplete.freevalue. item: ' + item + ' value: ' + $(this).val() + '\n');
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,56 +0,0 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Bootstrap AutoComplete Test Issue 35</title>
|
||||
|
||||
<!-- Required meta tags -->
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" integrity="sha384-9gVQ4dYFwwWSjIDZnLEWnxCjeSWFphJiwGPXr1jddIhOegiu1FwO5qRGvFXOdJZ4" crossorigin="anonymous">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1 class="border-bottom">Bootstrap Autocomplete test issue 35</h1>
|
||||
<p>
|
||||
Testing page for <a href="https://github.com/xcash/bootstrap-autocomplete/issues/35">issue #35</a>
|
||||
</p>
|
||||
<form action="//httpbin.org" method="GET" target="_blank">
|
||||
<input class="form-control basicAutoComplete" name="q" type="text" autocomplete="off">
|
||||
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js" integrity="sha384-cs/chFZiN24E4KMATLdqdvsezGxaGsi4hLGOzlXwp5UZB1LY//20VyM2taTB4QvJ" crossorigin="anonymous"></script>
|
||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js" integrity="sha384-uefMccjFJAIv6A+rW+L4AHf99KvxDjWSu1z9VI8SKNVmz4sk7buKt/6v9KI65qnm" crossorigin="anonymous"></script>
|
||||
<script src="../bootstrap-autocomplete.js"></script>
|
||||
<script>
|
||||
$(function () {
|
||||
// Basic
|
||||
$('.basicAutoComplete').autoComplete({
|
||||
minLength: 0,
|
||||
resolverSettings: {
|
||||
url: 'test-list.json'
|
||||
},
|
||||
events: {
|
||||
search: () => {
|
||||
console.log('basicAutoComplete search');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Events
|
||||
$('.basicAutoComplete').on('change', function() {
|
||||
console.log('basicAutoComplete change');
|
||||
});
|
||||
$('.basicAutoComplete').on('autocomplete.select', function(evt, item) {
|
||||
console.log('basicAutoComplete autocomplete.select');
|
||||
});
|
||||
$('.basicAutoComplete').on('autocomplete.freevalue', function(evt, item) {
|
||||
console.log('basicAutoComplete autocomplete.freevalue');
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,51 +0,0 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Bootstrap AutoComplete Test Issue 35</title>
|
||||
|
||||
<!-- Required meta tags -->
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1 class="border-bottom">Bootstrap Autocomplete test issue 59</h1>
|
||||
<p>
|
||||
Testing page for <a href="https://github.com/xcash/bootstrap-autocomplete/issues/59">issue #59</a>
|
||||
</p>
|
||||
<form action="//httpbin.org/anything" method="GET" target="_blank">
|
||||
<input class="form-control basicAutoComplete" name="q" type="text" autocomplete="off">
|
||||
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
|
||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
|
||||
<script src="../bootstrap-autocomplete.js"></script>
|
||||
<script>
|
||||
$(function () {
|
||||
// Basic
|
||||
$('.basicAutoComplete').autoComplete({
|
||||
resolverSettings: {
|
||||
url: 'test-list.json'
|
||||
},
|
||||
// preventEnter: true
|
||||
});
|
||||
|
||||
// Events
|
||||
$('.basicAutoComplete').on('change', function() {
|
||||
console.log('basicAutoComplete change');
|
||||
});
|
||||
$('.basicAutoComplete').on('autocomplete.select', function(evt, item) {
|
||||
console.log('basicAutoComplete autocomplete.select');
|
||||
});
|
||||
$('.basicAutoComplete').on('autocomplete.freevalue', function(evt, item) {
|
||||
console.log('basicAutoComplete autocomplete.freevalue');
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,70 +0,0 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Bootstrap AutoComplete Test Issue 80</title>
|
||||
|
||||
<!-- Required meta tags -->
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1 class="border-bottom">Bootstrap Autocomplete test issue 80</h1>
|
||||
<p>
|
||||
Testing page for <a href="https://github.com/xcash/bootstrap-autocomplete/issues/80">issue #80</a>
|
||||
</p>
|
||||
<form action="//httpbin.org/anything" method="GET" target="_blank">
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<input class="form-control basicAutoComplete" name="q" type="text" autocomplete="off">
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<script src="http://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
|
||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js" integrity="sha384-B4gt1jrGC7Jh4AgTPSdUtOBvfO8shuf57BaghqFfPlYxofvL8/KUEfYiJOMMV+rV" crossorigin="anonymous"></script>
|
||||
<script src="../bootstrap-autocomplete.js"></script>
|
||||
<script>
|
||||
$(function () {
|
||||
var cbNR = $('#returnNoResults');
|
||||
|
||||
var results = [];
|
||||
for (var i=111; i<99999; i++) {
|
||||
results.push(i.toString());
|
||||
}
|
||||
|
||||
$('.basicAutoComplete').autoComplete({
|
||||
resolver: 'custom',
|
||||
// noResultsText: '',
|
||||
events: {
|
||||
search: function (qry, callback) {
|
||||
var res = results.filter( (v) => {
|
||||
if (v.indexOf(qry) > -1) {
|
||||
return v;
|
||||
}
|
||||
})
|
||||
callback(res);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Events
|
||||
$('.basicAutoComplete').on('change', function() {
|
||||
console.log('basicAutoComplete change');
|
||||
});
|
||||
$('.basicAutoComplete').on('autocomplete.select', function(evt, item) {
|
||||
console.log('basicAutoComplete autocomplete.select');
|
||||
});
|
||||
$('.basicAutoComplete').on('autocomplete.freevalue', function(evt, item) {
|
||||
console.log('basicAutoComplete autocomplete.freevalue');
|
||||
});
|
||||
|
||||
$('.basicAutoComplete').focus();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,66 +0,0 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Bootstrap AutoComplete Test Issue 83</title>
|
||||
|
||||
<!-- Required meta tags -->
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1 class="border-bottom">Bootstrap Autocomplete test issue 83</h1>
|
||||
<p>
|
||||
Testing page for <a href="https://github.com/xcash/bootstrap-autocomplete/issues/83">issue #83</a>
|
||||
</p>
|
||||
<form action="//httpbin.org/anything" method="GET" target="_blank">
|
||||
<input class="form-control basicAutoComplete" name="q" type="text" autocomplete="off">
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<script src="http://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
|
||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js" integrity="sha384-B4gt1jrGC7Jh4AgTPSdUtOBvfO8shuf57BaghqFfPlYxofvL8/KUEfYiJOMMV+rV" crossorigin="anonymous"></script>
|
||||
<script src="../bootstrap-autocomplete.js"></script>
|
||||
<script>
|
||||
$(function () {
|
||||
var cbNR = $('#returnNoResults');
|
||||
var results = [
|
||||
"abc",
|
||||
"abcd",
|
||||
"abcde"
|
||||
]
|
||||
|
||||
$('.basicAutoComplete').autoComplete({
|
||||
resolver: 'custom',
|
||||
// noResultsText: '',
|
||||
events: {
|
||||
search: function (qry, callback) {
|
||||
var res = results.filter( (v) => {
|
||||
if (v.indexOf(qry) > -1) {
|
||||
return v;
|
||||
}
|
||||
})
|
||||
callback(res);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Events
|
||||
$('.basicAutoComplete').on('change', function() {
|
||||
console.log('basicAutoComplete change');
|
||||
});
|
||||
$('.basicAutoComplete').on('autocomplete.select', function(evt, item) {
|
||||
console.log('basicAutoComplete autocomplete.select');
|
||||
});
|
||||
$('.basicAutoComplete').on('autocomplete.freevalue', function(evt, item) {
|
||||
console.log('basicAutoComplete autocomplete.freevalue');
|
||||
});
|
||||
|
||||
$('.basicAutoComplete').focus();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,6 +0,0 @@
|
|||
[
|
||||
"Google Cloud Platform",
|
||||
"Amazon AWS",
|
||||
"Docker",
|
||||
"Digital Ocean"
|
||||
]
|
6
static/node_modules/bootstrap-autocomplete/src/testdata/test-select-simple.json
generated
vendored
6
static/node_modules/bootstrap-autocomplete/src/testdata/test-select-simple.json
generated
vendored
|
@ -1,6 +0,0 @@
|
|||
[
|
||||
{ "value": 1, "text": "Google Cloud Platform" },
|
||||
{ "value": 2, "text": "Amazon AWS" },
|
||||
{ "value": 3, "text": "Docker" },
|
||||
{ "value": 4, "text": "Digital Ocean" }
|
||||
]
|
|
@ -46,12 +46,12 @@ Our default branch is for development of our Bootstrap 5 release. Head to the [`
|
|||
|
||||
Several quick start options are available:
|
||||
|
||||
- [Download the latest release](https://github.com/twbs/bootstrap/archive/v5.3.6.zip)
|
||||
- [Download the latest release](https://github.com/twbs/bootstrap/archive/v5.3.7.zip)
|
||||
- Clone the repo: `git clone https://github.com/twbs/bootstrap.git`
|
||||
- Install with [npm](https://www.npmjs.com/): `npm install bootstrap@v5.3.6`
|
||||
- Install with [yarn](https://yarnpkg.com/): `yarn add bootstrap@v5.3.6`
|
||||
- Install with [Bun](https://bun.sh/): `bun add bootstrap@v5.3.6`
|
||||
- Install with [Composer](https://getcomposer.org/): `composer require twbs/bootstrap:5.3.6`
|
||||
- Install with [npm](https://www.npmjs.com/): `npm install bootstrap@v5.3.7`
|
||||
- Install with [yarn](https://yarnpkg.com/): `yarn add bootstrap@v5.3.7`
|
||||
- Install with [Bun](https://bun.sh/): `bun add bootstrap@v5.3.7`
|
||||
- Install with [Composer](https://getcomposer.org/): `composer require twbs/bootstrap:5.3.7`
|
||||
- Install with [NuGet](https://www.nuget.org/): CSS: `Install-Package bootstrap` Sass: `Install-Package bootstrap.sass`
|
||||
|
||||
Read the [Getting started page](https://getbootstrap.com/docs/5.3/getting-started/introduction/) for information on the framework contents, templates, examples, and more.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*!
|
||||
* Bootstrap Grid v5.3.6 (https://getbootstrap.com/)
|
||||
* Bootstrap Grid v5.3.7 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2025 The Bootstrap Authors
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,5 +1,5 @@
|
|||
/*!
|
||||
* Bootstrap Grid v5.3.6 (https://getbootstrap.com/)
|
||||
* Bootstrap Grid v5.3.7 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2025 The Bootstrap Authors
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,5 +1,5 @@
|
|||
/*!
|
||||
* Bootstrap Reboot v5.3.6 (https://getbootstrap.com/)
|
||||
* Bootstrap Reboot v5.3.7 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2025 The Bootstrap Authors
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,5 +1,5 @@
|
|||
/*!
|
||||
* Bootstrap Reboot v5.3.6 (https://getbootstrap.com/)
|
||||
* Bootstrap Reboot v5.3.7 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2025 The Bootstrap Authors
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,5 +1,5 @@
|
|||
/*!
|
||||
* Bootstrap Utilities v5.3.6 (https://getbootstrap.com/)
|
||||
* Bootstrap Utilities v5.3.7 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2025 The Bootstrap Authors
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,5 +1,5 @@
|
|||
/*!
|
||||
* Bootstrap Utilities v5.3.6 (https://getbootstrap.com/)
|
||||
* Bootstrap Utilities v5.3.7 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2025 The Bootstrap Authors
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,6 +1,6 @@
|
|||
@charset "UTF-8";
|
||||
/*!
|
||||
* Bootstrap v5.3.6 (https://getbootstrap.com/)
|
||||
* Bootstrap v5.3.7 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2025 The Bootstrap Authors
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,6 +1,6 @@
|
|||
@charset "UTF-8";
|
||||
/*!
|
||||
* Bootstrap v5.3.6 (https://getbootstrap.com/)
|
||||
* Bootstrap v5.3.7 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2025 The Bootstrap Authors
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,5 +1,5 @@
|
|||
/*!
|
||||
* Bootstrap v5.3.6 (https://getbootstrap.com/)
|
||||
* Bootstrap v5.3.7 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2025 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
|
@ -647,7 +647,7 @@
|
|||
* Constants
|
||||
*/
|
||||
|
||||
const VERSION = '5.3.6';
|
||||
const VERSION = '5.3.7';
|
||||
|
||||
/**
|
||||
* Class definition
|
||||
|
@ -4805,7 +4805,6 @@
|
|||
*
|
||||
* Shout-out to Angular https://github.com/angular/angular/blob/15.2.8/packages/core/src/sanitization/url_sanitizer.ts#L38
|
||||
*/
|
||||
// eslint-disable-next-line unicorn/better-regex
|
||||
const SAFE_URL_PATTERN = /^(?!javascript:)(?:[a-z0-9+.-]+:|[^&:/?#]*(?:[/?#]|$))/i;
|
||||
const allowedAttribute = (attribute, allowedAttributeList) => {
|
||||
const attributeName = attribute.nodeName.toLowerCase();
|
||||
|
@ -5349,6 +5348,7 @@
|
|||
if (trigger === 'click') {
|
||||
EventHandler.on(this._element, this.constructor.eventName(EVENT_CLICK$1), this._config.selector, event => {
|
||||
const context = this._initializeOnDelegatedTarget(event);
|
||||
context._activeTrigger[TRIGGER_CLICK] = !(context._isShown() && context._activeTrigger[TRIGGER_CLICK]);
|
||||
context.toggle();
|
||||
});
|
||||
} else if (trigger !== TRIGGER_MANUAL) {
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,5 +1,5 @@
|
|||
/*!
|
||||
* Bootstrap v5.3.6 (https://getbootstrap.com/)
|
||||
* Bootstrap v5.3.7 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2025 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
|
@ -643,7 +643,7 @@ class Config {
|
|||
* Constants
|
||||
*/
|
||||
|
||||
const VERSION = '5.3.6';
|
||||
const VERSION = '5.3.7';
|
||||
|
||||
/**
|
||||
* Class definition
|
||||
|
@ -2964,7 +2964,6 @@ const uriAttributes = new Set(['background', 'cite', 'href', 'itemtype', 'longde
|
|||
*
|
||||
* Shout-out to Angular https://github.com/angular/angular/blob/15.2.8/packages/core/src/sanitization/url_sanitizer.ts#L38
|
||||
*/
|
||||
// eslint-disable-next-line unicorn/better-regex
|
||||
const SAFE_URL_PATTERN = /^(?!javascript:)(?:[a-z0-9+.-]+:|[^&:/?#]*(?:[/?#]|$))/i;
|
||||
const allowedAttribute = (attribute, allowedAttributeList) => {
|
||||
const attributeName = attribute.nodeName.toLowerCase();
|
||||
|
@ -3508,6 +3507,7 @@ class Tooltip extends BaseComponent {
|
|||
if (trigger === 'click') {
|
||||
EventHandler.on(this._element, this.constructor.eventName(EVENT_CLICK$1), this._config.selector, event => {
|
||||
const context = this._initializeOnDelegatedTarget(event);
|
||||
context._activeTrigger[TRIGGER_CLICK] = !(context._isShown() && context._activeTrigger[TRIGGER_CLICK]);
|
||||
context.toggle();
|
||||
});
|
||||
} else if (trigger !== TRIGGER_MANUAL) {
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,5 +1,5 @@
|
|||
/*!
|
||||
* Bootstrap v5.3.6 (https://getbootstrap.com/)
|
||||
* Bootstrap v5.3.7 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2025 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
|
@ -666,7 +666,7 @@
|
|||
* Constants
|
||||
*/
|
||||
|
||||
const VERSION = '5.3.6';
|
||||
const VERSION = '5.3.7';
|
||||
|
||||
/**
|
||||
* Class definition
|
||||
|
@ -2987,7 +2987,6 @@
|
|||
*
|
||||
* Shout-out to Angular https://github.com/angular/angular/blob/15.2.8/packages/core/src/sanitization/url_sanitizer.ts#L38
|
||||
*/
|
||||
// eslint-disable-next-line unicorn/better-regex
|
||||
const SAFE_URL_PATTERN = /^(?!javascript:)(?:[a-z0-9+.-]+:|[^&:/?#]*(?:[/?#]|$))/i;
|
||||
const allowedAttribute = (attribute, allowedAttributeList) => {
|
||||
const attributeName = attribute.nodeName.toLowerCase();
|
||||
|
@ -3531,6 +3530,7 @@
|
|||
if (trigger === 'click') {
|
||||
EventHandler.on(this._element, this.constructor.eventName(EVENT_CLICK$1), this._config.selector, event => {
|
||||
const context = this._initializeOnDelegatedTarget(event);
|
||||
context._activeTrigger[TRIGGER_CLICK] = !(context._isShown() && context._activeTrigger[TRIGGER_CLICK]);
|
||||
context.toggle();
|
||||
});
|
||||
} else if (trigger !== TRIGGER_MANUAL) {
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,5 +1,5 @@
|
|||
/*!
|
||||
* Bootstrap alert.js v5.3.6 (https://getbootstrap.com/)
|
||||
* Bootstrap alert.js v5.3.7 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2025 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*!
|
||||
* Bootstrap base-component.js v5.3.6 (https://getbootstrap.com/)
|
||||
* Bootstrap base-component.js v5.3.7 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2025 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
|
@ -21,7 +21,7 @@
|
|||
* Constants
|
||||
*/
|
||||
|
||||
const VERSION = '5.3.6';
|
||||
const VERSION = '5.3.7';
|
||||
|
||||
/**
|
||||
* Class definition
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"version":3,"file":"base-component.js","sources":["../src/base-component.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap base-component.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport Data from './dom/data.js'\nimport EventHandler from './dom/event-handler.js'\nimport Config from './util/config.js'\nimport { executeAfterTransition, getElement } from './util/index.js'\n\n/**\n * Constants\n */\n\nconst VERSION = '5.3.6'\n\n/**\n * Class definition\n */\n\nclass BaseComponent extends Config {\n constructor(element, config) {\n super()\n\n element = getElement(element)\n if (!element) {\n return\n }\n\n this._element = element\n this._config = this._getConfig(config)\n\n Data.set(this._element, this.constructor.DATA_KEY, this)\n }\n\n // Public\n dispose() {\n Data.remove(this._element, this.constructor.DATA_KEY)\n EventHandler.off(this._element, this.constructor.EVENT_KEY)\n\n for (const propertyName of Object.getOwnPropertyNames(this)) {\n this[propertyName] = null\n }\n }\n\n // Private\n _queueCallback(callback, element, isAnimated = true) {\n executeAfterTransition(callback, element, isAnimated)\n }\n\n _getConfig(config) {\n config = this._mergeConfigObj(config, this._element)\n config = this._configAfterMerge(config)\n this._typeCheckConfig(config)\n return config\n }\n\n // Static\n static getInstance(element) {\n return Data.get(getElement(element), this.DATA_KEY)\n }\n\n static getOrCreateInstance(element, config = {}) {\n return this.getInstance(element) || new this(element, typeof config === 'object' ? config : null)\n }\n\n static get VERSION() {\n return VERSION\n }\n\n static get DATA_KEY() {\n return `bs.${this.NAME}`\n }\n\n static get EVENT_KEY() {\n return `.${this.DATA_KEY}`\n }\n\n static eventName(name) {\n return `${name}${this.EVENT_KEY}`\n }\n}\n\nexport default BaseComponent\n"],"names":["VERSION","BaseComponent","Config","constructor","element","config","getElement","_element","_config","_getConfig","Data","set","DATA_KEY","dispose","remove","EventHandler","off","EVENT_KEY","propertyName","Object","getOwnPropertyNames","_queueCallback","callback","isAnimated","executeAfterTransition","_mergeConfigObj","_configAfterMerge","_typeCheckConfig","getInstance","get","getOrCreateInstance","NAME","eventName","name"],"mappings":";;;;;;;;;;;EAAA;EACA;EACA;EACA;EACA;EACA;;;EAOA;EACA;EACA;;EAEA,MAAMA,OAAO,GAAG,OAAO;;EAEvB;EACA;EACA;;EAEA,MAAMC,aAAa,SAASC,MAAM,CAAC;EACjCC,EAAAA,WAAWA,CAACC,OAAO,EAAEC,MAAM,EAAE;EAC3B,IAAA,KAAK,EAAE;EAEPD,IAAAA,OAAO,GAAGE,mBAAU,CAACF,OAAO,CAAC;MAC7B,IAAI,CAACA,OAAO,EAAE;EACZ,MAAA;EACF;MAEA,IAAI,CAACG,QAAQ,GAAGH,OAAO;MACvB,IAAI,CAACI,OAAO,GAAG,IAAI,CAACC,UAAU,CAACJ,MAAM,CAAC;EAEtCK,IAAAA,IAAI,CAACC,GAAG,CAAC,IAAI,CAACJ,QAAQ,EAAE,IAAI,CAACJ,WAAW,CAACS,QAAQ,EAAE,IAAI,CAAC;EAC1D;;EAEA;EACAC,EAAAA,OAAOA,GAAG;EACRH,IAAAA,IAAI,CAACI,MAAM,CAAC,IAAI,CAACP,QAAQ,EAAE,IAAI,CAACJ,WAAW,CAACS,QAAQ,CAAC;EACrDG,IAAAA,YAAY,CAACC,GAAG,CAAC,IAAI,CAACT,QAAQ,EAAE,IAAI,CAACJ,WAAW,CAACc,SAAS,CAAC;MAE3D,KAAK,MAAMC,YAAY,IAAIC,MAAM,CAACC,mBAAmB,CAAC,IAAI,CAAC,EAAE;EAC3D,MAAA,IAAI,CAACF,YAAY,CAAC,GAAG,IAAI;EAC3B;EACF;;EAEA;IACAG,cAAcA,CAACC,QAAQ,EAAElB,OAAO,EAAEmB,UAAU,GAAG,IAAI,EAAE;EACnDC,IAAAA,+BAAsB,CAACF,QAAQ,EAAElB,OAAO,EAAEmB,UAAU,CAAC;EACvD;IAEAd,UAAUA,CAACJ,MAAM,EAAE;MACjBA,MAAM,GAAG,IAAI,CAACoB,eAAe,CAACpB,MAAM,EAAE,IAAI,CAACE,QAAQ,CAAC;EACpDF,IAAAA,MAAM,GAAG,IAAI,CAACqB,iBAAiB,CAACrB,MAAM,CAAC;EACvC,IAAA,IAAI,CAACsB,gBAAgB,CAACtB,MAAM,CAAC;EAC7B,IAAA,OAAOA,MAAM;EACf;;EAEA;IACA,OAAOuB,WAAWA,CAACxB,OAAO,EAAE;EAC1B,IAAA,OAAOM,IAAI,CAACmB,GAAG,CAACvB,mBAAU,CAACF,OAAO,CAAC,EAAE,IAAI,CAACQ,QAAQ,CAAC;EACrD;IAEA,OAAOkB,mBAAmBA,CAAC1B,OAAO,EAAEC,MAAM,GAAG,EAAE,EAAE;MAC/C,OAAO,IAAI,CAACuB,WAAW,CAACxB,OAAO,CAAC,IAAI,IAAI,IAAI,CAACA,OAAO,EAAE,OAAOC,MAAM,KAAK,QAAQ,GAAGA,MAAM,GAAG,IAAI,CAAC;EACnG;IAEA,WAAWL,OAAOA,GAAG;EACnB,IAAA,OAAOA,OAAO;EAChB;IAEA,WAAWY,QAAQA,GAAG;EACpB,IAAA,OAAO,CAAM,GAAA,EAAA,IAAI,CAACmB,IAAI,CAAE,CAAA;EAC1B;IAEA,WAAWd,SAASA,GAAG;EACrB,IAAA,OAAO,CAAI,CAAA,EAAA,IAAI,CAACL,QAAQ,CAAE,CAAA;EAC5B;IAEA,OAAOoB,SAASA,CAACC,IAAI,EAAE;EACrB,IAAA,OAAO,GAAGA,IAAI,CAAA,EAAG,IAAI,CAAChB,SAAS,CAAE,CAAA;EACnC;EACF;;;;;;;;"}
|
||||
{"version":3,"file":"base-component.js","sources":["../src/base-component.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap base-component.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport Data from './dom/data.js'\nimport EventHandler from './dom/event-handler.js'\nimport Config from './util/config.js'\nimport { executeAfterTransition, getElement } from './util/index.js'\n\n/**\n * Constants\n */\n\nconst VERSION = '5.3.7'\n\n/**\n * Class definition\n */\n\nclass BaseComponent extends Config {\n constructor(element, config) {\n super()\n\n element = getElement(element)\n if (!element) {\n return\n }\n\n this._element = element\n this._config = this._getConfig(config)\n\n Data.set(this._element, this.constructor.DATA_KEY, this)\n }\n\n // Public\n dispose() {\n Data.remove(this._element, this.constructor.DATA_KEY)\n EventHandler.off(this._element, this.constructor.EVENT_KEY)\n\n for (const propertyName of Object.getOwnPropertyNames(this)) {\n this[propertyName] = null\n }\n }\n\n // Private\n _queueCallback(callback, element, isAnimated = true) {\n executeAfterTransition(callback, element, isAnimated)\n }\n\n _getConfig(config) {\n config = this._mergeConfigObj(config, this._element)\n config = this._configAfterMerge(config)\n this._typeCheckConfig(config)\n return config\n }\n\n // Static\n static getInstance(element) {\n return Data.get(getElement(element), this.DATA_KEY)\n }\n\n static getOrCreateInstance(element, config = {}) {\n return this.getInstance(element) || new this(element, typeof config === 'object' ? config : null)\n }\n\n static get VERSION() {\n return VERSION\n }\n\n static get DATA_KEY() {\n return `bs.${this.NAME}`\n }\n\n static get EVENT_KEY() {\n return `.${this.DATA_KEY}`\n }\n\n static eventName(name) {\n return `${name}${this.EVENT_KEY}`\n }\n}\n\nexport default BaseComponent\n"],"names":["VERSION","BaseComponent","Config","constructor","element","config","getElement","_element","_config","_getConfig","Data","set","DATA_KEY","dispose","remove","EventHandler","off","EVENT_KEY","propertyName","Object","getOwnPropertyNames","_queueCallback","callback","isAnimated","executeAfterTransition","_mergeConfigObj","_configAfterMerge","_typeCheckConfig","getInstance","get","getOrCreateInstance","NAME","eventName","name"],"mappings":";;;;;;;;;;;EAAA;EACA;EACA;EACA;EACA;EACA;;;EAOA;EACA;EACA;;EAEA,MAAMA,OAAO,GAAG,OAAO;;EAEvB;EACA;EACA;;EAEA,MAAMC,aAAa,SAASC,MAAM,CAAC;EACjCC,EAAAA,WAAWA,CAACC,OAAO,EAAEC,MAAM,EAAE;EAC3B,IAAA,KAAK,EAAE;EAEPD,IAAAA,OAAO,GAAGE,mBAAU,CAACF,OAAO,CAAC;MAC7B,IAAI,CAACA,OAAO,EAAE;EACZ,MAAA;EACF;MAEA,IAAI,CAACG,QAAQ,GAAGH,OAAO;MACvB,IAAI,CAACI,OAAO,GAAG,IAAI,CAACC,UAAU,CAACJ,MAAM,CAAC;EAEtCK,IAAAA,IAAI,CAACC,GAAG,CAAC,IAAI,CAACJ,QAAQ,EAAE,IAAI,CAACJ,WAAW,CAACS,QAAQ,EAAE,IAAI,CAAC;EAC1D;;EAEA;EACAC,EAAAA,OAAOA,GAAG;EACRH,IAAAA,IAAI,CAACI,MAAM,CAAC,IAAI,CAACP,QAAQ,EAAE,IAAI,CAACJ,WAAW,CAACS,QAAQ,CAAC;EACrDG,IAAAA,YAAY,CAACC,GAAG,CAAC,IAAI,CAACT,QAAQ,EAAE,IAAI,CAACJ,WAAW,CAACc,SAAS,CAAC;MAE3D,KAAK,MAAMC,YAAY,IAAIC,MAAM,CAACC,mBAAmB,CAAC,IAAI,CAAC,EAAE;EAC3D,MAAA,IAAI,CAACF,YAAY,CAAC,GAAG,IAAI;EAC3B;EACF;;EAEA;IACAG,cAAcA,CAACC,QAAQ,EAAElB,OAAO,EAAEmB,UAAU,GAAG,IAAI,EAAE;EACnDC,IAAAA,+BAAsB,CAACF,QAAQ,EAAElB,OAAO,EAAEmB,UAAU,CAAC;EACvD;IAEAd,UAAUA,CAACJ,MAAM,EAAE;MACjBA,MAAM,GAAG,IAAI,CAACoB,eAAe,CAACpB,MAAM,EAAE,IAAI,CAACE,QAAQ,CAAC;EACpDF,IAAAA,MAAM,GAAG,IAAI,CAACqB,iBAAiB,CAACrB,MAAM,CAAC;EACvC,IAAA,IAAI,CAACsB,gBAAgB,CAACtB,MAAM,CAAC;EAC7B,IAAA,OAAOA,MAAM;EACf;;EAEA;IACA,OAAOuB,WAAWA,CAACxB,OAAO,EAAE;EAC1B,IAAA,OAAOM,IAAI,CAACmB,GAAG,CAACvB,mBAAU,CAACF,OAAO,CAAC,EAAE,IAAI,CAACQ,QAAQ,CAAC;EACrD;IAEA,OAAOkB,mBAAmBA,CAAC1B,OAAO,EAAEC,MAAM,GAAG,EAAE,EAAE;MAC/C,OAAO,IAAI,CAACuB,WAAW,CAACxB,OAAO,CAAC,IAAI,IAAI,IAAI,CAACA,OAAO,EAAE,OAAOC,MAAM,KAAK,QAAQ,GAAGA,MAAM,GAAG,IAAI,CAAC;EACnG;IAEA,WAAWL,OAAOA,GAAG;EACnB,IAAA,OAAOA,OAAO;EAChB;IAEA,WAAWY,QAAQA,GAAG;EACpB,IAAA,OAAO,CAAM,GAAA,EAAA,IAAI,CAACmB,IAAI,CAAE,CAAA;EAC1B;IAEA,WAAWd,SAASA,GAAG;EACrB,IAAA,OAAO,CAAI,CAAA,EAAA,IAAI,CAACL,QAAQ,CAAE,CAAA;EAC5B;IAEA,OAAOoB,SAASA,CAACC,IAAI,EAAE;EACrB,IAAA,OAAO,GAAGA,IAAI,CAAA,EAAG,IAAI,CAAChB,SAAS,CAAE,CAAA;EACnC;EACF;;;;;;;;"}
|
|
@ -1,5 +1,5 @@
|
|||
/*!
|
||||
* Bootstrap button.js v5.3.6 (https://getbootstrap.com/)
|
||||
* Bootstrap button.js v5.3.7 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2025 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*!
|
||||
* Bootstrap carousel.js v5.3.6 (https://getbootstrap.com/)
|
||||
* Bootstrap carousel.js v5.3.7 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2025 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*!
|
||||
* Bootstrap collapse.js v5.3.6 (https://getbootstrap.com/)
|
||||
* Bootstrap collapse.js v5.3.7 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2025 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*!
|
||||
* Bootstrap data.js v5.3.6 (https://getbootstrap.com/)
|
||||
* Bootstrap data.js v5.3.7 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2025 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue