sfarzoso
sfarzoso

Reputation: 1600

Cannot change DataTable header

I'm trying to use the same DataTable structure for multiple purpose, for do this I have a select which is used as a filter:

<select id="filter">
    <option value="contacts">Contacts</option>
    <option value="apps" selected>Apps</option>
</select>

when a filter is chosed I actually initialize the DataTable as follow:

$('#filter').on('change', function(){

    let tableOpts = [{
       data: 'name';
    }];

    let tr = $('my-dataTable thead').empty();
    let cols = '<th>Name</th>';

    if($(this).val() == 'contacts'){
        cols += '<th>color</th>';
        tr.append(cols);

        tableOpts.push({
             data: 'color'
        });
    }

    tr.append(cols);
    $('#my-dataTable thead').append(tr);

    $('#my-dataTable').DataTable({
        columns: tableOpts,
        destroy: true,
    });
});

the DataTable is actually initialized with 2 columns, because the initial selected value in the filter is apps, when I chose contacts I get:

TypeError: Cannot read property 'style' of undefined

this usually means that I didn't added all the th in the DataTable header but this is weird 'cause I did.

Also, if I set as initial value contacts and switch to apps all works well.

This issue only happen when I have as initial value apps.

What I did wrong?

Upvotes: 0

Views: 239

Answers (2)

dganenco
dganenco

Reputation: 1616

You can map your object like so:

const objWithoutColor = [{name:'John'}, {name:'Sam'}];
const mappedObj = objWithoutColor.map((obj)=>({...obj,['color']:"color"}));

console.log(mappedObj);

Upvotes: 1

dganenco
dganenco

Reputation: 1616

That's because of multiple initialization of the same datatable. First of all, it's definitely a bad idea to initialize dataTable on each filter change. I'd suggest you to initialize it on DOM ready event and hide it if needed. Also, you should initialize it with 2 columns, and then handle filter change and hide particular column based on your condition using built-in method.

I've prepared a sample fiddle for you.

const table = $('#my-dataTable').DataTable({
  columns: [{
    data: 'name'
  }, {
    data: 'color'
  }],
  destroy: true,
});

$('#my-dataTable_wrapper').hide();

$('#filter').on('change', function() {
  table.column(1).visible($(this).val().toLowerCase().trim() === 'contacts');
  $('#my-dataTable_wrapper').show();
});


<select id="filter">
  <option value="contacts">Contacts</option>
  <option value="apps" selected>Apps</option>
</select>

<table id='my-dataTable'>
  <thead>
    <th>Name</th>
    <th>Color</th>
  </thead>
</table>

Upvotes: 1

Related Questions