Holt59 / datatable

Javascript Plugin for data tables creation
http://holt59.github.io/datatable/
MIT License
108 stars 42 forks source link

Inject data to table row #29

Closed Sch-Tim closed 6 years ago

Sch-Tim commented 6 years ago

Hello, I want to use datatable.js for a table in which every row has a data- element. When I use datatable they get removed and replaced by the data-id element. How can I rescue them and let datatable inject them in the newly created table?

Holt59 commented 6 years ago

Unfortunately, there are currently no automatic ways to "rescue" the attributes of the rows and cells of the original table, but if you save them manually prior to the creation of the datatable, you can use the lineFormat option to inject whatever you want on the row after, e.g.:

var dt = new DataTable(myTable, {
    lineFormat: function (id, data) {
        var res = document.createElement('tr');
        res.dataset.id = id;
        for (var key in data) {
            if (data.hasOwnProperty(key)) {
                res.innerHTML += '<td>' + data[key] + '</td>';
            }
        }
        // You can set the dataset attribute here if you want:
        tr.dataset.whatever = 'hello world!';
        // Or maybe:
        tr.dataset.oldAttribute = oldAttributeSave[id];
        return res;
    }
});

If you are using jQuery, you can return a jQuery object instead:

myTable.datatable({
    lineFormat: function (id, data) {
        var res = $('<tr></tr>');
        res.data('id', id);
        for (var key in data) {
            if (data.hasOwnProperty(key)) {
                res.append('<td>' + data[key] + '</td>');
            }
        }
        // You can set the dataset attribute here if you want:
        res.data('whatever', 'hello world!');
        return res;
    }
});

Of course, you can customize the <td> elements if you want.

Sch-Tim commented 6 years ago

Thanks for your answer! Unfortunately I still can't solve my problem. Maybe I don't understand it right.

This is how my original table row looks like (before I use(d) datatable:

<tr class="clickable" data-exercise="{{ $exercise }}">  
                <td>  
                    {{ $exercise->display_name }}  
                </td>  
                <td>  
                    {{ $exercise->firstCategory->display_name }}  
                </td>  
                <td>  
                    {{ $exercise->secondCategory->display_name }}  
               </td>  
           </tr>  

I need to access (and save/rescue) the data-exercise attribute. Could you give me a hint how to achieve this?

Thank you!

Holt59 commented 6 years ago

I think the easiest way here is to send the data as json and let datatable do the display. I don't know which template renderer you are using, but in pure PHP you could do something like:

var allExercices = <?php echo json_encode($exercices); ?>

Assuming $exercices contains the list of $exercice, and then with datatable:

var datatable = new DataTable(myTable, {
    data: allExercices,
    lineFormat: function (id, data) {
        var res = document.createElement('tr');
        res.classList.add('clickable');
        res.dataset.id = id;
        res.innerHTML += '<td>' + exercice.display_name + </td>;
        res.innerHTML += '<td>' + exercice.firstCategory.display_name + </td>;
        res.innerHTML += '<td>' + exercice.secondCategory.display_name + </td>;
        return res;
    }
});

And then you can retrieve the whole exercise when you need it, e.g.:

datatable.select(exerciceId);

You can also add the click listener inside the lineFormat function so that you directly have access to the exercice:

// Inside lineFormat
res.addEventListener('click', function () {
     // Do whatever you want with data...
});
Sch-Tim commented 6 years ago

Thank you so much! That solved my problem almost. One last thing. I noticed that my filters don't work anymore. The select filter shows 'undefined' and when I enter text in a text filter it shows an empty result although there would be at least one entry that fits.

I couldn't find an answer in the docs so could you help me (hopefully) a last time?

That's how I did it until now:

$('#availableExercises').datatable({
        pageSize: 12,
        sort: [true, true, true],
        filters: [true, true, false],
        filterText: 'Suchen...',
        data: phpVars.availableExercises,
        lineFormat: function (id, data) {
            var res = $('<tr></tr>');
            res.addClass('clickable');
            res.append('<td>' + data.display_name + '</td>');
            res.append('<td>' + data.first_category.display_name + '</td>');
            res.append('<td>' + data.second_category.display_name + '</td>');
            res.click(function () {
                addExerciseModal.data('exercise', data);
                addExerciseModal.trigger('initAddModal');
                addExerciseModal.modal("show");
            });
            return res;
        }
    });

I found the lambda Filters I think that's it. I will try and give feedback. Thank you!