Compare commits
1 Commits
d1b04676a7
...
multipleau
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
26a10eb0df |
237
assets/mcu/htmx4.html
Normal file
237
assets/mcu/htmx4.html
Normal file
@@ -0,0 +1,237 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Typeahead Example with HTMX</title>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdn.jsdelivr.net/npm/bootstrap@4.1.3/dist/css/bootstrap.min.css"
|
||||
integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO"
|
||||
crossorigin="anonymous"
|
||||
/>
|
||||
<script src="https://unpkg.com/htmx.org@1.9.12/dist/htmx.js"></script>
|
||||
<style>
|
||||
.dropdown-menu {
|
||||
max-height: 200px;
|
||||
overflow-y: auto;
|
||||
width: 100%; /* Ensure the dropdown menu width matches the input width */
|
||||
}
|
||||
.dropdown-menu.show {
|
||||
display: block; /* Ensure the dropdown menu is displayed */
|
||||
}
|
||||
.spinner-border {
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
}
|
||||
.badge-container {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
margin-top: 10px;
|
||||
}
|
||||
.badge-container .badge {
|
||||
margin: 2px;
|
||||
}
|
||||
.badge-container input {
|
||||
border: none;
|
||||
outline: none;
|
||||
flex-grow: 1;
|
||||
}
|
||||
.dropdown-item.active {
|
||||
background-color: #007bff;
|
||||
color: white;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container mt-5">
|
||||
<h2>Typeahead Example with HTMX</h2>
|
||||
<input type="text" name="selectedvalue" />
|
||||
<div class="dropdown">
|
||||
<input
|
||||
type="text"
|
||||
id="search-inputx"
|
||||
name="query"
|
||||
placeholder="Search for a state..."
|
||||
hx-get="http://localhost:5000/mcu/proses_obj_search.php"
|
||||
hx-trigger="input changed delay:300ms, focus from:search-inputx"
|
||||
hx-target="#dropdown-menu"
|
||||
hx-indicator="#loading-indicator"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="false"
|
||||
autocomplete="off"
|
||||
hx-include="[name='selectedvalue']"
|
||||
class="form-control"
|
||||
/>
|
||||
<div id="loading-indicator" style="display: none">
|
||||
<div class="spinner-border text-primary" role="status">
|
||||
<span class="sr-only">Loading...</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dropdown-menu" id="dropdown-menu"></div>
|
||||
</div>
|
||||
|
||||
<div class="badge-container form-control">
|
||||
<!-- Badge will be appended here -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
let selectedItems = [];
|
||||
|
||||
function selectItem(element) {
|
||||
var container = document.querySelector(".badge-container");
|
||||
|
||||
// Get the selected item text and id
|
||||
var itemText = element.textContent;
|
||||
var itemId = element.getAttribute("data-id");
|
||||
|
||||
// Check if the item is already selected
|
||||
if (selectedItems.some((item) => item.id === itemId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Add the item to the selected items list
|
||||
selectedItems.push({ id: itemId, name: itemText });
|
||||
|
||||
// Create a badge element
|
||||
var badge = document.createElement("span");
|
||||
badge.className = "badge badge-primary";
|
||||
badge.textContent = itemText;
|
||||
|
||||
// Create a close button
|
||||
var closeBtn = document.createElement("span");
|
||||
closeBtn.className = "badge badge-light ml-1";
|
||||
closeBtn.style.cursor = "pointer";
|
||||
closeBtn.textContent = "×";
|
||||
closeBtn.onclick = function () {
|
||||
container.removeChild(badge);
|
||||
selectedItems = selectedItems.filter((item) => item.id !== itemId);
|
||||
updateQueryParameter();
|
||||
};
|
||||
|
||||
// Append close button to badge
|
||||
badge.appendChild(closeBtn);
|
||||
|
||||
// Append the badge to the container
|
||||
container.appendChild(badge);
|
||||
|
||||
// Clear the input
|
||||
document.getElementById("search-inputx").value = "";
|
||||
|
||||
// Hide dropdown
|
||||
document.getElementById("dropdown-menu").classList.remove("show");
|
||||
|
||||
// Highlight the selected item in the dropdown
|
||||
element.classList.add("selected");
|
||||
|
||||
// Update query parameter
|
||||
updateQueryParameter();
|
||||
}
|
||||
|
||||
function updateQueryParameter() {
|
||||
var selectedValues = selectedItems.map((item) => item.id).join(",");
|
||||
document.querySelector('input[name="selectedvalue"]').value =
|
||||
selectedValues;
|
||||
}
|
||||
|
||||
// Display loading indicator when request is in progress
|
||||
document.body.addEventListener("htmx:configRequest", function (event) {
|
||||
document.getElementById("loading-indicator").style.display = "block";
|
||||
});
|
||||
|
||||
document.body.addEventListener("htmx:afterOnLoad", function (event) {
|
||||
document.getElementById("loading-indicator").style.display = "none";
|
||||
var dropdown = document.getElementById("dropdown-menu");
|
||||
if (dropdown.children.length > 0) {
|
||||
dropdown.classList.add("show");
|
||||
dropdown.focus();
|
||||
var activeItem = dropdown.querySelector(".active");
|
||||
if (activeItem) {
|
||||
dropdown.scrollTop = activeItem.offsetTop - dropdown.offsetTop;
|
||||
}
|
||||
} else {
|
||||
dropdown.classList.remove("show");
|
||||
}
|
||||
});
|
||||
|
||||
// Hide the dropdown when clicking outside
|
||||
document.addEventListener("click", function (event) {
|
||||
var isClickInside =
|
||||
event.target.classList.contains("search-input") ||
|
||||
event.target.classList.contains("badge-container") ||
|
||||
event.target.closest(".badge-container");
|
||||
if (!isClickInside) {
|
||||
document.getElementById("dropdown-menu").classList.remove("show");
|
||||
}
|
||||
});
|
||||
|
||||
// Handle keyboard navigation
|
||||
document
|
||||
.getElementById("search-inputx")
|
||||
.addEventListener("keydown", function (event) {
|
||||
var dropdownMenu = document.getElementById("dropdown-menu");
|
||||
var items = dropdownMenu.querySelectorAll(".dropdown-item");
|
||||
var activeItem = dropdownMenu.querySelector(".active");
|
||||
|
||||
if (event.key === "ArrowDown") {
|
||||
event.preventDefault(); // Prevent page scroll
|
||||
if (!activeItem) {
|
||||
items[0].classList.add("active");
|
||||
} else {
|
||||
activeItem.classList.remove("active");
|
||||
var next = activeItem.nextElementSibling;
|
||||
if (next) {
|
||||
next.classList.add("active");
|
||||
} else {
|
||||
items[0].classList.add("active");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (event.key === "ArrowUp") {
|
||||
event.preventDefault(); // Prevent page scroll
|
||||
if (!activeItem) {
|
||||
items[items.length - 1].classList.add("active");
|
||||
} else {
|
||||
activeItem.classList.remove("active");
|
||||
var prev = activeItem.previousElementSibling;
|
||||
if (prev) {
|
||||
prev.classList.add("active");
|
||||
} else {
|
||||
items[items.length - 1].classList.add("active");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (event.key === "Enter" && activeItem) {
|
||||
selectItem(activeItem);
|
||||
}
|
||||
|
||||
if (activeItem) {
|
||||
dropdownMenu.scrollTop =
|
||||
activeItem.offsetTop - dropdownMenu.offsetTop;
|
||||
}
|
||||
});
|
||||
|
||||
// Set the input value and hide the dropdown when an item is clicked
|
||||
document.body.addEventListener("click", function (event) {
|
||||
if (event.target.classList.contains("dropdown-item")) {
|
||||
selectItem(event.target);
|
||||
}
|
||||
});
|
||||
|
||||
// Show dropdown when input gets focus and has value
|
||||
document
|
||||
.getElementById("search-inputx")
|
||||
.addEventListener("focus", function (event) {
|
||||
var input = event.target;
|
||||
var dropdown = document.getElementById("dropdown-menu");
|
||||
if (input.value.length > 0) {
|
||||
dropdown.classList.add("show");
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
33
assets/mcu/proses_obj_search.php
Normal file
33
assets/mcu/proses_obj_search.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
header('Content-Type: text/html'); // Set header to indicate HTML response
|
||||
|
||||
// Data dummy dengan id dan nama sebagai contoh
|
||||
$data = [
|
||||
["id" => 1, "name" => "Alabama"],
|
||||
["id" => 2, "name" => "Alaska"],
|
||||
// other data...
|
||||
["id" => 49, "name" => "Wisconsin"],
|
||||
["id" => 50, "name" => "Wyoming"],
|
||||
];
|
||||
|
||||
$query = isset($_GET['query']) ? $_GET['query'] : '';
|
||||
$selected = isset($_GET['selectedvalue']) ? explode(',', $_GET['selectedvalue']) : [];
|
||||
|
||||
if ($query) {
|
||||
$results = array_filter($data, function($item) use ($query, $selected) {
|
||||
// Filter out items that do not match the query and are already selected
|
||||
return stripos($item["name"], $query) !== false && !in_array($item["id"], $selected);
|
||||
});
|
||||
} else {
|
||||
$results = [];
|
||||
}
|
||||
|
||||
// Prepare HTML response
|
||||
$html = '';
|
||||
foreach ($results as $result) {
|
||||
$html .= '<a class="dropdown-item" href="#" data-id="' . htmlspecialchars($result["id"]) . '" onclick="selectItem(this)">' . htmlspecialchars($result["name"]) . '</a>';
|
||||
}
|
||||
|
||||
// Return HTML response
|
||||
echo $html;
|
||||
?>
|
||||
74
handlers/dev/xsampleautocomplete.handlers.go
Normal file
74
handlers/dev/xsampleautocomplete.handlers.go
Normal file
@@ -0,0 +1,74 @@
|
||||
package dev_handlers
|
||||
|
||||
import (
|
||||
"cpone/models"
|
||||
"cpone/utils"
|
||||
dev_xsampleautocomplete "cpone/views/dev/xsampleautocomplete"
|
||||
"fmt"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type XSampleAutoCompleteServices interface {
|
||||
GetListT_Test(search string, selectedIdxArr string) ([]models.XsampleT_Test, []models.XsampleT_Test, error)
|
||||
}
|
||||
|
||||
func NewXSampleAutoCompleteHandler(us XSampleAutoCompleteServices) *XSampleAutoCompleteHandler {
|
||||
return &XSampleAutoCompleteHandler{
|
||||
XSampleAutoCompleteServices: us,
|
||||
}
|
||||
}
|
||||
|
||||
type XSampleAutoCompleteHandler struct {
|
||||
XSampleAutoCompleteServices XSampleAutoCompleteServices
|
||||
}
|
||||
|
||||
// INITIAL
|
||||
func (lh *XSampleAutoCompleteHandler) HandleShowXSampleAutoComplete(c echo.Context) error {
|
||||
// logger, _ := zap.NewProduction()
|
||||
// dataList, dataSelected, err := lh.XSampleAutoCompleteServices.GetListT_Test("", "")
|
||||
|
||||
// if err != nil {
|
||||
// defer logger.Sync()
|
||||
// logger.Info("ERROR GET GROUP RESULT",
|
||||
// zap.Any("error", err),
|
||||
// )
|
||||
// fmt.Println(dataList)
|
||||
// fmt.Println(dataSelected)
|
||||
// return err
|
||||
// }
|
||||
|
||||
view := dev_xsampleautocomplete.ShowXSampleScreen("AutoComplete",
|
||||
dev_xsampleautocomplete.MainAutoComplete(),
|
||||
dev_xsampleautocomplete.CssXsampleAutoComplete(),
|
||||
dev_xsampleautocomplete.TemplJsAutoComplete(),
|
||||
dev_xsampleautocomplete.EmptyDiv1(),
|
||||
dev_xsampleautocomplete.EmptyDiv1(),
|
||||
dev_xsampleautocomplete.EmptyDiv1())
|
||||
return utils.View(c, view)
|
||||
}
|
||||
|
||||
// PROSES SEARCH
|
||||
func (lh *XSampleAutoCompleteHandler) HandleSearchAutoComplete(c echo.Context) error {
|
||||
logger, _ := zap.NewProduction()
|
||||
|
||||
query := c.QueryParam("query")
|
||||
selectedValue := c.QueryParam("selectedvalue")
|
||||
|
||||
dataList, dataSelected, err := lh.XSampleAutoCompleteServices.GetListT_Test(query, selectedValue)
|
||||
|
||||
if err != nil {
|
||||
defer logger.Sync()
|
||||
logger.Info("ERROR GET GROUP RESULT",
|
||||
zap.Any("error", err),
|
||||
)
|
||||
fmt.Println(dataList)
|
||||
fmt.Println(dataSelected)
|
||||
return err
|
||||
}
|
||||
|
||||
view := dev_xsampleautocomplete.ListData(dataList)
|
||||
|
||||
return utils.View(c, view)
|
||||
}
|
||||
@@ -291,4 +291,10 @@ func SetupRoutesDev(app *echo.Echo, appStore db.AppStore) {
|
||||
dev.GET("/md/groupresultv2/opendelete", devMdGRhandlers.HandleOpenDeleteForm)
|
||||
dev.POST("/md/groupresultv2/closedeleteform", devMdGRhandlers.HandleCloseFormDelete)
|
||||
dev.POST("/md/groupresultv2/delete", devMdGRhandlers.HandleDeleteUserGroup)
|
||||
|
||||
// autocomplete
|
||||
devAutoServices := dev_services.NewServicesXSampleAutoComplete(appStore)
|
||||
devAutohandlers := dev_handlers.NewXSampleAutoCompleteHandler(devAutoServices)
|
||||
dev.GET("/autocompletev1", devAutohandlers.HandleShowXSampleAutoComplete)
|
||||
dev.GET("/searchautocompletev1", devAutohandlers.HandleSearchAutoComplete)
|
||||
}
|
||||
|
||||
7
models/xsampleautocomplete.models.go
Normal file
7
models/xsampleautocomplete.models.go
Normal file
@@ -0,0 +1,7 @@
|
||||
package models
|
||||
|
||||
type XsampleT_Test struct {
|
||||
T_TestID int `db:"T_TestID"`
|
||||
T_TestCode string `db:"T_TestCode"`
|
||||
T_TestName string `db:"T_TestName"`
|
||||
}
|
||||
86
services/dev/xsampleautocomplete.services.go
Normal file
86
services/dev/xsampleautocomplete.services.go
Normal file
@@ -0,0 +1,86 @@
|
||||
package dev_services
|
||||
|
||||
import (
|
||||
"cpone/db"
|
||||
"cpone/models"
|
||||
dbx "cpone/package/database"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
func NewServicesXSampleAutoComplete(uStore db.AppStore) *ServicesXSampleAutoComplete {
|
||||
|
||||
return &ServicesXSampleAutoComplete{
|
||||
XSampleAutoCompleteStore: uStore,
|
||||
}
|
||||
}
|
||||
|
||||
type ServicesXSampleAutoComplete struct {
|
||||
XSampleAutoCompleteStore db.AppStore
|
||||
}
|
||||
|
||||
// LIST T_Test plus search
|
||||
func (su *ServicesXSampleAutoComplete) GetListT_Test(search string, selectedIdxArr string) ([]models.XsampleT_Test, []models.XsampleT_Test, error) {
|
||||
var dataList []models.XsampleT_Test
|
||||
var dataListSelected []models.XsampleT_Test
|
||||
// var dataListNew []models.XsampleT_Test
|
||||
|
||||
logger, _ := zap.NewProduction()
|
||||
defer logger.Sync()
|
||||
|
||||
prm := "%" + strings.TrimSpace(search) + "%"
|
||||
|
||||
// Check if selectedIdxArr is not empty
|
||||
if len(selectedIdxArr) > 0 {
|
||||
qrySelected := fmt.Sprintf(`
|
||||
SELECT T_TestID, T_TestCode, T_TestName
|
||||
FROM t_test
|
||||
WHERE T_TestIsActive = 'Y'
|
||||
AND T_TestID IN (%s)
|
||||
LIMIT 0, 50
|
||||
`, selectedIdxArr)
|
||||
|
||||
err := dbx.Handlex.Select(&dataListSelected, qrySelected)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error querying database: %v", err)
|
||||
}
|
||||
|
||||
qryListX := fmt.Sprintf(`SELECT T_TestID, T_TestCode, T_TestName
|
||||
FROM t_test
|
||||
WHERE T_TestIsActive = 'Y'
|
||||
AND (T_TestCode LIKE ? OR T_TestName LIKE ?)
|
||||
AND T_TestID NOT IN (%s)
|
||||
LIMIT 0, 50
|
||||
`, selectedIdxArr)
|
||||
|
||||
logger.Info("QUERY SEARCH INITIAL TOTAL COUNT",
|
||||
zap.String("query search", qryListX),
|
||||
)
|
||||
|
||||
errx := dbx.Handlex.Select(&dataList, qryListX, prm, prm)
|
||||
if errx != nil {
|
||||
return nil, nil, fmt.Errorf("error querying database: %v", err)
|
||||
}
|
||||
} else {
|
||||
qryList := `
|
||||
SELECT T_TestID, T_TestCode, T_TestName
|
||||
FROM t_test
|
||||
WHERE T_TestIsActive = 'Y'
|
||||
AND (T_TestCode LIKE ? OR T_TestName LIKE ?)
|
||||
LIMIT 0, 50
|
||||
`
|
||||
|
||||
logger.Info("QUERY SEARCH INITIAL TOTAL COUNT",
|
||||
zap.String("query search", qryList),
|
||||
)
|
||||
|
||||
err := dbx.Handlex.Select(&dataList, qryList, prm, prm)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error querying database: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
return dataList, dataListSelected, nil
|
||||
}
|
||||
280
views/dev/xsampleautocomplete/xsampleautocomplete.templ
Normal file
280
views/dev/xsampleautocomplete/xsampleautocomplete.templ
Normal file
@@ -0,0 +1,280 @@
|
||||
package dev_xsampleautocomplete
|
||||
|
||||
import (
|
||||
"cpone/layout"
|
||||
"cpone/models"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
templ EmptyDiv1() {
|
||||
<div></div>
|
||||
}
|
||||
|
||||
templ Selected(data []models.XsampleT_Test) {
|
||||
if len(data) > 0 {
|
||||
for _, v := range data {
|
||||
<span class="badge badge-primary">
|
||||
{ v.T_TestCode } - { v.T_TestName }
|
||||
<span class="badge badge-light ml-1" style="cursor: pointer;">×</span>
|
||||
</span>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
templ ListData(dataList []models.XsampleT_Test) {
|
||||
if len(dataList) > 0 {
|
||||
<div class="dropdown-menu show" id="dropdown-menu" hx-swap-oob="true">
|
||||
for _, v := range dataList {
|
||||
<a class="dropdown-item" data-id={ strconv.Itoa(v.T_TestID) } onclick="selectItem(this)">{ v.T_TestCode } - { v.T_TestName }</a>
|
||||
}
|
||||
</div>
|
||||
} else {
|
||||
<div class="dropdown-menu" id="dropdown-menu" hx-swap-oob="true">
|
||||
<a class="dropdown-item" data-id="" onclick="">Tidak Ada Data</a>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
templ MainAutoComplete() {
|
||||
<div class="container mt-5">
|
||||
<h2>Typeahead Example with HTMX</h2>
|
||||
<input type="text" name="selectedvalue"/>
|
||||
<div class="dropdown">
|
||||
<input
|
||||
type="text"
|
||||
id="search-inputx"
|
||||
name="query"
|
||||
placeholder="Search for a state..."
|
||||
hx-get="/dev/searchautocompletev1"
|
||||
hx-trigger="input changed delay:300ms, focus from:search-inputx"
|
||||
hx-target="#dropdown-menu"
|
||||
hx-indicator="#loading-indicator"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="false"
|
||||
autocomplete="off"
|
||||
hx-include="[name='selectedvalue']"
|
||||
class="form-control"
|
||||
/>
|
||||
<div id="loading-indicator" style="display:none;">
|
||||
<div class="spinner-border text-primary" role="status">
|
||||
<span class="sr-only">Loading...</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dropdown-menu" id="dropdown-menu"></div>
|
||||
</div>
|
||||
<div class="badge-container form-control"></div>
|
||||
</div>
|
||||
@JsCustomAutoComplete()
|
||||
}
|
||||
|
||||
templ TemplJsAutoComplete() {
|
||||
}
|
||||
|
||||
script JsCustomAutoComplete() {
|
||||
let selectedItems = [];
|
||||
|
||||
function selectItem(element) {
|
||||
var container = document.querySelector('.badge-container');
|
||||
|
||||
// Get the selected item text and id
|
||||
var itemText = element.textContent;
|
||||
var itemId = element.getAttribute('data-id');
|
||||
|
||||
// Check if the item is already selected
|
||||
if (selectedItems.some(item => item.id === itemId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Add the item to the selected items list
|
||||
selectedItems.push({ id: itemId, name: itemText });
|
||||
|
||||
// Create a badge element
|
||||
var badge = document.createElement('span');
|
||||
badge.className = 'badge badge-primary';
|
||||
badge.textContent = itemText;
|
||||
|
||||
// Create a close button
|
||||
var closeBtn = document.createElement('span');
|
||||
closeBtn.className = 'badge badge-light ml-1';
|
||||
closeBtn.style.cursor = 'pointer';
|
||||
closeBtn.textContent = '×';
|
||||
closeBtn.onclick = function() {
|
||||
container.removeChild(badge);
|
||||
selectedItems = selectedItems.filter(item => item.id !== itemId);
|
||||
updateQueryParameter();
|
||||
};
|
||||
|
||||
// Append close button to badge
|
||||
badge.appendChild(closeBtn);
|
||||
|
||||
// Append the badge to the container
|
||||
container.appendChild(badge);
|
||||
|
||||
// Clear the input
|
||||
document.getElementById('search-inputx').value = '';
|
||||
|
||||
// Hide dropdown
|
||||
document.getElementById('dropdown-menu').classList.remove('show');
|
||||
|
||||
// Highlight the selected item in the dropdown
|
||||
element.classList.add('selected');
|
||||
|
||||
// Update query parameter
|
||||
updateQueryParameter();
|
||||
}
|
||||
|
||||
function updateQueryParameter() {
|
||||
var selectedValues = selectedItems.map(item => item.id).join(',');
|
||||
document.querySelector('input[name="selectedvalue"]').value = selectedValues;
|
||||
}
|
||||
|
||||
// Display loading indicator when request is in progress
|
||||
document.body.addEventListener('htmx:configRequest', function(event) {
|
||||
document.getElementById('loading-indicator').style.display = 'block';
|
||||
});
|
||||
|
||||
document.body.addEventListener('htmx:afterOnLoad', function(event) {
|
||||
document.getElementById('loading-indicator').style.display = 'none';
|
||||
var dropdown = document.getElementById('dropdown-menu');
|
||||
if (dropdown.children.length > 0) {
|
||||
dropdown.classList.add('show');
|
||||
dropdown.focus();
|
||||
var activeItem = dropdown.querySelector('.active');
|
||||
if (activeItem) {
|
||||
dropdown.scrollTop = activeItem.offsetTop - dropdown.offsetTop;
|
||||
}
|
||||
} else {
|
||||
dropdown.classList.remove('show');
|
||||
}
|
||||
});
|
||||
|
||||
// Hide the dropdown when clicking outside
|
||||
document.addEventListener('click', function(event) {
|
||||
var isClickInside = event.target.classList.contains('search-input') || event.target.classList.contains('badge-container') || event.target.closest('.badge-container');
|
||||
if (!isClickInside) {
|
||||
document.getElementById('dropdown-menu').classList.remove('show');
|
||||
}
|
||||
});
|
||||
|
||||
// Handle keyboard navigation
|
||||
document.getElementById('search-inputx').addEventListener('keydown', function(event) {
|
||||
var dropdownMenu = document.getElementById('dropdown-menu');
|
||||
var items = dropdownMenu.querySelectorAll('.dropdown-item');
|
||||
var activeItem = dropdownMenu.querySelector('.active');
|
||||
|
||||
if (event.key === 'ArrowDown') {
|
||||
event.preventDefault(); // Prevent page scroll
|
||||
if (!activeItem) {
|
||||
items[0].classList.add('active');
|
||||
} else {
|
||||
activeItem.classList.remove('active');
|
||||
var next = activeItem.nextElementSibling;
|
||||
if (next) {
|
||||
next.classList.add('active');
|
||||
} else {
|
||||
items[0].classList.add('active');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (event.key === 'ArrowUp') {
|
||||
event.preventDefault(); // Prevent page scroll
|
||||
if (!activeItem) {
|
||||
items[items.length - 1].classList.add('active');
|
||||
} else {
|
||||
activeItem.classList.remove('active');
|
||||
var prev = activeItem.previousElementSibling;
|
||||
if (prev) {
|
||||
prev.classList.add('active');
|
||||
} else {
|
||||
items[items.length - 1].classList.add('active');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (event.key === 'Enter' && activeItem) {
|
||||
selectItem(activeItem);
|
||||
}
|
||||
|
||||
if (activeItem) {
|
||||
dropdownMenu.scrollTop = activeItem.offsetTop - dropdownMenu.offsetTop;
|
||||
}
|
||||
});
|
||||
|
||||
// Set the input value and hide the dropdown when an item is clicked
|
||||
document.body.addEventListener('click', function(event) {
|
||||
if (event.target.classList.contains('dropdown-item')) {
|
||||
selectItem(event.target);
|
||||
}
|
||||
});
|
||||
|
||||
// Show dropdown when input gets focus and has value
|
||||
document.getElementById('search-inputx').addEventListener('focus', function(event) {
|
||||
var input = event.target;
|
||||
var dropdown = document.getElementById('dropdown-menu');
|
||||
if (input.value.length > 0) {
|
||||
dropdown.classList.add('show');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
templ CssXsampleAutoComplete() {
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="assets/css/googlefont/poppins.css"
|
||||
/>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="assets/css/googlefont/publicsans.css"
|
||||
/>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="assets/css/googlefont/roboto.css"
|
||||
/>
|
||||
<style>
|
||||
body {
|
||||
background-color: white;
|
||||
/* padding-right: 100px;
|
||||
padding-left: 100px; */
|
||||
}
|
||||
.dropdown-menu {
|
||||
max-height: 200px;
|
||||
overflow-y: auto;
|
||||
width: 100%; /* Ensure the dropdown menu width matches the input width */
|
||||
}
|
||||
.dropdown-menu.show {
|
||||
display: block; /* Ensure the dropdown menu is displayed */
|
||||
}
|
||||
.spinner-border {
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
}
|
||||
.badge-container {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
margin-top: 10px;
|
||||
}
|
||||
.badge-container .badge {
|
||||
margin: 2px;
|
||||
}
|
||||
.badge-container input {
|
||||
border: none;
|
||||
outline: none;
|
||||
flex-grow: 1;
|
||||
}
|
||||
.dropdown-item.active {
|
||||
background-color: #007bff;
|
||||
color: white;
|
||||
}
|
||||
</style>
|
||||
}
|
||||
|
||||
templ ShowXSampleScreen(title string, cmp templ.Component, css templ.Component, js templ.Component,
|
||||
navbarmenu templ.Component,
|
||||
navbaruser templ.Component,
|
||||
userprofile templ.Component) {
|
||||
@layout.CorporateLayout(title, css, js, navbarmenu, navbaruser, userprofile) {
|
||||
@cmp
|
||||
}
|
||||
}
|
||||
443
views/dev/xsampleautocomplete/xsampleautocomplete_templ.go
Normal file
443
views/dev/xsampleautocomplete/xsampleautocomplete_templ.go
Normal file
@@ -0,0 +1,443 @@
|
||||
// Code generated by templ - DO NOT EDIT.
|
||||
|
||||
// templ: version: v0.2.663
|
||||
package dev_xsampleautocomplete
|
||||
|
||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
||||
|
||||
import "github.com/a-h/templ"
|
||||
import "context"
|
||||
import "io"
|
||||
import "bytes"
|
||||
|
||||
import (
|
||||
"cpone/layout"
|
||||
"cpone/models"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func EmptyDiv1() templ.Component {
|
||||
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
templ_7745c5c3_Buffer = templ.GetBuffer()
|
||||
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var1 == nil {
|
||||
templ_7745c5c3_Var1 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
func Selected(data []models.XsampleT_Test) templ.Component {
|
||||
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
templ_7745c5c3_Buffer = templ.GetBuffer()
|
||||
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var2 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var2 == nil {
|
||||
templ_7745c5c3_Var2 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
if len(data) > 0 {
|
||||
for _, v := range data {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<span class=\"badge badge-primary\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var3 string
|
||||
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(v.T_TestCode)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views\dev\xsampleautocomplete\xsampleautocomplete.templ`, Line: 17, Col: 18}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" - ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var4 string
|
||||
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(v.T_TestName)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views\dev\xsampleautocomplete\xsampleautocomplete.templ`, Line: 17, Col: 37}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" <span class=\"badge badge-light ml-1\" style=\"cursor: pointer;\">×</span></span>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
}
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
func ListData(dataList []models.XsampleT_Test) templ.Component {
|
||||
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
templ_7745c5c3_Buffer = templ.GetBuffer()
|
||||
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var5 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var5 == nil {
|
||||
templ_7745c5c3_Var5 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
if len(dataList) > 0 {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"dropdown-menu show\" id=\"dropdown-menu\" hx-swap-oob=\"true\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
for _, v := range dataList {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<a class=\"dropdown-item\" data-id=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var6 string
|
||||
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(strconv.Itoa(v.T_TestID))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views\dev\xsampleautocomplete\xsampleautocomplete.templ`, Line: 28, Col: 63}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" onclick=\"selectItem(this)\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var7 string
|
||||
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(v.T_TestCode)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views\dev\xsampleautocomplete\xsampleautocomplete.templ`, Line: 28, Col: 107}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" - ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var8 string
|
||||
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(v.T_TestName)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views\dev\xsampleautocomplete\xsampleautocomplete.templ`, Line: 28, Col: 126}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</a>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
} else {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"dropdown-menu\" id=\"dropdown-menu\" hx-swap-oob=\"true\"><a class=\"dropdown-item\" data-id=\"\" onclick=\"\">Tidak Ada Data</a></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
func MainAutoComplete() templ.Component {
|
||||
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
templ_7745c5c3_Buffer = templ.GetBuffer()
|
||||
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var9 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var9 == nil {
|
||||
templ_7745c5c3_Var9 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"container mt-5\"><h2>Typeahead Example with HTMX</h2><input type=\"text\" name=\"selectedvalue\"><div class=\"dropdown\"><input type=\"text\" id=\"search-inputx\" name=\"query\" placeholder=\"Search for a state...\" hx-get=\"/dev/searchautocompletev1\" hx-trigger=\"input changed delay:300ms, focus from:search-inputx\" hx-target=\"#dropdown-menu\" hx-indicator=\"#loading-indicator\" aria-haspopup=\"true\" aria-expanded=\"false\" autocomplete=\"off\" hx-include=\"[name='selectedvalue']\" class=\"form-control\"><div id=\"loading-indicator\" style=\"display:none;\"><div class=\"spinner-border text-primary\" role=\"status\"><span class=\"sr-only\">Loading...</span></div></div><div class=\"dropdown-menu\" id=\"dropdown-menu\"></div></div><div class=\"badge-container form-control\"></div></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = JsCustomAutoComplete().Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
func TemplJsAutoComplete() templ.Component {
|
||||
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
templ_7745c5c3_Buffer = templ.GetBuffer()
|
||||
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var10 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var10 == nil {
|
||||
templ_7745c5c3_Var10 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
func JsCustomAutoComplete() templ.ComponentScript {
|
||||
return templ.ComponentScript{
|
||||
Name: `__templ_JsCustomAutoComplete_4b2e`,
|
||||
Function: `function __templ_JsCustomAutoComplete_4b2e(){let selectedItems = [];
|
||||
|
||||
function selectItem(element) {
|
||||
var container = document.querySelector('.badge-container');
|
||||
|
||||
// Get the selected item text and id
|
||||
var itemText = element.textContent;
|
||||
var itemId = element.getAttribute('data-id');
|
||||
|
||||
// Check if the item is already selected
|
||||
if (selectedItems.some(item => item.id === itemId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Add the item to the selected items list
|
||||
selectedItems.push({ id: itemId, name: itemText });
|
||||
|
||||
// Create a badge element
|
||||
var badge = document.createElement('span');
|
||||
badge.className = 'badge badge-primary';
|
||||
badge.textContent = itemText;
|
||||
|
||||
// Create a close button
|
||||
var closeBtn = document.createElement('span');
|
||||
closeBtn.className = 'badge badge-light ml-1';
|
||||
closeBtn.style.cursor = 'pointer';
|
||||
closeBtn.textContent = '×';
|
||||
closeBtn.onclick = function() {
|
||||
container.removeChild(badge);
|
||||
selectedItems = selectedItems.filter(item => item.id !== itemId);
|
||||
updateQueryParameter();
|
||||
};
|
||||
|
||||
// Append close button to badge
|
||||
badge.appendChild(closeBtn);
|
||||
|
||||
// Append the badge to the container
|
||||
container.appendChild(badge);
|
||||
|
||||
// Clear the input
|
||||
document.getElementById('search-inputx').value = '';
|
||||
|
||||
// Hide dropdown
|
||||
document.getElementById('dropdown-menu').classList.remove('show');
|
||||
|
||||
// Highlight the selected item in the dropdown
|
||||
element.classList.add('selected');
|
||||
|
||||
// Update query parameter
|
||||
updateQueryParameter();
|
||||
}
|
||||
|
||||
function updateQueryParameter() {
|
||||
var selectedValues = selectedItems.map(item => item.id).join(',');
|
||||
document.querySelector('input[name="selectedvalue"]').value = selectedValues;
|
||||
}
|
||||
|
||||
// Display loading indicator when request is in progress
|
||||
document.body.addEventListener('htmx:configRequest', function(event) {
|
||||
document.getElementById('loading-indicator').style.display = 'block';
|
||||
});
|
||||
|
||||
document.body.addEventListener('htmx:afterOnLoad', function(event) {
|
||||
document.getElementById('loading-indicator').style.display = 'none';
|
||||
var dropdown = document.getElementById('dropdown-menu');
|
||||
if (dropdown.children.length > 0) {
|
||||
dropdown.classList.add('show');
|
||||
dropdown.focus();
|
||||
var activeItem = dropdown.querySelector('.active');
|
||||
if (activeItem) {
|
||||
dropdown.scrollTop = activeItem.offsetTop - dropdown.offsetTop;
|
||||
}
|
||||
} else {
|
||||
dropdown.classList.remove('show');
|
||||
}
|
||||
});
|
||||
|
||||
// Hide the dropdown when clicking outside
|
||||
document.addEventListener('click', function(event) {
|
||||
var isClickInside = event.target.classList.contains('search-input') || event.target.classList.contains('badge-container') || event.target.closest('.badge-container');
|
||||
if (!isClickInside) {
|
||||
document.getElementById('dropdown-menu').classList.remove('show');
|
||||
}
|
||||
});
|
||||
|
||||
// Handle keyboard navigation
|
||||
document.getElementById('search-inputx').addEventListener('keydown', function(event) {
|
||||
var dropdownMenu = document.getElementById('dropdown-menu');
|
||||
var items = dropdownMenu.querySelectorAll('.dropdown-item');
|
||||
var activeItem = dropdownMenu.querySelector('.active');
|
||||
|
||||
if (event.key === 'ArrowDown') {
|
||||
event.preventDefault(); // Prevent page scroll
|
||||
if (!activeItem) {
|
||||
items[0].classList.add('active');
|
||||
} else {
|
||||
activeItem.classList.remove('active');
|
||||
var next = activeItem.nextElementSibling;
|
||||
if (next) {
|
||||
next.classList.add('active');
|
||||
} else {
|
||||
items[0].classList.add('active');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (event.key === 'ArrowUp') {
|
||||
event.preventDefault(); // Prevent page scroll
|
||||
if (!activeItem) {
|
||||
items[items.length - 1].classList.add('active');
|
||||
} else {
|
||||
activeItem.classList.remove('active');
|
||||
var prev = activeItem.previousElementSibling;
|
||||
if (prev) {
|
||||
prev.classList.add('active');
|
||||
} else {
|
||||
items[items.length - 1].classList.add('active');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (event.key === 'Enter' && activeItem) {
|
||||
selectItem(activeItem);
|
||||
}
|
||||
|
||||
if (activeItem) {
|
||||
dropdownMenu.scrollTop = activeItem.offsetTop - dropdownMenu.offsetTop;
|
||||
}
|
||||
});
|
||||
|
||||
// Set the input value and hide the dropdown when an item is clicked
|
||||
document.body.addEventListener('click', function(event) {
|
||||
if (event.target.classList.contains('dropdown-item')) {
|
||||
selectItem(event.target);
|
||||
}
|
||||
});
|
||||
|
||||
// Show dropdown when input gets focus and has value
|
||||
document.getElementById('search-inputx').addEventListener('focus', function(event) {
|
||||
var input = event.target;
|
||||
var dropdown = document.getElementById('dropdown-menu');
|
||||
if (input.value.length > 0) {
|
||||
dropdown.classList.add('show');
|
||||
}
|
||||
});
|
||||
}`,
|
||||
Call: templ.SafeScript(`__templ_JsCustomAutoComplete_4b2e`),
|
||||
CallInline: templ.SafeScriptInline(`__templ_JsCustomAutoComplete_4b2e`),
|
||||
}
|
||||
}
|
||||
|
||||
func CssXsampleAutoComplete() templ.Component {
|
||||
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
templ_7745c5c3_Buffer = templ.GetBuffer()
|
||||
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var11 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var11 == nil {
|
||||
templ_7745c5c3_Var11 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<link rel=\"stylesheet\" href=\"assets/css/googlefont/poppins.css\"><link rel=\"stylesheet\" href=\"assets/css/googlefont/publicsans.css\"><link rel=\"stylesheet\" href=\"assets/css/googlefont/roboto.css\"><style>\r\n body {\r\n background-color: white;\r\n /* padding-right: 100px;\r\n padding-left: 100px; */\r\n }\r\n .dropdown-menu {\r\n max-height: 200px;\r\n overflow-y: auto;\r\n width: 100%; /* Ensure the dropdown menu width matches the input width */\r\n }\r\n .dropdown-menu.show {\r\n display: block; /* Ensure the dropdown menu is displayed */\r\n }\r\n .spinner-border {\r\n width: 2rem;\r\n height: 2rem;\r\n }\r\n .badge-container {\r\n display: flex;\r\n flex-wrap: wrap;\r\n align-items: center;\r\n margin-top: 10px;\r\n }\r\n .badge-container .badge {\r\n margin: 2px;\r\n }\r\n .badge-container input {\r\n border: none;\r\n outline: none;\r\n flex-grow: 1;\r\n }\r\n .dropdown-item.active {\r\n background-color: #007bff;\r\n color: white;\r\n }\r\n</style>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
func ShowXSampleScreen(title string, cmp templ.Component, css templ.Component, js templ.Component,
|
||||
navbarmenu templ.Component,
|
||||
navbaruser templ.Component,
|
||||
userprofile templ.Component) templ.Component {
|
||||
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
templ_7745c5c3_Buffer = templ.GetBuffer()
|
||||
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var12 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var12 == nil {
|
||||
templ_7745c5c3_Var12 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Var13 := templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
templ_7745c5c3_Buffer = templ.GetBuffer()
|
||||
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
}
|
||||
templ_7745c5c3_Err = cmp.Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
_, templ_7745c5c3_Err = io.Copy(templ_7745c5c3_W, templ_7745c5c3_Buffer)
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
templ_7745c5c3_Err = layout.CorporateLayout(title, css, js, navbarmenu, navbaruser, userprofile).Render(templ.WithChildren(ctx, templ_7745c5c3_Var13), templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user