Add 'tags' to event model. Add a dataimport system - currently for MaxMind zip files
This commit is contained in:
145
app/javascript/controllers/country_selector_controller.js
Normal file
145
app/javascript/controllers/country_selector_controller.js
Normal file
@@ -0,0 +1,145 @@
|
||||
import { Controller } from "@hotwired/stimulus"
|
||||
|
||||
export default class extends Controller {
|
||||
static targets = [ "select" ]
|
||||
static values = {
|
||||
options: Array,
|
||||
placeholder: String
|
||||
}
|
||||
|
||||
connect() {
|
||||
// Check if the element is visible, if not, wait for it to become visible
|
||||
if (this.isHidden()) {
|
||||
// Element is hidden, set up a MutationObserver to watch for visibility changes
|
||||
this.observer = new MutationObserver(() => {
|
||||
if (!this.isHidden()) {
|
||||
this.initializeTomSelect()
|
||||
this.observer.disconnect()
|
||||
}
|
||||
})
|
||||
|
||||
this.observer.observe(this.element, {
|
||||
attributes: true,
|
||||
attributeFilter: ['class']
|
||||
})
|
||||
|
||||
// Also check periodically as a fallback
|
||||
this.checkInterval = setInterval(() => {
|
||||
if (!this.isHidden()) {
|
||||
this.initializeTomSelect()
|
||||
this.cleanup()
|
||||
}
|
||||
}, 500)
|
||||
} else {
|
||||
// Element is already visible, initialize immediately
|
||||
this.initializeTomSelect()
|
||||
}
|
||||
}
|
||||
|
||||
isHidden() {
|
||||
return this.element.offsetParent === null || this.element.classList.contains('hidden')
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
if (this.observer) {
|
||||
this.observer.disconnect()
|
||||
this.observer = null
|
||||
}
|
||||
if (this.checkInterval) {
|
||||
clearInterval(this.checkInterval)
|
||||
this.checkInterval = null
|
||||
}
|
||||
}
|
||||
|
||||
initializeTomSelect() {
|
||||
if (!this.hasSelectTarget) {
|
||||
console.log('No select target found')
|
||||
return
|
||||
}
|
||||
|
||||
// Check if Tom Select is available
|
||||
if (typeof TomSelect === 'undefined') {
|
||||
console.log('Tom Select is not loaded')
|
||||
return
|
||||
}
|
||||
|
||||
// If TomSelect is already initialized, destroy it first
|
||||
if (this.tomSelect) {
|
||||
this.tomSelect.destroy()
|
||||
}
|
||||
|
||||
console.log('Initializing Tom Select with options:', this.optionsValue.length, 'countries')
|
||||
console.log('First few country options:', this.optionsValue.slice(0, 3))
|
||||
|
||||
// Prepare options for Tom Select
|
||||
const options = this.optionsValue.map(([display, value]) => ({
|
||||
value: value,
|
||||
text: display,
|
||||
// Add searchable fields for better search
|
||||
search: display + ' ' + value
|
||||
}))
|
||||
|
||||
// Get currently selected values from the hidden select
|
||||
const selectedValues = Array.from(this.selectTarget.selectedOptions).map(option => option.value)
|
||||
|
||||
try {
|
||||
// Initialize Tom Select
|
||||
this.tomSelect = new TomSelect(this.selectTarget, {
|
||||
options: options,
|
||||
items: selectedValues,
|
||||
plugins: ['remove_button'],
|
||||
maxItems: null,
|
||||
maxOptions: 1000,
|
||||
create: false,
|
||||
placeholder: this.placeholderValue || "Search and select countries...",
|
||||
searchField: ['text', 'search'],
|
||||
searchConjunction: 'or',
|
||||
onItemAdd: function() {
|
||||
// Clear the search input after selecting an item
|
||||
this.setTextboxValue('');
|
||||
this.refreshOptions();
|
||||
},
|
||||
render: {
|
||||
option: function(data, escape) {
|
||||
return `<div class="flex items-center p-2">
|
||||
<span>${escape(data.text)}</span>
|
||||
</div>`
|
||||
},
|
||||
item: function(data, escape) {
|
||||
return `<div class="flex items-center text-sm">
|
||||
<span>${escape(data.text)}</span>
|
||||
</div>`
|
||||
}
|
||||
},
|
||||
dropdownParent: 'body',
|
||||
copyClassesToDropdown: false
|
||||
})
|
||||
|
||||
console.log('Tom Select successfully initialized for country selector')
|
||||
|
||||
// Make sure the wrapper is visible
|
||||
setTimeout(() => {
|
||||
if (this.tomSelect && this.tomSelect.wrapper) {
|
||||
this.tomSelect.wrapper.style.visibility = 'visible'
|
||||
this.tomSelect.wrapper.style.display = 'block'
|
||||
console.log('Tom Select wrapper made visible')
|
||||
}
|
||||
}, 100)
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error initializing Tom Select:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// Public method to reinitialize if needed
|
||||
reinitialize() {
|
||||
this.initializeTomSelect()
|
||||
}
|
||||
|
||||
disconnect() {
|
||||
this.cleanup()
|
||||
if (this.tomSelect) {
|
||||
this.tomSelect.destroy()
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user