MaterialSelect Destroy


Topic: MaterialSelect Destroy

Thomas Emmanuel asked 6 years ago

Expected behavior$('#id').materialSelect('destroy') should destroy the select.

Actual behavior$('#id').materialSelect('destroy') is not destroying the select -> worked in earlier version

$('#id').materialSelect({destroy:true}) - works in new version.

I have written a lot of code using $('#id').materialSelect('destroy') , now that i have updated to 4.7.7 all my pages have a problem with select.

Need a quick work around.

Regards Prashanth

Resources (screenshots, code snippets etc.)


Kneidels pro commented 6 years ago

same here. Quite a pain!

there really needs to be better documentation on upgrades like this, and backwards compatibility for a few versions. is this materialSelect a new item from 4.7.7 or 4.8.0 from yesterday?


Legay commented 6 years ago

This component suite is a joke. Just look at their own source code in material-select.js. You'll find references to $('#id').materialSelect('destroy') in a few places, which breaks rendering. I've been working on implementing this component in our app for the past few days and have found multiple bugs already. Fixing this issue, the negative z-index problem, and rendering labels properly took maybe 10 lines of code, I submitted the snippets, and here we are, v4.8 - same bugs.

And don't get me started on performance - shameful.


Bartłomiej Malanowski staff pro premium commented 6 years ago

Thank you for your opinions. I agree we should work on our Material Select component. We'll take care of it so it should be getting better


gianlucagiacometti pro premium priority answered 6 years ago

jQuery.fn.extend({
    destroyMaterialSelect: function() {
        return this.each(function() {
            let wrapper = $(this).parent();
            let core = wrapper.find('select');
            wrapper.after(core.removeClass('initialized').prop('outerHTML'));
            wrapper.remove();
        });
    }
});

usage:

$('SELECTOR').destroyMaterialSelect();

Enjoy!


Hi, Is this issue fixed on 4.8.0?


Bartłomiej Malanowski staff pro premium commented 6 years ago

@Legay confirmed that the issue wasn't fixed in 4.8.0


Thomas Emmanuel commented 6 years ago

@Bartłomiej Malanowski is it fixed in 4.8.1?


Bartłomiej Malanowski staff pro premium commented 6 years ago

It's still on our TODO list


Andrew Ford pro premium priority answered 5 years ago

I just added v4.11.0, and "destroy" doesn't work 100% of the time. Including what @gianlucagiacometti posted 7 months ago, doesn't always work.

I am working with cascading selects "country - state - city". In the country list I select "United States"... and it shows all 50 states, plus other US territories, then I switch to "Vatican" (a "City-State") -- which shows that the "destroy" method is successful, but I switch to a different county ---- ok, I have no idea how to explain it from this point. But eventually there is a bit of a retrieve lag of sorts... well while I was typing this, I had a crazy idea of doing the following - which actually works, no lag in data retrieval.

$('.mdb-select').materialSelect();
$('#country').on('change', function () {
  $.ajax({
    // boring ajax stuff
  }).done(function (data, textStatus, jqXHR) {
    $('#adminarea1').materialSelect({
      destroy: true
    });
    $('#adminarea1').materialSelect();
    $('#adminarea1').html(data);

    // crazy idea that works below this line
    $('#adminarea1').materialSelect({
      destroy: true
    });
    $('#adminarea1').materialSelect();
    $('#adminarea1').html(data);
  });
});

I should also ask, can anyone else confirm this same behavior with "Cascading Dropdowns" with PHP and a database? Or just me?

Thanks.


Mateusz Łubianka staff commented 5 years ago

@Andrew Ford,

Does it work now?

Best,


Sanches answered 5 years ago

Add attribute <select class="mdb-select ... " data-stop-refresh="true">...</select> in your select as follows for browser not to freeze while populating select with options via ajax;

Before populating select destroy material select! I've noticed that mdb pro has a bug in initialization or wrong documentation. Due to the fact that after initialization of select (calling the method $('.mdb-select') materialSelect()) mdb.js generates parent <div class="select-wrapper mdb-select" ...>...</div> while cloning classes from select class. That means that when you call $('.mdb-select').materialSelect({destroy: true}) it removes select parent .e.g. .select-wrapper and parent of .select-wrapper outer html which breaks layout as you noticed =);

For that reason just call destroy as follows $('select.mdb-select').materialSelect({destroy: true}) WORKS FINE =);

Call your ajax to pupulate your select and reinitialize it $('select.mdb-select').materialSelect().


Grzegorz Bujański staff commented 5 years ago

Hi. Which MDB version are you using?


sessionbase pro answered 5 years ago

Hi!

I update my MDBootstrap 4.12.0 to 4.16.0 and the materialselect destroy isn't working.

The destroy code in 4.12.0:
this.view.$nativeSelect.unwrap();

The destroy code in 4.16.0:
if( this.view.$nativeSelect.hasClass('select-wrapper')) {
this.view.$nativeSelect.find('select').unwrap();
}

The bug in the source:

enter image description here

Thanks!


Grzegorz Bujański staff commented 5 years ago

Hi. We have this bug in our todo list. We will fix it.


sessionbase pro commented 5 years ago

Thank you very much!


Pablo answered 5 years ago

Seriously. One year for this? It's just adding a ".parent()".

For those who are still waiting for this issue to be fixed, this is my code:

import MaterialSelectViewRenderer from "mdbootstrap-pro/src/js/pro/material-select/material-select-view-renderer";

// Fix issue with material select destroy
MaterialSelectViewRenderer.prototype.destroy = function ()
{
    const currentUuid = this.view.$nativeSelect.data( 'select-id' );

    this.view.$nativeSelect.data( 'select-id' , null ).removeClass( 'initialized' );
    const parent = this.view.$nativeSelect.parent();
    parent.find( 'span.caret' ).remove();
    parent.find( 'input' ).remove();

    if ( parent.hasClass( 'select-wrapper' ) )
    {
        parent.find( 'select' ).unwrap();
    }

    $( `ul#select-options-${ currentUuid }` ).remove();
};

If you're not using Webpack, you should import the MaterialSelectViewRenderer class in your own way. Once imported (required, whatever, ...), override the destroy prototype with this code.

If you're using Webpack and Laravel Mix, I've published here how to import MDB with Webpack and Laravel Mix.


Grzegorz Bujański staff commented 5 years ago

Hi. Thanks for your code. I see a small change. We will test it and fix it as soon as possible.


paul.holbrook pro commented 5 years ago

Hi, could you give an indication of timescale for release of this fix please?


Grzegorz Bujański staff commented 5 years ago

Unfortunately not. We will fix it as soon as we can. I don't promise, but maybe we'll have time to do it in this release.


Please insert min. 20 characters.

FREE CONSULTATION

Hire our experts to build a dedicated project. We'll analyze your business requirements, for free.

Status

Answered

Specification of the issue
  • User: Free
  • Premium support: No
  • Technology: MDB jQuery
  • MDB Version: 4.7.7
  • Device: Lenovo, Mac
  • Browser: Chrome, Firefox
  • OS: Windows
  • Provided sample code: No
  • Provided link: No