Search code examples
jqueryajaxtwigbootstrap-table

Appending Data w/ Bootstrap-table plugin


On page load, Symfony/Twig take care of providing/rendering the data initially shown in the table which bootstrap-table is applied on.

Users can click to get more records at which point I do:

$table = $("#reviewTable");
$table.bootstrapTable('append', data);

In this case data is structured as it is in this example: https://github.com/wenzhixin/bootstrap-table-examples/blob/master/methods/append.html BUT I am returning HTML for many of the cells. This sort of works but I lose the table-related styling on the appended rows. Things aren't centered or spaced correctly because that styling is done at the cell level.

I would prefer to use the AJAX capability that bootstrap-table has built in however I don't want to lose the power that Twig provides since I am using Symfony2 behind the scenes.

Any thoughts from those who have used this (or similar) plugins?


Solution

  • I ended up replacing the Twig template and server-side HTML generation with a JS solution. Here is what my final code ended up like.

    HTML:

     <table class="table table-striped" id="tblReviewDetails"
                           data-toggle="table" data-pagination="true"
                           data-ajax="getReviewData" data-side-pagination="server" data-page-list="[10, 25, 50, 100, 250]">
                        <thead>
                            <tr>
                                <th class="centerCell" data-field="type" data-sortable="true">Site</th>
                                <th class="centerCell" data-field="rating" id="headRating" data-sortable="true" data-width="100px">Rating</th>
                                <th data-field="content" data-width="50%">Review Content</th>
                                <th data-field="time" data-sortable="true">Date</th>
                                <th class="centerCell" data-field="author" data-sortable="true">Name</th>
                                <th data-field="url">Direct Link</th>
                            </tr>
                        </thead>
                    </table>
    

    JS:

    function getReviewData(params, offset) {
    
        $.post("/extended-review-monitor/reviews", {"limit": 10, "offset": offset})
            .done(function (data) {
                console.dir(data);
    
                processedData = transformData(data.data);
    
                console.log("processed data");
                console.dir(processedData);
    
                setTimeout(function() {
                    params.success({
                        total: data.data[0].total,
                        rows: processedData
                    });
    
                }, 1000);
    
            })
            .fail(function () {
                console.log("ajax error");
            });
    
        console.log("ajax complete");
    }
    
    function transformData(data) {
    
        var transformedArray = [];
    
        for(var i = 0; i < data.length; i++) {
            var obj = {
                id : data[i].id,
                type : getTemplate('type', data[i].type),
                author : data[i].author,
                time : data[i].time,
                rating : getTemplate('rating', data[i].rating),
                content : getTemplate('content', data[i].content),
                url : getTemplate('url', data[i].url)
            };
    
            console.log("In loop: " + i);
            console.dir(obj);
    
            transformedArray.push(obj);
        }
    
        return transformedArray;
    }
    
    function getTemplate(key, value) {
    
        var html = '';
    
        switch (key) {
            case "type" :
                html = '<img src="/images/social-icons/' + value + '.png" style="height:32px;" title="' + value + '"/>';
                break;
            case "rating" :
                html = getRatingHTML(value);
                break;
            case "content" :
                html = getContentHTML(value);
                break;
            case "url" :
                html = '<a class="viewButton" href="' + value + '" target="_blank">View</a>';
                break;
        }
    
        return html;
    }
    
    function getContentHTML(value) {
    
        var html = '<div',
            indicator = '';
    
        if (value.length > 275) {
            html += ' class="block-with-text"';
            indicator += '<div class="over-flow-indicator">[Read more]</div>';
        }
    
        html += '>' + value + '</div>' + indicator;
    
        return html;
    }
    
    function getRatingHTML(value) {
        var html = '<div class="starContainer" style="min-width: 72px">';
    
        for (var i = 1; i <= 5; i++) {
            html += '<span class="gfsStar ';
            if (i <= value) {
                html += 'on';
            }
    
            html += '"></span>';
        }
    
        html += "</div>";
        html += '<div class="ratingBadge">' + value + ' / 5</div>';
    
        return html;
    }
    

    This approach works great and the styling + event handlers are all preserved.