Elment Plus + Vue3 js table with dynamic table columns , input box inside the table - dynamic

the actual display of the table
Got problems with data-binding under such circumstance. Input boxes from the whole row seems to be recognizede as one.
<h2>Vue3 + Element plus Dyanamic table</h2>
<el-table :data="tableData" style="width: 100%">
<el-table-column
:prop="index"
:label="item"
v-for="(item, index) in tableHeader"
:key="index"
>
<template v-slot="scope">
<el-input :name="item" v-model="scope.row.index"></el-input>
</template>
</el-table-column>
</el-table>
data() {
return {
tableHeader: {
1: "Name",
2: "Birthday",
3: "Address",
4: "Age",
5: "Tel",
},
tableData: [{
1:'',
2:'',
3:'',
4:'',
5:'',
}, {
1:'',
2:'',
3:'',
4:'',
5:'',
}]
I'm trying to load the table header(namely the number of the columns and each column's name) from back-end data. Input boxes is the main feature in this table. And i want to store the data fram input boxes into tableData and then send it back to back-end.How could i fix this?

Here is an example of a very basic Element+ Table from the Docs.
The way you are trying to bind props to index does not make sense to me.
<template>
<el-table :data="tableData" stripe style="width: 100%">
<el-table-column prop="date" label="Date" width="180" />
<el-table-column prop="name" label="Name" width="180" />
<el-table-column prop="address" label="Address" />
</el-table>
</template>
<script lang="ts" setup>
const tableData = [
{
date: '2016-05-03',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-02',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-04',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-01',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
]
</script>

Related

How to change style in specific row in Element UI Table

I'm using Element UI for my web app.
In my app, there is a table component, that is made by el-table component provided by Element UI.
And I would like to change style for the only specific row.
Firstly, please take a look at the screenshot and my code, later, I will explain what I would like to do specifically with them.
These are the screenshot of table in my app and my code.
<template>
<el-table
:data="tableData"
height="250"
style="width: 100%">
<el-table-column
prop="date"
label="Date"
width="180">
</el-table-column>
<el-table-column
prop="name"
label="Name"
width="180">
</el-table-column>
<el-table-column
prop="address"
label="Address">
</el-table-column>
</el-table>
</template>
<script>
export default {
data() {
return {
tableData: [{
date: '2016-05-03',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles'
}, {
date: '2016-05-02',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles'
}, {
date: '2016-05-04',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles'
}, {
date: '2016-05-01',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles'
}, {
date: '2016-05-08',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles'
}, {
date: '2016-05-06',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles'
}, {
date: '2016-05-07',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles'
}],
}
}
}
</script>
I would like to change background color blue for the row that's Data is 2016-05-03 and 2016-05-04 in the case above.
You should have a look at this https://element.eleme.io/#/en-US/component/table#table-with-status. based on the property row-class-name you can apply some logic to add an class to the row.
<el-table
:data="tableData"
style="width: 100%"
:row-class-name="tableRowClassName">
JS
methods: {
tableRowClassName({row, rowIndex}) {
if (row.date >= new Date()) {
return 'warning-row';
} else if (rowIndex === 3) {
return 'success-row';
}
return '';
}
},
Of course you've to customize this to your needs
Add this code on the component stylesheet
.el-table tr:nth-child(odd) {
background-color: #845353;
}
Additionally +
If you are using the new version of Element-UI and row-style instead of header-row-class-name, you must not use like return: 'background: red'. You have to return Object.
ex: return: {'background': 'red'}

Double footer on vue-boostrap table component

I would like to implement a double footer for a bootstrap-vue table.
<b-table
striped hover
:items="items"
:fields="visibleFields"
:sort-compare="sortCompare"
:sort-by.sync="sortBy"
foot-clone
selectable
select-mode="single"
#row-selected="onRowSelected"
:tbody-tr-class="rowClass"
>
<!-- Footers total nutritional values -->
<template v-slot:foot(serving)="data">
<span>Total:</span>
</template>
</b-table>
The table looks like this :
Bootstrap vue documentation only provides this to create a footer :
<!-- Footers total nutritional values -->
<template v-slot:foot(serving)="data">
<span>Total:</span>
</template>
The problem is I don't see how can I add a second footer with this. Another way to do this would be to add a div just below the table and to display what I want but I think there is a cleaner way to do this.
You can use the custom-foot slot. This slot will render directly into the tfoot of the table, so you have free control to structure the foot however you want using tr and td
new Vue({
el: '#app',
data() {
return {
fields: [
// A column that needs custom formatting
{ key: 'name', label: 'Full Name' },
{ key: 'age', label: 'Age' },
{ key: 'sex', label: 'Sex' }
],
items: [
{ name: { first: 'John', last: 'Doe' }, sex: 'Male', age: 42 },
{ name: { first: 'Jane', last: 'Doe' }, sex: 'Female', age: 36 },
{ name: { first: 'Rubin', last: 'Kincade' }, sex: 'Male', age: 73 },
{ name: { first: 'Shirley', last: 'Partridge' }, sex: 'Female', age: 62 }
]
}
}
})
<link href="https://unpkg.com/bootstrap#4.4.1/dist/css/bootstrap.min.css" rel="stylesheet"/>
<link href="https://unpkg.com/bootstrap-vue#2.3.0/dist/bootstrap-vue.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.js"></script>
<script src="https://unpkg.com/bootstrap-vue#2.3.0/dist/bootstrap-vue.js"></script>
<div id="app">
<b-table :fields="fields" :items="items">
<template v-slot:cell(name)="data">
{{ data.value.first }} {{ data.value.last }}
</template>
<template v-slot:custom-foot>
<!-- You can customize this however you want, this is just as an example -->
<tr>
<th v-for="field in fields" :key="field.key">
{{ field.label }}
</th>
</tr>
<tr>
<td class="bg-dark text-white" :colspan="fields.length">
This is my second footer
</td>
</tr>
</template>
</b-table>
</div>

Setting up row components for element-ui table

just started using Vue and Element UI libraray but got stuck with their table component: https://element.eleme.io/#/en-US/component/table
I'd like to have a component for each table row to handle all logic related to that row (actions, click, etc.) in this component but checking their documentation looks like the components are column-based. What am I missing?
Let me show you how to use the basic el-table, such as processing the data of a row
var Main = {
data() {
return {
tableData: [{
date: '2016-05-03',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles'
}, {
date: '2016-05-02',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles'
}, {
date: '2016-05-04',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles'
}, {
date: '2016-05-01',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles'
}]
}
},
methods: {
handleEdit(index, row) {
console.log(index, row);
},
handleDelete(index, row) {
// Here you can access the row data (objects in the object array) to be deleted
console.log(index, row);
this.$confirm('This will permanently delete the record. Continue?', 'Warning', {
confirmButtonText: 'OK',
cancelButtonText: 'Cancel',
type: 'warning'
}).then(() => {
this.tableData.splice(index, 1);
this.$message({
type: 'success',
message: 'Delete completed'
});
}).catch(() => {
this.$message({
type: 'info',
message: 'Delete canceled'
});
});
}
}
}
var Ctor = Vue.extend(Main)
new Ctor().$mount('#app')
#import url("//unpkg.com/element-ui#2.12.0/lib/theme-chalk/index.css");
<script src="//unpkg.com/vue/dist/vue.min.js"></script>
<script src="//unpkg.com/element-ui#2.12.0/lib/index.js"></script>
<div id="app">
<template>
<el-table
:data="tableData"
style="width: 100%">
<el-table-column
label="Date"
width="180">
<template slot-scope="scope">
<i class="el-icon-time"></i>
<span style="margin-left: 10px">{{ scope.row.date }}</span>
</template>
</el-table-column>
<el-table-column label="Name" width="180">
<template slot-scope="scope">
<el-tag size="medium">{{ scope.row.name }}</el-tag>
</template>
</el-table-column>
<el-table-column label="Operations">
<template slot-scope="scope">
<el-button
size="mini"
#click="handleEdit(scope.$index, scope.row)">Edit</el-button>
<el-button
size="mini"
type="danger"
#click="handleDelete(scope.$index, scope.row)">Delete</el-button>
</template>
</el-table-column>
</el-table>
</template>
</div>
Based on Sugars' answer you can toggle an input to allow edits throughout the columns on each row. I've made a simple demo based on his answer.
var Main = {
data() {
return {
tableData: [{
date: '2016-05-03',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles'
editable: false
}, {
date: '2016-05-02',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles'
editable: false
}, {
date: '2016-05-04',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles'
editable: false
}, {
date: '2016-05-01',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles'
editable: false
}]
}
},
methods: {
handleEdit(index, row) {
console.log(index, row);
row.editable = !row.editable;
},
handleDelete(index, row) {
// Here you can access the row data (objects in the object array) to be deleted
console.log(index, row);
this.$confirm('This will permanently delete the record. Continue?', 'Warning', {
confirmButtonText: 'OK',
cancelButtonText: 'Cancel',
type: 'warning'
}).then(() => {
this.tableData.splice(index, 1);
this.$message({
type: 'success',
message: 'Delete completed'
});
}).catch(() => {
this.$message({
type: 'info',
message: 'Delete canceled'
});
});
}
}
}
var Ctor = Vue.extend(Main)
new Ctor().$mount('#app')
#import url("//unpkg.com/element-ui#2.12.0/lib/theme-chalk/index.css");
<script src="//unpkg.com/vue/dist/vue.min.js"></script>
<script src="//unpkg.com/element-ui#2.12.0/lib/index.js"></script>
<div id="app">
<template>
<el-table
:data="tableData"
style="width: 100%">
<el-table-column
label="Date"
width="180">
<template slot-scope="scope">
<i class="el-icon-time"></i>
<span style="margin-left: 10px" v-if="!scope.row.editable">{{ scope.row.date }}</span>
<el-date-picker v-model="scope.row.date" v-if="scope.row.editable"></el-date-picker>
</template>
</el-table-column>
<el-table-column label="Name" width="180">
<template slot-scope="scope">
<el-tag size="medium" v-if="!scope.row.editable">{{ scope.row.name }}</el-tag>
<el-input v-model="scope.row.name" v-if="scope.row.editable"></el-input>
</template>
</el-table-column>
<el-table-column label="Operations">
<template slot-scope="scope">
<el-button
size="mini"
#click="handleEdit(scope.$index, scope.row)">Edit</el-button>
<el-button
size="mini"
type="danger"
#click="handleDelete(scope.$index, scope.row)">Delete</el-button>
</template>
</el-table-column>
</el-table>
</template>
</div>

Why bootstrap table example not working for me?

I have a some project with table like this bootstrap table.
Codesandbox
template:
<b-table small :fields="fields" :items="items">
<template v-slot:cell(index)="data">
{{ data.index + 1 }}
</template>
<!-- A custom formatted column -->
<template v-slot:cell(name)="data">
<b class="text-info">{{ data.value.last.toUpperCase() }}</b>, <b>{{ data.value.first }}</b>
</template>
<!-- A virtual composite column -->
<template v-slot:cell(nameage)="data">
{{ data.item.name.first }} is {{ data.item.age }} years old
</template>
<!-- Optional default data cell scoped slot -->
<template v-slot:cell()="data">
<i>{{ data.value }}</i>
</template>
</b-table>
And script:
fields: [
// A virtual column that doesn't exist in items
'index',
// A column that needs custom formatting
{ key: 'name', label: 'Full Name' },
// A regular column
'age',
// A regular column
'sex',
// A virtual column made up from two fields
{ key: 'nameage', label: 'First name and age' }
],
items: [
{ name: { first: 'John', last: 'Doe' }, sex: 'Male', age: 42 },
{ name: { first: 'Jane', last: 'Doe' }, sex: 'Female', age: 36 },
{ name: { first: 'Rubin', last: 'Kincade' }, sex: 'Male', age: 73 },
{ name: { first: 'Shirley', last: 'Partridge' }, sex: 'Female', age: 62 }
]
Bootstrap table works. I am copy this code and example not work. And I do not understand why.
Question: So, Why bootstrap table example not working?
Helo, i have same problem.
I have some custom fields table, on vue devtools the data has been seen. in vuex bindings.
But on custom table no data can appear, just the amount of data available.
This is my template code
<template>
<div class="table-responsive">
<b-table striped hover :items="todos.data" :fields="fields" show-empty>
<template slot="jadwal" slot-scope="row">
<td class="parent-row">{{ row.item.name }}</td>
</template>
</b-table>
</div>
</template>
and this object vuex binding
{"current_page":1,"data":[{"id":1,"name":"Belajar Vue Laravel","note":"Apa aja boleh deh ini deskripsinnya","due_date":"2019-09-30","status":0,"created_at":"2019-09-29 18:23:51","updated_at":"2019-09-29 18:23:51"},{"id":2,"name":"Belajar mengerti kamu","note":"you are my everythings","due_date":"2019-10-01","status":1,"created_at":"2019-09-29 18:23:51","updated_at":"2019-09-29 18:23:51"}],"first_page_url":"http://localhost:8000/api/todo?page=1","from":1,"last_page":1,"last_page_url":"http://localhost:8000/api/todo?page=1","next_page_url":null,"path":"http://localhost:8000/api/todo","per_page":10,"prev_page_url":null,"to":2,"total":2}

Vuetify, v-for checkbox with search field. Strange behavior on the checkbox

I'm making a list of person to select with a search bar to find the person name. I'm using computed and filter to search the list. But there's strange behavior on my checklist. I don't know what happen. Please check the codepen link above. Try searching then delete the search.
https://codepen.io/rahmatfajar15/pen/OqPqRy?editors=1010
template:
<v-layout column fill-height>
<v-flex>
<v-text-field
v-model="pattern"
box
hide-details
label="Cari Peserta..."
prepend-inner-icon="search"
clear-icon="close"
clearable
/>
</v-flex>
<v-layout column>
<div
v-for="item in filteredPeserta"
>
<v-layout row class="text-xs-left">
<div class="xs2 justify-center align-center">
<v-checkbox
height="16"
v-model="tempPeserta"
:value="item.id"
/>
</div>
<v-layout xs10 column justify-center>
<pre class="body-2">{{ item.name }}</pre>
</v-layout>
</v-layout>
</div>
</v-layout>
</v-layout>
script:
new Vue({
el: '#app',
data: () => ({
pattern: '',
tempPeserta: [],
listPeserta: [
{
id: '1',
name: 'Agung'
},
{
id: '2',
name: 'Bucin'
},
{
id: '3',
name: 'Chandra'
},
{
id: '4',
name: 'Dedek'
},
{
id: '5',
name: 'Enok'
},
{
id: '6',
name: 'Fajar'
},
{
id: '7',
name: 'Galih'
},
{
id: '8',
name: 'Hayo'
},
{
id: '9',
name: 'Ilsa'
},
]
}),
computed: {
filteredPeserta () {
return this.listPeserta.filter(item => {
return item.name.toLowerCase().indexOf(this.pattern.toLowerCase()) > -1
})
}
}
})
You need to add key when using v-for because Vue will reuse list component (document)
<div
v-for="item in filteredPeserta"
:key="item.id"
>
....
</div>