New Metronic Docs!Added Integration Docs with Starter Kits Apps for Laravel, Laravel Livewire, Angular, Vue, Symfony, Blazor Server, Django & Flask & more
Browse Docs

Problem using livewire and ktSelect


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));
});
}


but the problem is when I'm opening the modal to edit a pack. I've tried to add the createInstances of the KTSelect on a livewire hook to trigger the reload of the select everytime livewire refresh the component but that doesn't seem to work

document.addEventListener("livewire:initialized", () => {
Livewire.hook("morph.updated", ({el, component}) => {
KTSelect.createInstances()
})
});


On the documentation it doesn't seem to have a component API methods like for the dropdown, are they implemented and working the same ? How can I make that work properly ?


Text formatting options
Submit
Here's a how to add some HTML formatting to your comment:
  • <pre></pre> for JS codes block
  • <pre lang="html"></pre> for HTML code block
  • <pre lang="scss"></pre> for SCSS code block
  • <pre lang="php"></pre> for PHP code block
  • <code></code> for single line of code
  • <strong></strong> to make things bold
  • <em></em> to emphasize
  • <ul><li></li></ul>  to make list
  • <ol><li></li></ol>  to make ordered list
  • <h3></h3> to make headings
  • <a></a> for links
  • <img> to paste in an image
  • <blockquote></blockquote> to quote somebody
  • happy  :)
  • shocked  :|
  • sad  :(

Replies (4)


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>
@endscript


Is this the good approach or am I missing something?



It 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));
});
}
}


My only problem now is to be able to reload KTSelect when livewire update the select value. I've tried to do it on the morph:updated hook with destroying the ktselect instance and recreating it with new KTSelect() but it seems that it does generate a change event and thus being listened by the eventlistener and creating an infinite loop of livewire update.

Is there a method to refresh ktselect without triggering the change event ?


Text formatting options
Submit
Here's a how to add some HTML formatting to your comment:
  • <pre></pre> for JS codes block
  • <pre lang="html"></pre> for HTML code block
  • <pre lang="scss"></pre> for SCSS code block
  • <pre lang="php"></pre> for PHP code block
  • <code></code> for single line of code
  • <strong></strong> to make things bold
  • <em></em> to emphasize
  • <ul><li></li></ul>  to make list
  • <ol><li></li></ol>  to make ordered list
  • <h3></h3> to make headings
  • <a></a> for links
  • <img> to paste in an image
  • <blockquote></blockquote> to quote somebody
  • happy  :)
  • shocked  :|
  • sad  :(
Text formatting options
Submit
Here's a how to add some HTML formatting to your comment:
  • <pre></pre> for JS codes block
  • <pre lang="html"></pre> for HTML code block
  • <pre lang="scss"></pre> for SCSS code block
  • <pre lang="php"></pre> for PHP code block
  • <code></code> for single line of code
  • <strong></strong> to make things bold
  • <em></em> to emphasize
  • <ul><li></li></ul>  to make list
  • <ol><li></li></ol>  to make ordered list
  • <h3></h3> to make headings
  • <a></a> for links
  • <img> to paste in an image
  • <blockquote></blockquote> to quote somebody
  • happy  :)
  • shocked  :|
  • sad  :(