pagination Vue.js using DataTables and make search bar work across pages of table

pagination Vue.js using DataTables and make search bar work across pages of table

DjangoDjango Posts: 1Questions: 1Answers: 0

I have a web app, backend using Django, frontend using Vue.js.

In one HTML page, I have a Vue.js table. As there are 700+ rows in the table, this page loads very slow and the button part buttons could not be shown. So I want to do pagination to this table to show the bottom buttons after initial loading. I have tried datatable using jquery to do pagination, but it does not meet user's requirements. Also seems like jquery datatable go against with Vue.js table and it has to load twice. How could I do the pagination and make search bar work across pages of table using Vue.js version of DataTables?

 <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js" xmlns:v-on="http://www.w3.org/1999/xhtml"
            xmlns:v-on="http://www.w3.org/1999/xhtml"></script>

            <table id="myTable">
                <thead>
                <tr>
                    <th>Title</th>


                    <th>Tag course & Submit</th>
                </tr>
                </thead>
                <tbody>
                <tr v-for="(row, index) in filteredRows" :key="`title-${index}`">
                    <td  v-html="highlightMatches(row.title)">{{ row.title }}</td>

                    <td><button type="button" class="button2" v-on:click="check( $event, row.title)">Tag & Submit</button></td>
                </tr>
                </tbody>
            </table>

<script>
        Vue.prototype.$http = axios;
        var book_rows = [{title: XXX];

        const app = new Vue({
            el: '#app',
            data:() => ({
                filter: '',
                rows: book_rows
            }),

            methods: {
                highlightMatches(text)
                {
                    if (typeof text === 'string' || text instanceof String){
                        text = (text?text:'None');
                        const matchExists = text.toLowerCase().includes(this.filter.toLowerCase());
                        if (!matchExists) return text;
                        const re = new RegExp(this.filter, 'ig');
                        return text.replace(re, matchedText => `<strong>${matchedText}</strong>`);
                    }

                },
                submit : function(){
                    this.$refs.form.submit()
                },

            },
            computed: {
                filteredRows() {
                    return this.rows.filter(row => {
                        const author = String(row.author).toString().toLowerCase();
                        const title = String(row.title).toLowerCase();
                        const searchTerm = this.filter.toLowerCase();
                        return title.includes(searchTerm) ||
                            author.includes(searchTerm);
                    });
                }
            },
        });
 </script>

Answers

  • allanallan Posts: 54,921Questions: 1Answers: 8,611 Site admin

    but it does not meet user's requirements.

    In what way? Are there missing features or something?

    With Vue, you are running into a problem with both Vue and DataTables trying to control the DOM for the table. Rather than using <tr v-for... to create the rows in a template have simply for the HTML table:

    <table id="myTable" v-once>
      <thead> ... </thead>
    </table>
    

    Note the v-once so Vue doesn't attempt to control the DOM once created, and also that I've defined only the table header.

    Then in the mounted lifecycle hood, initialise the DataTable and use the data property to pass in the data. Any changes to the data will not be automatically detected (since DataTables doesn't use Vue bindings), so you might need a watch on the data if you are expecting it to change.

    Allan

Sign In or Register to comment.