vue use elementUI <el-popover> in table - vue.js

I've a button that opens a Popover element. In the dialog I've two buttons: Cancel and Sure, when I click on one of these I want to close the dialog.
How can I do that?
This is my code:
var vm = new Vue({
el:'#app',
data:function(){
return {
data:[
{
id:1,
name: 'jak',
age: 24
},
{
id:2,
name: 'irol',
age: 34
}
]
}
},
methods:{
edit(){},
remove(){
// how can i cancel the el-popover
},
otherClick(){
}
}
})
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<script src="https://cdn.bootcss.com/vue/2.5.17-beta.0/vue.js"></script>
<script src="https://cdn.bootcss.com/element-ui/2.3.2/index.js"></script>
<div id="app">
<el-table :data="data" style="width:100%" border>
<el-table-column prop="id" label="id" ></el-table-column>
<el-table-column prop="name" label="Name" ></el-table-column>
<el-table-column prop="age" label="Age" ></el-table-column>
<el-table-column label="Action">
<template slot-scope="scope">
<el-button type="primary" class="mr-20" #click="edit(scope)">Edit</el-button>
<el-popover placement="top" trigger="click" title="Sure?">
<div class="btn-confirm">
<el-button type="text" size="mini" #click="otherClick">Cancel</el-button>
<el-button type="primary" size="mini" #click="remove(scope)">Sure</el-button>
</div>
<el-button type="danger" slot="reference">Delete</el-button>
</el-popover>
</template>
</el-table-column>
</el-table>
</div>

