Changing Language Dynamically on Vue 3

Changing Language Dynamically on Vue 3

RaZzLeRaZzLe Posts: 4Questions: 2Answers: 0

vue version: 3.2.13
datatables.net-dt: 2.1.8
datatables.net-vue3: 3.0.2

I want to change table language at the same instance when an end user change the site's language from navbar.

Below is my template:

<template>
    <div class="keyword_table_wrapper">
        <DataTable
            class="display"
            width="100%"
            :columns="keywordColumns"
            :data="keywords"
            :options="datatableOpts"
            ref="table"
        >
            <thead>
                <tr>
                    <th>ID</th>
                    <th>Anahtar Kelime</th>
                    <th>Oluşturma Tarihi</th>
                    <th>Güncelleme Tarihi</th>
                </tr>
            </thead>
        </DataTable>
    </div>
</template>

Pretty much a simple datatable so far.. Below is my script (I'm using Options API):

import { DataTable } from 'datatables.net-vue3';
import DataTablesLib from 'datatables.net';

DataTable.use(DataTablesLib);

export default {
    components: {
        DataTable
    },
    data() {
        return {
            keywordColumns:[
                { data: "id" },
                { data: "text" },
                { data: "createtime" },
                { data: "updatetime" }
            ],
            keywords: [],
            datatableOpts: {
                language: {
                    url: "https://cdn.datatables.net/plug-ins/2.1.8/i18n/tr.json"
                }
            }
        }
    },
    computed: {
        userLanguage() {
            return this.$store.getters.languageId;
        }
    },
    methods: {
        async loadKeywords() {
                //loading table data stuff..
            }
        }
    },
    watch: {
        userLanguage(newVal, oldVal) {
            if (newVal && newVal != oldVal) {
                const dt = this.$refs.table;

                if (newVal == "tr") {
                    this.datatableOpts.language = "https://cdn.datatables.net/plug-ins/2.1.8/i18n/tr.json";
                    dt.dt.draw();
                    dt.dt.init();
                } else if (newVal == "en") {
                    this.datatableOpts.language = "https://cdn.datatables.net/plug-ins/2.1.8/i18n/en-GB.json";
                    dt.dt.draw();
                    dt.dt.init();
                } else if (newVal == "ar") {
                    this.datatableOpts.language = "https://cdn.datatables.net/plug-ins/2.1.8/i18n/ar.json";
                    dt.dt.draw();
                    dt.dt.init();
                } else {
                    this.datatableOpts.language = "https://cdn.datatables.net/plug-ins/2.1.8/i18n/tr.json";
                    dt.dt.draw();
                    dt.dt.init();
                }
            }
        }
    },
    async created() {
        await this.loadKeywords();
    }
}

I can guarantee that my userLanguage computed value is working fine. I'm not sharing its under the hood codes as it will make off-topic content.
When userLanguage watcher triggered datatable lang remains as the same on its initial value. I think I have to re-render the table somehow but couldn't find how from the docs. Those .draw() and .init() funcs don't make any difference.
Anyone has an idea?

Thank you in advance.

This question has an accepted answers - jump to answer

Answers

  • kthorngrenkthorngren Posts: 21,443Questions: 26Answers: 4,974

    Most config options can't be changed dynamically. There aren't any API's to change the language settings. To change these types of settings you will need to destroy and reinitialize Datatables. Try using the destroy option in your Datatable config and reinitialize with the new language settings.

    Kevin

  • chocchoc Posts: 101Questions: 12Answers: 9
    edited October 27

    I think it is somehow possible? I use the below snippet code to change the language.zeroRecords in DT React for example.

    const table = useRef(null);
    
    useEffect(() => {
        const api = table.current?.dt({ visible: true, api: true });
        if (api) {
            if (language === "de") {
                api.settings()[0].oLanguage.sZeroRecords = "Hallo"
            } else {
                api.settings()[0].oLanguage.sZeroRecords = "Hello"
            }
        }
    }, [language]);
    

    I put the snippet in a useEffect that can listen to changes in the settings. In your case, it could be the language setting from the navbar.

  • allanallan Posts: 63,678Questions: 1Answers: 10,498 Site admin

    Yes, using the private configuration object from the settings object is currently the only way to do this. It is worth noting that it is considered private, and while it is unusual for options to change or disappear, it can happen.

    What I have been considering is putting a deep watch on the configuration object that is passed into the Vue component. If anything in it changes, then destroy and reinitalise the table with the new option. That would make to fully dynamic, Vue style.

    Allan

  • RaZzLeRaZzLe Posts: 4Questions: 2Answers: 0

    Thank you all for your comments guys. I knew I need to re-render my data table. I was misusing .draw() and .init() funcs at that moment as you can see from my question post.

    But, in the end I end up with using key attribute to re-render my data table. As you know Vue re-compiles any component when its key changes. So, I define a key to my datatable as below:

            <DataTable 
                class="display" 
                width="100%" 
                :columns="keywordColumns" 
                :data="keywords" 
                :options="datatableOpts"
                :key="keywordTableId"
            >
    

    This is the initial key value:

    data() {
            return {
                keywordTableId: "keywordTable", //here it is
                keywordColumns: [
                    { data: "id" },
                    { data: "text" },
                    { data: "createtime" },
                    { data: "updatetime" }
                ],
                keywords: [],
                datatableOpts: {
                    language: {
                        url: ""
                    }
                }
            }
        },
    

    Finally, I change this key inside my watch method's if...else blocks like this:

    if (newVal == "tr") {
        this.keywordTableId = "keywordTableTr";
        this.datatableOpts.language.url = "https://cdn.datatables.net/plug-ins/2.1.8/i18n/tr.json";
    } else if (newVal == "en") {
        this.keywordTableId = "keywordTableEn";
        this.datatableOpts.language.url = "https://cdn.datatables.net/plug-ins/2.1.8/i18n/en-GB.json";
    }
    
  • allanallan Posts: 63,678Questions: 1Answers: 10,498 Site admin
    Answer ✓

    Nice one - thanks for posting back with your solution.

    Allan

Sign In or Register to comment.