Hi Keen team,
I've come across a problem while using livewire with ktui.
I've got a form inside a modal. I'm using wire:ignore.self on the modal div to let ktui work on the opening and closing of the modal.
Inside I've a form with different inputs using wire:model to synchronise it with a livewire form handling validation.
For the select I've tried many options and none are working properly. I've put a wire:ignore on the div surronding the label and select, i've put the kt-select class and the data-kt-select attribute.
this select also triggers the change on the rest of the form depending on its value. I've used this script on the modal to make it work using the change event of ktselect
const selectElement = document.getElementById("pack");
if (selectElement) {
selectElement.addEventListener("change", (event) => {
const { value } = event.detail.payload;
$wire.$set("form.pack", parseInt(value));
});
}document.addEventListener("livewire:initialized", () => {
Livewire.hook("morph.updated", ({el, component}) => {
KTSelect.createInstances()
})
});DELIMa 2.0 is an upgraded digital learning platform introduced by the Ministry of Education Malaysia to support students, teachers, and parents
with interactive and data-driven educational resources. It focuses on personalized learning, improved user experience, and smart analytics tools,
helping make teaching and learning more flexible, engaging, and effective in the modern education system.
As there is not much documented on the KTSelect methods, I've found a workaround by completely removing the select and recreating it entirely.
I don't know if that's the good way and hopefully methods on KTSelect could help doing that with less code but here is my implementation:
<div class="flex flex-col gap-1.5" wire:ignore>
<label class="kt-label">
Pack Premium
</label>
<select
class="kt-select kt-select-lg
>
<option value="0" selected>No</option>
<option value="1">Yes</option>
</select>
</div>
@script
<script>
document.addEventListener("livewire:initialized", () => {
let selectElement = document.getElementById("pack_premium");
let ktSelectInstance = null;
function initializeKTSelect() {
const currentValue = String($wire.form.pack_premium);
if (ktSelectInstance) {
if (ktSelectInstance.dispose) {
ktSelectInstance.dispose();
}
ktSelectInstance = null;
}
const parent = selectElement.parentElement;
const newSelect = document.createElement("select");
newSelect.id = "pack_premium";
newSelect.className = "kt-select kt-select-lg";
const option0 = document.createElement("option");
option0.value = "0";
option0.textContent = "No";
const option1 = document.createElement("option");
option1.value = "1";
option1.textContent = "Yes";
if (currentValue === "0") {
option0.setAttribute("selected", "selected");
option0.selected = true;
} else {
option1.setAttribute("selected", "selected");
option1.selected = true;
}
newSelect.appendChild(option0);
newSelect.appendChild(option1);
newSelect.value = currentValue;
parent.replaceChild(newSelect, selectElement);
selectElement = newSelect;
ktSelectInstance = new KTSelect(selectElement);
let isManualChange = false;
selectElement.addEventListener("change", (e) => {
if (!isManualChange) {
$wire.$set("form.pack_premium", parseInt(e.target.value));
}
});
}
const add_pack_modal = KTModal.getInstance(document.querySelector("#add_pack_modal"));
add_pack_modal.on("hide", (detail) => {
$wire.$dispatch("reset-form");
});
$wire.$on("open-pack-create-modal", () => {
$wire.$set("form.pack_premium", 0);
initializeKTSelect();
});
$wire.$on("pack-form-loaded", () => {
initializeKTSelect();
});
$wire.$on("pack-updated-success", (event) => {
KTToast.show({ message: "Pack updated", variant: "success" })
add_pack_modal.hide();
})
$wire.$on("pack-created-success", (event) => {
KTToast.show({ message: "Pack created", variant: "success" })
add_pack_modal.hide();
})
});
</script>
@endscriptIt sounds like you’re running into a common issue when integrating Livewire with `ktSelect`—usually it comes down to the fact that `ktSelect` (or any JS-based select component) initializes on page load, but Livewire can re-render DOM elements, causing the select to lose its event listeners or selected state. One way to handle this is to use Livewire’s `wire:ignore` on the select element and then re-initialize `ktSelect` in a Livewire hook like `Livewire.hook('message.processed', ...)`. I’ve found that approach keeps the component functional even after updates. Do you also use dynamic content or live streams on your project, like embedding Photocall TV online links, that might complicate the Livewire re-renders?
I indeed had an interference with a wire:key which provokes a rerendering even though I had wire:ignore on the div surrounding the select.
I've made the condition on the form work with hooking to the livewire:initialized event (livewire:init doesn't seem to work)
document.addEventListener("livewire:initialized", () => {
const selectElement = document.getElementById("pack_sans_stand");
if (selectElement) {
selectElement.addEventListener("change", (event) => {
const {value} = event.detail.payload;
$wire.$set("form.pack_sans_stand", parseInt(value));
});
}
}