You have to define a property to show/hide the dialog in the data attribute:
data:[
{
id:1,
name: 'jak',
age: 24,
showDialog: false
},
Then add the v-model property to the el-popover:
And finally define the action on Cancel/Sure button, for the 'Cancel' you could simply set the property to false:
<el-button type="text" size="mini" #click="scope.row.showDialog=false">Cancel
For the 'Sure', since you have to add more code, you can set the property in the click method:
remove(row){
//DO THE REMOVE ACTION!
row.showDialog=false;
}
Please take a look to the complete example:
var vm = new Vue({
el:'#app',
data:function(){
return {
data:[
{
id:1,
name: 'jak',
age: 24,
showDialog: false
},
{
id:2,
name: 'irol',
age: 34,
showDialog: false
}
]
}
},
methods:{
edit(){},
remove(row){
//DO THE REMOVE ACTION!
row.showDialog = false;
}
}
})
<script src="//unpkg.com/vue/dist/vue.js"></script>
<script src="//unpkg.com/element-ui#2.4.7/lib/index.js"></script>
<div id="app">
<template>
<el-table :data="data" style="width:100%" border>
<el-table-column prop="id" label="id" ></el-table-column>
<el-table-column prop="name" label="Name" ></el-table-column>
<el-table-column prop="age" label="Age" ></el-table-column>
<el-table-column label="Action">
<template slot-scope="scope">
<el-button type="primary" #click="edit(scope)">Edit</el-button><br/>
<el-button type="danger" slot="reference" #click="scope.row.showDialog=true">Delete</el-button>
<el-popover trigger="click" title="Sure?" v-model="scope.row.showDialog">
<div class="btn-confirm">
<el-button type="text" size="mini" #click="scope.row.showDialog=false">Cancel</el-button>
<el-button type="primary" size="mini" #click="remove(scope.row)">Sure</el-button>
</div>
</el-popover>
</template>
</el-table-column>
</el-table>
</template>
</div>
I hope it helps you, bye.

This dose not work if you have more than 2 records, e.g., using below data:
data:[
{
id:1,
name: 'jak',
age: 24
},
{
id:3,
name: 'irol',
age: 34
},
{
id:2,
name: 'irol1',
age: 34
}
{
id:4,
name: 'irol2',
age: 35
},
]
3 delete confirm dialog will show at the same time.

several hours later and a little of code diggin I finally found the way.
Use ':ref'
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<script src="https://cdn.bootcss.com/vue/2.5.17-beta.0/vue.js"></script>
<script src="https://cdn.bootcss.com/element-ui/2.3.2/index.js"></script>
<div id="app">
<el-table :data="data" style="width:100%" border>
<el-table-column prop="id" label="id" ></el-table-column>
<el-table-column prop="name" label="Name" ></el-table-column>
<el-table-column prop="age" label="Age" ></el-table-column>
<el-table-column label="Action">
<template slot-scope="scope">
<el-button type="primary" #click="edit(scope)">Edit</el-button><br/>
<el-button type="danger" slot="reference" #click="showDialog=true">Delete</el-button>
<el-popover trigger="click" :ref="'popover'+scope.$index">
<div class="btn-confirm">
<el-button type="text" size="mini" #click="remove(scope.$index)">Cancel</el-button>
<el-button type="primary" size="mini" #click="remove(scope)">Sure</el-button>
</div>
</el-popover>
</template>
</el-table-column>
</el-table>
var vm = new Vue({
el:'#app',
data:function(){
return {
showDialog: false,
data:[
{
id:1,
name: 'jak',
age: 24
},
{
id:2,
name: 'irol',
age: 34
}
]
}
},
methods:{
edit(){},
remove(popRef){
//DO THE REMOVE ACTION!
var child = this.$refs[popRef].doClose();
}
}
})

<el-table :data="rows">
<el-table-column prop="name" label="Name" ></el-table-column>
<el-table-column fixed="right" label="Operations">
<template slot-scope="scope">
<el-popover placement="right" trigger="click">
<ul class="table-popover-list">
<li>Copy</li>
<li>Edit</li>
<li>Remove</li>
</ul>
<el-button size="mini" slot="reference">...</el-button>
</el-popover>
</template>
</el-table-column>

Related

vue2 + element ui - how to setting dynamic v-model

Let's make the string(categoryV3) an array with ','
and create array length.
and icon-add click add ..
but v-model not working.. and i don't know add .........
I am not good at speaking English.
Please give me your opinion.
<template>
<el-table
:data="tableData"
>
<el-table-column type="selection" width="55" align="center"> </el-table-column>
<el-table-column props="category" label="category" show-overflow-tooltip>
<template slot-scope="{row}">
<div v-for="(item, index) in generateArray(row.categoryV3)" :key="index">
<el-select class="filter-item select1" filterable v-model="item[index]" placeholder="-">
<el-option
v-for="item in options"
:key="item.value"
:label="`${item.value}. ${item.label}`"
:value="item.value"
/>
</el-select>
<span class="tmp-icon icon-add"><i class="el-icon-circle-plus-outline"></i></span>
<span class="tmp-icon icon-remove" v-show="generateArray(row.categoryV3).length > 1"
><i class="el-icon-remove-outline"></i
></span>
</div>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
export default {
data() {
return {
tableData: [{
categoryV3:"option1,option2"
}, {
categoryV3:""
}],
options: [{
value: 'Option1',
label: 'Option1'
}, {
value: 'Option2',
label: 'Option2'
}]
};
},
methods: {
generateArray(val) {
return val.split(',');
},
}
};
</script>
data add 'categoryV3: []'
<div v-for="(item, index) in categoryV3[scope.$index]" :key="index">
<el-select class="filter-item select1" filterable v-model="categoryV3[scope.$index][index]" placeholder="-">
<el-option
v-for="item in relationCode"
:key="item.code_value"
:label="`${item.code_value}. ${item.code_name}`"
:value="item.code_value"
/>
</el-select>
<span class="tmp-icon icon-add" #click="addModel(categoryV3[scope.$index], '')"
><i class="el-icon-circle-plus-outline"></i
></span>
<span
class="tmp-icon icon-remove"
#click="removeModel(categoryV3[scope.$index], index)"
v-show="categoryV3[scope.$index].length > 1"
><i class="el-icon-remove-outline"></i
></span>
</div>

ElementUI: How to use <el-table> to traverse data which in a database

Here is my code:
<template>
<div>
<el-table
ref="multipleTable"
:data="users">
<el-table-column
prop="id"
label="id">
</el-table-column>
<el-table-column
prop="name"
label="name">
</el-table-column>
</el-table>
</div>
</template>
<script>
export default {
name:'User',
data() {
return{
users:[],
}
},
}
</script>
My database have 'user' table and have id and name. I know use v-for="user in users" to traverse data in <table>, but I don't know how to do it in <el-table>
el-table is a component itself and will traverse the data you pass internally.
You have to pass an array of objects to it, so it will iterate it automatically.
Please refer to the docs for examples here
You need to this like this for example:
<template>
<div>
<el-table
:data="users"
style="width: 100%">
<el-table-column
prop="id"
label="ID"
width="180">
</el-table-column>
<el-table-column
prop="name"
label="Name"
width="180">
</el-table-column>
</el-table>
</div>
</template>
<script>
export default {
data() {
return{
users: [
{
id: 0,
name: 'Name 1'
},
{
id: 1,
name: 'Name 2'
},
{
id: 2,
name: 'Name 3'
},
{
id: 3,
name: 'Name 4'
},
],
}
},
}
</script>

bootstrap-vue using colgroup to group the column with column header

I have to create the table as in the design shown below in the figure, using Bootstrap Vue.
Here the Male and Female is grouped by respective section, this can be done using the simple <td> and <col-group>,
there is the slot table-colgroup in bootstrap-vue documentation, but i did not found the way to use in this scenario.
I have implemented the table in the code snippets below:
Vue.config.productionTip = false
Vue.component('icons', {
template: '<a><slot></slot></a>'
})
new Vue({
el: '#app',
methods: {
addService() {
this.model.services.push({});
}
},
computed: {
sec_a_male: function() {
return this.model.services.reduce(function(a, c) {
return a + Number((c.section_a_male) || 0)
}, 0)
},
sec_a_female: function() {
return this.model.services.reduce(function(a, c) {
return a + Number((c.section_a_female) || 0)
}, 0)
},
sec_b_male: function() {
return this.model.services.reduce(function(a, c) {
return a + Number((c.section_b_male) || 0)
}, 0)
},
sec_b_female: function() {
return this.model.services.reduce(function(a, c) {
return a + Number((c.section_b_female) || 0)
}, 0)
}
},
data: {
model: {
services: []
},
fields: [{
key: "class",
label: "Class"
},
{
key: "section_a_male",
label: "Male"
},
{
key: "section_a_female",
label: "Female"
},
{
key: "section_b_male",
label: "Male"
},
{
key: "section_b_female",
label: "Male"
}
]
}
})
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap-vue#latest/dist/bootstrap-vue.css" />
<script src="https://unpkg.com/vue"></script>
<script src="//unpkg.com/babel-polyfill#latest/dist/polyfill.min.js"></script>
<script src="//unpkg.com/bootstrap-vue#latest/dist/bootstrap-vue.js"></script>
<div id="app">
<b-card header-tag="header" footer-tag="footer">
<template slot="header" class="mb-0">
<button type="button" class="btn btn-primary btn-sm" #click.prevent="addService">
<icons :icon="['fas', 'plus']" /> Add Items/Service</button>
</template>
<b-card-body>
<b-table responsive bordered striped hover caption-top :fields="fields" :items="model.services" caption-top>
<template slot="top-row" slot-scope="data">
<td rowspan="1"></td>
<th colspan="2" scope="colgroup">Section A</th>
<th colspan="2" scope="colgroup">Section B</th>
</template>
<template slot="class" slot-scope="data">
<b-form-input size="sm" class="form-control" v-model="data.item.class" :name="`class_${data.index}`" type="text" />
</template>
<template slot="section_a_male" slot-scope="data">
<b-form-input size="sm" class="form-control" v-model="data.item.section_a_male" :name="`section_a_male_${data.index}`" type="text" />
</template>
<template slot="section_a_female" slot-scope="data">
<b-form-input size="sm" class="form-control" v-model="data.item.section_a_female" :name="`section_a_female_${data.index}`" type="text" />
</template>
<template slot="section_b_male" slot-scope="data">
<b-form-input size="sm" class="form-control" v-model="data.item.section_b_male" :name="`section_b_male_${data.index}`" type="text" />
</template>
<template slot="section_b_female" slot-scope="data">
<b-form-input size="sm" class="form-control" v-model="data.item.section_b_female" :name="`section_b_female_${data.index}`" type="text" />
</template>
<template slot="bottom-row" slot-scope="data">
<td>Total</td>
<td>{{sec_a_male}}</td>
<td>{{sec_a_female}}</td>
<td>{{sec_b_male}}</td>
<td>{{sec_b_female}}</td>
</template>
<template slot="table-colgroup">
<col>
<col span="2">
<col span="2">
</template>
</b-table>
</b-card-body>
</b-card>
</div>
Expected Output:
Please help!
This might get you started. You can add a class bg-danger to your td elements, and you can add variants/classes to your fields array.
Vue.config.productionTip = false
Vue.component('icons', {
template: '<a><slot></slot></a>'
})
new Vue({
el: '#app',
methods: {
addService() {
this.model.services.push({});
}
},
computed: {
sec_a_male: function() {
return this.model.services.reduce(function(a, c) {
return a + Number((c.section_a_male) || 0)
}, 0)
},
sec_a_female: function() {
return this.model.services.reduce(function(a, c) {
return a + Number((c.section_a_female) || 0)
}, 0)
},
sec_b_male: function() {
return this.model.services.reduce(function(a, c) {
return a + Number((c.section_b_male) || 0)
}, 0)
},
sec_b_female: function() {
return this.model.services.reduce(function(a, c) {
return a + Number((c.section_b_female) || 0)
}, 0)
}
},
data: {
model: {
services: []
},
fields: [{
key: "class",
label: "Class"
},
{
key: "section_a_male",
label: "Male",
variant: 'danger'
},
{
key: "section_a_female",
label: "Female",
variant: 'danger'
},
{
key: "section_b_male",
label: "Male",
variant: 'warning'
},
{
key: "section_b_female",
label: "Male",
variant: 'warning'
}
]
}
})
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap-vue#latest/dist/bootstrap-vue.css" />
<script src="https://unpkg.com/vue"></script>
<script src="//unpkg.com/babel-polyfill#latest/dist/polyfill.min.js"></script>
<script src="//unpkg.com/bootstrap-vue#latest/dist/bootstrap-vue.js"></script>
<div id="app">
<b-card header-tag="header" footer-tag="footer">
<template slot="header" class="mb-0">
<button type="button" class="btn btn-primary btn-sm" #click.prevent="addService">
<icons :icon="['fas', 'plus']" /> Add Items/Service</button>
</template>
<b-card-body>
<b-table responsive bordered hover caption-top :fields="fields" :items="model.services" foot-clone>
<template slot="class" slot-scope="data">
<b-form-input size="sm" class="form-control" v-model="data.item.class" :name="`class_${data.index}`" type="text" />
</template>
<template slot="section_a_male" slot-scope="data">
<b-form-input size="sm" class="form-control" v-model="data.item.section_a_male" :name="`section_a_male_${data.index}`" type="text" />
</template>
<template slot="section_a_female" slot-scope="data">
<b-form-input size="sm" class="form-control" v-model="data.item.section_a_female" :name="`section_a_female_${data.index}`" type="text" />
</template>
<template slot="section_b_male" slot-scope="data">
<b-form-input size="sm" class="form-control" v-model="data.item.section_b_male" :name="`section_b_male_${data.index}`" type="text" />
</template>
<template slot="section_b_female" slot-scope="data">
<b-form-input size="sm" class="form-control" v-model="data.item.section_b_female" :name="`section_b_female_${data.index}`" type="text" />
</template>
<template slot="bottom-row" slot-scope="data">
<td>Total</td>
<td class="bg-danger">{{sec_a_male}}</td>
<td class="bg-danger">{{sec_a_female}}</td>
<td class="bg-warning">{{sec_b_male}}</td>
<td class="bg-warning">{{sec_b_female}}</td>
</template>
</b-table>
</b-card-body>
</b-card>
</div>
This hasn't been on the boostrap-vue before, new changes has just been published on current version of boostrap-vue v2.0.0-rc.14, which support for the header row.
<b-table responsive bordered striped hover caption-top :fields="fields" :items="model.services" caption-top>
<template slot="thead-top" slot-scope="{}">
<tr>
<th></th>
<th class="text-center" colspan="2">Section A</th>
<th class="text-center" colspan="2">Section B</th>
</tr>
</template>
</b-table>
This can be done by using thead-top slot, further explained here
https://bootstrap-vue.js.org/docs/components/table#adding-additional-rows-to-the-header
This might give the alternate case:
<b-table class ="table" :fields="fields" :items="items">
<template slot="bottom-row" slot-scope="{}">
<th colspan="5" class="text-center">No Data</th>
</template>
</b-table>
get header table from :fields
default row in bottom with text "No Data" align center. Post condition :items is null.
Check table output below:

"element-ui" table How to change empty cells as '-'.

var Main = {
data() {
return {
tableData: [{
date: '2016-05-03',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles'
}, {
date: '2016-05-02',
name: '',
address: 'No. 189, Grove St, Los Angeles'
}, {
date: '2016-05-04',
name: '',
address: 'No. 189, Grove St, Los Angeles'
}, {
date: '2016-05-01',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles'
}]
}
}
}
var Ctor = Vue.extend(Main)
new Ctor().$mount('#app')
#import url("//unpkg.com/element-ui#2.4.11/lib/theme-chalk/index.css");
<script src="//unpkg.com/vue/dist/vue.js"></script>
<script src="//unpkg.com/element-ui#2.4.11/lib/index.js"></script>
<div id="app">
<template>
<el-table :data="tableData" style="width: 100%">
<el-table-column prop="date" label="Date" width="180">
</el-table-column>
<el-table-column prop="name" label="Name" width="180">
<template slot-scope="scope">
{{scope.row.name || '-'}}
</template>
</el-table-column>
<el-table-column prop="address" label="Address">
</el-table-column>
</el-table>
</template>
</div>
I know If I use 'template' tag I can convert null data as '-'.
now let's suppose that I have more than 100 tables and I don't know which cells can be null. putting 'template' to all el-table-columns will be very hard work and inefficient way.
I want to know is there any way that I can change empty cells as '-' at the same time. help me guys
jsfiddle
Just :
<template>
<el-table :data="tableData" style="width: 100%">
<el-table-column prop="date" label="Date" width="180">
</el-table-column>
<el-table-column prop="name" label="Name" width="180">
<template slot-scope="scope">
<!-- Replace empty cell by '-' --->
<div class="cell" v-if="scope.row.name !== null">{{ scope.row.answer }}</div>
<div v-else class="cell">-</div>
</template>
</el-table-column>
<el-table-column prop="address" label="Address">
</el-table-column>
</el-table>
I'm sure there are many ways to achieve that. But try this:
computed: {
items() {
let data = this.tableData;
for(let item of data) {
for(let key in item) {
if (!item[key]) {
item[key] = '-';
}
}
}
return data;
}
}
<template>
<el-table :data="items" style="width: 100%">
<! -- the rest of the content -->

Addings Rows in Element In Vue Js

I'm trying to display rows using the Element IO in VueJs. My problem is why is my code not outputting and how can i add some rows and remove some rows? Is there something wrong with my code? I've attached a v-for but it seems it can't work. I'm sorry i'm new to element-ui. Please see my code below.Thank you.
<template>
<div>
<el-form>
<el-table v-for='(item, index) in items' :key='index'>
<el-table-column
sortable="true"
label="Item">
<template>
<el-input v-model="item.item_id"></el-input>
</template>
</el-table-column>
<el-table-column
sortable="true"
label="Quantity">
<template>
<el-input v-model="item.quantity"></el-input>
</template>
</el-table-column>
<el-table-column
sortable="true"
label="Unit">
<template>
<el-input v-model="item.quantity"></el-input>
</template>
</el-table-column>
<el-table-column
sortable="true"
label="Unit Price">
<template>
<el-input v-model="item.unit_price"></el-input>
</template>
</el-table-column>
<el-table-column
fixed="right"
property="action"
label="Action">
<template>
<el-button type="danger" size="small">Remove</el-button>
</template>
</el-table-column>
</el-table>
<br>
<el-form-item style="float:right;">
<el-button type="submit" #click.prevent="createNewPurchaseOrder">Create</el-button>
<el-button>Cancel</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
export default {
data () {
return {
items: [
{
item_id: '1',
quantity: '8',
unit_id: 'Gram',
unit_price: '100'
}
]
}
},
methods: {
createNewPurchaseOrder () {
console.log(this.$data)
}
}
}
</script>
You don't need to iterate your self. el-table component from Element-Ui is taking a array as data props to work. See Table Props for el-table component in ElementUI
This should works :
<el-table :data="items">
...
</el-table>
Each el-table-column must be a key of your item in your item list by adding prop='myKey' to each el-table-column
For exemple if I got a array of items like this :
[{
id : 12,
firstname : "John",
lastname : "Doe"
}]
I will have a table like this
<el-table :data="items">
<el-table-column prop="id" label="ID">...</el-table-column>
<el-table-column prop="firstname" label="Firstname">...</el-table-column>
<el-table-column prop="lastname " label="Lastname">...</el-table-column>
</el-table>
When you will remove or add an item to your array, the :data props of the el-table will be reactive to changes.
Take more look at element table documentation
You have to pass a data property to el-table and a prop property to el-table-column
<template>
<div>
<el-form>
<el-table :data="items" :key='index'>
[...]
</el-table>
<br>
<el-form-item style="float:right;">
<el-button type="submit" #click.prevent="createNewPurchaseOrder">Create</el-button>
<el-button>Cancel</el-button>
</el-form-item>
</el-form>
</div>