diff --git a/assets/mcu/htmx4.html b/assets/mcu/htmx4.html
new file mode 100644
index 0000000..b08fc49
--- /dev/null
+++ b/assets/mcu/htmx4.html
@@ -0,0 +1,237 @@
+
+
+
+
+
+ Typeahead Example with HTMX
+
+
+
+
+
+
+
Typeahead Example with HTMX
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/mcu/proses_obj_search.php b/assets/mcu/proses_obj_search.php
new file mode 100644
index 0000000..60a21ed
--- /dev/null
+++ b/assets/mcu/proses_obj_search.php
@@ -0,0 +1,33 @@
+ 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 .= '' . htmlspecialchars($result["name"]) . '';
+}
+
+// Return HTML response
+echo $html;
+?>
diff --git a/handlers/dev/xsampleautocomplete.handlers.go b/handlers/dev/xsampleautocomplete.handlers.go
new file mode 100644
index 0000000..776e687
--- /dev/null
+++ b/handlers/dev/xsampleautocomplete.handlers.go
@@ -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)
+}
diff --git a/handlers/routes.go b/handlers/routes.go
index d1b13b1..1637884 100644
--- a/handlers/routes.go
+++ b/handlers/routes.go
@@ -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)
}
diff --git a/models/xsampleautocomplete.models.go b/models/xsampleautocomplete.models.go
new file mode 100644
index 0000000..616bd45
--- /dev/null
+++ b/models/xsampleautocomplete.models.go
@@ -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"`
+}
diff --git a/services/dev/xsampleautocomplete.services.go b/services/dev/xsampleautocomplete.services.go
new file mode 100644
index 0000000..443cf62
--- /dev/null
+++ b/services/dev/xsampleautocomplete.services.go
@@ -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
+}
diff --git a/views/dev/xsampleautocomplete/xsampleautocomplete.templ b/views/dev/xsampleautocomplete/xsampleautocomplete.templ
new file mode 100644
index 0000000..9e901d7
--- /dev/null
+++ b/views/dev/xsampleautocomplete/xsampleautocomplete.templ
@@ -0,0 +1,280 @@
+package dev_xsampleautocomplete
+
+import (
+ "cpone/layout"
+ "cpone/models"
+ "strconv"
+)
+
+templ EmptyDiv1() {
+
+}
+
+templ Selected(data []models.XsampleT_Test) {
+ if len(data) > 0 {
+ for _, v := range data {
+
+ { v.T_TestCode } - { v.T_TestName }
+ ×
+
+ }
+ }
+}
+
+templ ListData(dataList []models.XsampleT_Test) {
+ if len(dataList) > 0 {
+
+ } else {
+
+ }
+}
+
+templ MainAutoComplete() {
+
+
Typeahead Example with HTMX
+
+
+
+
+ @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() {
+
+
+
+
+}
+
+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
+ }
+}
diff --git a/views/dev/xsampleautocomplete/xsampleautocomplete_templ.go b/views/dev/xsampleautocomplete/xsampleautocomplete_templ.go
new file mode 100644
index 0000000..e659498
--- /dev/null
+++ b/views/dev/xsampleautocomplete/xsampleautocomplete_templ.go
@@ -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("")
+ 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("")
+ 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(" ×")
+ 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("")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ } else {
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("")
+ 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("")
+ 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("")
+ 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
+ })
+}