PrimeVue: Edit DataTable Cell using CDN option

1 day ago 3
ARTICLE AD BOX

Here's the list of fixes made to your original code to make it working:


Fix 1 — Moved the script to the bottom of <body> and removed type="module" and defer

The script was in <head> with type="module", which caused timing and scoping issues with the UMD globals (PrimeVue, PrimeUIX) loaded via CDN. Placing the script at the bottom of <body> guarantees the CDN libraries and the DOM are already available when the app initialises.

Reference: https://developer.mozilla.org/en-US/docs/Learn/JavaScript/First_steps/What_is_JavaScript#script_loading_strategies


Fix 2 — Fixed the :pt structure (table was nested inside column)

table and column are sibling keys in the passthrough object, not parent/child. Having table inside column meant the min-width style was silently ignored.

Reference: https://primevue.org/datatable/#pt.props.table


Fix 3 — Used edit-mode instead of editMode

In a plain HTML file, the browser lowercases all attribute names before Vue sees them, so editMode becomes editmode and Vue doesn't recognise it as the correct prop. Kebab-case (edit-mode) survives the browser's lowercasing. This was the main reason cell editing wasn't working.

Reference: https://vuejs.org/guide/essentials/component-basics#in-dom-template-parsing-caveats


Fix 4 — The bare <template> wrapper

Vue treats a <template> with no directive as transparent and renders through it correctly. It's pointless but harmless.


Fix 5 — Added phases bogus object in place of empty array

Since we needed a populated table, I added a populated array as the value of phases and commented this.fetchData() in mounted()


This is the fixed demo:

<html> <head> <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script> <script src="https://unpkg.com/primevue/umd/primevue.min.js"></script> <script src="https://unpkg.com/@primeuix/themes/umd/aura.js"></script> </head> <body> <div id="app"> <h1>Phase List</h1> <p-datatable :value="phases" edit-mode="cell" @cell-edit-complete="onCellEditComplete" :pt="{ table: { style: 'min-width: 50rem' }, column: { bodycell: ({ state }) => ({ class: [{ '!py-0': state['d_editing'] }] }) } }" > <p-column v-for="col of columns" :key="col.field" :field="col.field" :header="col.header" style="width: 25%"> <template #body="{ data, field }"> [[ data[field] ]] </template> <template #editor="{ data, field }"> <p-inputtext v-model="data[field]" autofocus fluid /> </template> </p-column> </p-datatable> <input type="button" value="Refresh" @click="fetchData()" /> </div> <script defer> const { createApp, ref } = Vue; const app = createApp({ data() { const date = ref(); return { columns:[ { field:"id", header:"Code" }, { field:"name", header:"Name"}, ], phases: [ { id: 1, name: 'Phase One' }, { id: 2, name: 'Phase Two' }, { id: 3, name: 'Phase Three' }, ], } }, delimiters: ['[[',']]'], methods: { onCellEditComplete(e) { }, async fetchData() { this.phases = [] try { const res = await fetch(`/phases`) if (res.ok) this.phases = await res.json() } catch(error) { console.error("There was an error!", error); } }, renderData() { } }, mounted() { //this.fetchData(); }, watch: { phases() { for(var i = 0; i < this.phases.length; i++) { this.phases[i]["url"] = "/phases/" + this.phases[i].id } this.renderData() } } }) app.use( PrimeVue.Config, { theme: { preset: PrimeUIX.Themes.Aura } }); app.component('p-column', PrimeVue.Column); app.component('p-inputtext', PrimeVue.InputText); app.component('p-datatable', PrimeVue.DataTable); app.mount('#app'); </script> </body> </html>
Read Entire Article