migliori / universal-icon-picker

Vanilla JS Icon Picker for any Icon Library
https://universal-icon-picker.miglisoft.com
MIT License
79 stars 12 forks source link

Unable to use search when opened in bootstrap modal #26

Closed juniwalk closed 2 months ago

juniwalk commented 2 months ago

When I open icon picker from input that is inside bootstrap modal I am unable to click on search input.

migliori commented 2 months ago

I fixed it. Bootstrap modal doesn't like inputs outside of the opened modal. I've added the “parentElement” option, which lets you define the icon picker's parent element.

To open the icon picker from a Bootstrap modal, add it to the modal-body. This way Bootstrap will no longer block search input.

const options = {
    parentElement: '.modal-body' // or '#your-modal-body-id'
    // ...
}

const  uip = new UniversalIconPicker('#selector', options);
juniwalk commented 2 months ago

Hello, thanks for the quick fix. However now the icon picker won't open at all. I have the modal dynamically loaded as snippet from server and then icon picker setup on it. Before applying parentElement this was not an issue, could it be issue now?

migliori commented 2 months ago

The parentElement must exist when you load the icon picker. If your modal content is loaded dynamically you should then load the icon picker after it.

juniwalk commented 2 months ago

Well yes that does happen ofcourse. Snippet is loaded using Naja.js and then there is afterUpdate event that setups needed calls which also creates icon picker.

This is my icon picker init code:

$('input.icon-picker').each(function() {
    let preview = $(this).parents('.input-group').find('.icon-preview i');
    let target = $(this).attr('id');

    let iconPicker = new UniversalIconPicker('#'+target, {
        iconLibraries: ['font-awesome.min.json'],
        parentElement: '.modal-body',

        // Remove uip-close class on uip-modal after AJAX
        // request and snippet with iconPicker was updated
        onBeforeOpen: function() {
            $('#uip-modal-'+target).removeClass('uip-close');
        },

        onSelect: function(info) {
            $(preview).attr('class', info.iconClass).addClass('fa-fw');
            $('#'+target).val(info.iconClass);
        }
    });

    $(preview).attr('class', $(this).val()).addClass('fa-fw');
});
migliori commented 2 months ago

I'll afraid you'll have to debug your code by yourself. I tested with a non-dynamic Bootstrap modal: clicked the button to open the modal then click the icon picker button inside the modal body, it works fine. You probably should create the icon picker inside the "show.bs.modal" event

juniwalk commented 2 months ago

@migliori Alright, thank you for your help

migliori commented 2 months ago

You're welcome

juniwalk commented 2 months ago

One more question, I checked console for errors and it seems like the parentElement gets lost when opening?

Uncaught (in promise) TypeError: document.querySelector(...) is null

open: function () {
    this._loadIconLibraries().then(() => {
        this.iconLibrariesLoaded = true;
        if (!document.getElementById('uip-modal' + this.idSuffix)) {
            //push universal dom to body
            document.querySelector(this.options.parentElement).appendChild(this.universalDomEle);

I printed options in onBeforeOpen event and parentElement is there.

// EDIT: I see now, querySelector does not find the element and returns null.

juniwalk commented 2 months ago

So I managed to fix the opening, I had multiple modals so using just .modal-body was putting it to hidden modal. However now when I select icon and click insert it redirects somehow.

Yes it is submitting the form looks like. I am guessing it is because <button> is used to insert the icon and now it is inside form tag.