How to disabled v-slot for row in Table Bootstrap Vue - vue.js

I writing bootstrap component for inline edititng in table
I noticed that slots have priority: cell(%cell%) above cell()
How can I turn off a v-slot:cell(%cell%) for a specific row in a table?
<b-table ...>
<template v-slot:cell()="data">
<b-input
v-if="data.item.editing && data.field.editable"
v-model="tableData[data.index][data.field.key]"
/>
<span v-else>{{data.value}}</span>
</template>
<template
v-for="(_, slot) of $scopedSlots"
v-slot:[slot]="scope"
>
<slot
name="cell()"
v-bind="scope"
/>
</template>
<b-table>

If I'm understanding correctly, you want to be able to have a slot to customize the layout when the field is not being editted.
For this you will have to create your own component, wrapping <b-table>, and create your own slot.
<template v-slot:cell()="data">
<b-input
v-if="data.item.editing && data.field.editable"
v-model="tableData[data.index][data.field.key]"
/>
<span v-else>
<slot :name="`noedit(${data.field.key})`" v-bind="data">
{{ data.value }}
</slot>
</span>
</template>
The above code, will then allow you to use the slot noedit(field_key) (you can change the slot name to whatever you want), to edit the layout when that field is not in an "editing" state.
Example
Vue.component("data-table", {
template: "#data-table",
computed: {
editableFields() {
return this.fields.filter((field) => field.editable);
}
},
data() {
return {
userRow: null
};
},
props: ["items", "fields"],
methods: {
editUser(user) {
let doEdit = true;
if (
this.userRow &&
!confirm("You have unsaved changes, are you sure you want to continue?")
) {
doEdit = false;
}
if (doEdit) {
this.userRow = { ...user };
}
},
saveEdit() {
let user = this.items.find((u) => u.id === this.userRow.id);
Object.assign(user, this.userRow);
this.resetEdit();
},
resetEdit() {
this.userRow = null;
}
}
});
new Vue({
el: "#app",
data() {
return {
fields: [
{ key: "id" },
{ key: "first_name", editable: true },
{ key: "last_name", editable: true },
{ key: "age", editable: true, type: "number", isNumber: true },
{ key: "actions" }
],
items: [
{ id: 1, first_name: "Mikkel", last_name: "Hansen", age: 56 },
{ id: 2, first_name: "Mads", last_name: "Mikkelsen", age: 39 },
{ id: 3, first_name: "Anders", last_name: "Matthesen", age: 42 }
]
};
}
});
<link href="https://unpkg.com/bootstrap#4.5.2/dist/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://unpkg.com/bootstrap-vue#2.16.0/dist/bootstrap-vue.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.js"></script>
<script src="https://unpkg.com/bootstrap-vue#2.16.0/dist/bootstrap-vue.js"></script>
<div id="app">
<data-table :items="items" :fields="fields">
<template v-slot:noedit(first_name)="{ value }">
<b class="text-primary">
{{ value }}
</b>
</template>
<template v-slot:cell(id)="{ value }">
<i class="text-danger">{{ value }}</i>
</template>
</data-table>
</div>
<template id="data-table">
<b-table :items="items" :fields="fields">
<template v-for="field in editableFields" v-slot:[`cell(${field.key})`]="s">
<b-input v-if="userRow && userRow.id === s.item.id" v-model="userRow[s.field.key]" :type="s.field.type || 'text'" :number="s.field.isNumber">
</b-input>
<template v-else>
<slot :name="`noedit(${s.field.key})`" v-bind="s">
{{ s.value }}
</slot>
</template>
</template>
<template v-slot:cell(actions)="{ item }">
<b-button-group v-if="userRow && userRow.id === item.id">
<b-btn variant="success" #click="saveEdit">
Save
</b-btn>
<b-btn variant="danger" #click="resetEdit">
Cancel
</b-btn>
</b-button-group>
<b-btn v-else variant="primary" #click="editUser(item)">
Edit
</b-btn>
</template>
<!-- Pass in slots from parent -->
<template v-for="name in Object.keys($scopedSlots)" v-slot:[name]="scope">
<slot :name="name" v-bind="scope"></slot>
</template>
</b-table>
</template>

Related

Make a checkbox selection default out of a group

I want to make the second checkbox always selected by default even on page reload like the image-
The user can select other checkboxes later but by default, the second should be selected always.
Here is the checkbox code-
<template>
<div>
<div class="tw-flex tw-flex-wrap">
<div class="tw-w-full lg:tw-w-1/4">
<collabmed-loading v-if="!initialised">Loading Patient Info...</collabmed-loading>
<reception-patient-info
class="tw-px-0 tw-pt-0"
v-else
:patient-id="admissionRequest.patient_id"
>
</reception-patient-info>
</div>
<div class="tw-w-full lg:tw-w-3/4 lg:tw-pl-5">
<acemed-card>
<acemed-title>
Check In Details
<template #right>
<div v-if="initialised" class="tw-text-lg tw-text-gray-800"><strong>Admission Type:</strong> {{ admissionRequest.admission_type_name }}</div>
</template>
</acemed-title>
<div>
<collabmed-loading v-if="!initialised"></collabmed-loading>
<div v-else>
<div class="tw-flex tw-flex-wrap">
<div class="tw-w-full lg:tw-w-1/2">
<div class="tw-flex tw-flex-wrap tw-justify-between">
<div>
<v-tooltip bottom v-if="msetting('inpatient.inpatient_no_prefix')">
<v-btn flat style="min-width: 50px" slot="activator" class="pull-right pt-3">
{{ msetting('inpatient.inpatient_no_prefix') }}-
</v-btn>
<span>IP Number Prefix</span>
</v-tooltip>
</div>
<div>
<v-text-field
v-model="obj.admission.inpatient_no"
class="mr-2"
label="IP Number"
hint="Possible Format: #######/YY"
></v-text-field>
</div>
<div>
<v-tooltip bottom>
<v-btn
color="primary"
style="min-width: 50px"
slot="activator"
#click="generateIpNumber()"
:loading="generating"
>
<v-icon small>mdi-cached</v-icon>
</v-btn>
<span>Generate IP Number</span>
</v-tooltip>
</div>
</div>
</div>
<div class="tw-w-full tw-pt-5 lg:tw-pt-0 lg:tw-w-1/2 lg:tw-pl-5">
<collabmed-date-time-picker
label="Admission Date"
outline
:maxDate="today"
#input="setAdmissionDate"
></collabmed-date-time-picker>
</div>
<div class="tw-w-full lg:tw-w-1/2 tw-pt-5">
<div v-if="! obj.admission.external_doctor">
<div v-if="! obj.admission.doctor_id">
<users-search
:roles-like="['doc']"
:label="'Admission Doctor'"
#results="setDoctor"
></users-search>
</div>
<p v-else class="pt-3 pl-3 border-bottom subheading">Doctor:</p>
</div>
<p v-else class="pt-3 pl-3 border-bottom subheading">External Doctor:</p>
</div>
<div class="tw-w-full lg:tw-w-1/2 tw-pt-5 lg:tw-pl-5">
<div v-if="obj.admission.doctor_id">
<p class="pt-3 pl-3 border-bottom subheading">
{{ obj.admission.doctor_name }}
<v-btn small color="red" icon dark #click="unsetDoctor()">
<v-icon small>delete</v-icon>
</v-btn>
</p>
</div>
<div v-else>
<v-text-field
v-model="obj.admission.external_doctor"
class="mx-2"
label="External Doctor"
hide-details clearable
></v-text-field>
</div>
</div>
<div class="tw-w-full lg:tw-w-1/2 tw-pt-5">
<v-autocomplete
v-model="obj.admission.ward_id"
:items="wards"
#change="updateBeds()"
item-text="name"
item-value="id"
label="Select a Ward"
hide-details
outline
></v-autocomplete>
</div>
<div class="tw-w-full lg:tw-w-1/2 tw-pt-5 lg:tw-pl-5">
<div v-if="wardCashCharge" class="pl-3">
<p class="font-weight-bold title">Ward Charges</p>
<p>Cash Charge: <strong>{{ wardCashCharge | numberFormat }}</strong></p>
<p>Insurance Charge: <strong>{{ wardInsuranceCharge | numberFormat }}</strong></p>
</div>
</div>
<div class="tw-w-full lg:tw-w-1/2 tw-pt-5">
<v-autocomplete
v-model="obj.admission.bed_id"
:disabled="! obj.admission.ward_id"
:items="beds"
item-text="name"
item-value="id"
label="Select a Bed"
hide-details
outline
></v-autocomplete>
<p v-if="overbookingAllowed"><em>Over-booking of beds has been allowed in the system</em></p>
</div>
<div class="tw-w-full lg:tw-w-1/2 tw-pt-5 lg:tw-pl-5">
<v-autocomplete
v-model="obj.admission.charges"
:disabled="! obj.admission.ward_id"
:items="charges"
item-text="name"
item-value="id"
label="Select Other Charge(s)"
class="ml-2"
hide-details multiple
outline chips
></v-autocomplete>
</div>
<div class="tw-w-full lg:tw-w-1/2 tw-pt-5">
<v-alert :value="true" v-if="errors.any()" type="error" outline>
<div v-html="errors.display()"></div>
</v-alert>
</div>
<div class="tw-w-full tw-pt-5">
<v-btn block dark color="primary" class="mt-4" :loading="saveLoader" #click="save()">
Admit Patient
<v-icon class="pl-2">arrow_right_alt</v-icon>
</v-btn>
</div>
</div>
</div>
</div>
</acemed-card>
</div>
</div>
</div>
</template>
export default {
props: {
admissionRequestId: {
required: true,
}
},
data() {
return {
admissionRequestObj: new AdmissionRequest(),
obj: new Admission(),
wards: null,
saveLoader: false,
beds: [],
charges: [],
wardCashCharge: null,
wardInsuranceCharge: null,
today: moment(new Date()).format('YYYY-MM-DD HH:MM:ss'),
overbookingAllowed: false,
generating: false,
}
},
computed: {
...mapGetters([
'getWards',
]),
admissionRequest() {
return this.admissionRequestObj.selected
},
initialised() {
return this.wards && this.admissionRequest
},
saved() {
return this.obj.saved
},
submitted() {
return this.obj.form.submitted
},
contaminated() {
return this.obj.form.errorDetected;
},
errors() {
return this.obj.form.errors;
},
generatedIpNuber() {
return this.obj.generatedIpNuber
}
},
watch: {
contaminated(val) {
if(val) {
this.saveLoader = false
}
},
submitted(val) {
if(val) {
this.saveLoader = false
}
},
saved(val) {
if(val) {
this.saveLoader = false
this.dialog = false
window.location = route('inpatient.admissions.index').relative()
}
},
admissionRequest(val) {
if(val) {
this.obj.admission.admission_request_id = val.id
this.obj.admission.visit_id = val.visit_id
this.obj.admission.inpatient_no = val.visit.patient.inpatient_no
this.obj.admission.patient_id = val.visit.patient.id
}
},
getWards(val) {
if(val) {
this.wards = this.getWards.data
}
},
generatedIpNuber(val) {
this.generating = false
if(val)
this.obj.admission.inpatient_no = val
}
},
methods: {
...mapActions([
'setWards',
]),
initialise() {
this.admissionRequestObj.find(this.admissionRequestId)
this.setWards()
this.obj.admission.admission_date = this.today
this.overbookingAllowed = this.$options.methods.msetting('inpatient.allow_overbooking_of_wards') == 1
},
updateBeds() {
let ward = _.find(this.wards, {id: this.obj.admission.ward_id})
this.wardCashCharge = ward.cash_cost
this.wardInsuranceCharge = ward.insurance_cost
this.beds = _.map(ward.beds, item => {
let name = "Bed No. " + item.number
! item.is_available ? name += " (Unavailable)" : '';
let disabled = ! item.is_available
this.overbookingAllowed ? disabled = false : null
return {
name: name,
id: item.id,
disabled: disabled
}
})
let firstAvailableBed = _.find(this.beds, { disabled: false })
firstAvailableBed ? this.obj.admission.bed_id = firstAvailableBed.id : null
if(this.charges && this.charges.length && this.charges.length >=2) {
// charges[1] = second item
this.obj.admission.charges.push(this.charges[1].id)
}
this.charges = _.map(ward.charges, item => {
let name = item.name + " - Kshs. " + item.cost;
item.type == 'recurring' ? name += " [RECURRING]" : '';
return {
id: item.id,
name: name
}
})
},
setDoctor(doctor) {
this.obj.admission.doctor_id = doctor.id
this.obj.admission.doctor_name = doctor.full_name
},
unsetDoctor() {
this.obj.admission.doctor_id = null
this.obj.admission.doctor_name = null
},
generateIpNumber() {
this.generating = true
this.obj.generateInpatientNumber()
},
setAdmissionDate(datetime) {
this.obj.admission.admission_date = datetime
},
save() {
this.saveLoader = true
this.obj.save()
}
},
mounted() {
this.initialise()
}
}
</script>
<style scoped lang="scss">
</style>
The api data looks like-
When I select bed, I call a method to fetch the charges. Thats where I have placed the code to select the admission charge where second charge item should always be selected.
If you only want to keep the second item by default selected, then on the mounted hook, just find the second item's id in your charges array, and push this id to your v-model variable (obj.admission.charges) and you should see that the second item is always selected.
Here is the demo-
NOTE-
I used your API data inside the data property of Vue as I can't send requests to your server. I also assumed the possible structure of obj.admission because you didn't mention it.
<!DOCTYPE html>
<html>
<head>
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/#mdi/font#4.x/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.min.css" rel="stylesheet">
</head>
<body>
<div id="app">
<v-app>
<v-container>
<v-autocomplete
v-model="obj.admission.charges"
:disabled="!obj.admission.ward_id"
:items="charges"
item-text="name"
item-value="id"
label="Select Other Charge(s)"
class="ml-2"
hide-details
multiple
outlined
chips
>
</v-autocomplete>
</v-container>
</v-app>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue#2.x/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.js"></script>
<script>
new Vue({
el: '#app',
vuetify: new Vuetify(),
data() {
return {
search: null,
obj: {
admission: {
charges: [],
ward_id: "something",
}
},
charges: [
{
id: 2,
name: "Nursing Fee",
cost: "3000.00",
type: "recurring",
created_at: "2022-08-23 08:00",
},
{
id: 31,
name: "Admission Fee",
cost: "once",
type: "3000.00",
created_at: "2022-08-23 08:00",
},
{
id: 32,
name: "Dr. inpatient visit",
cost: "3000.00",
type: "once",
created_at: "2022-08-23 08:00",
},
{
id: 36,
name: "Dr. Anne Masicka",
cost: "3000.00",
type: "once",
created_at: "2022-08-23 08:00",
},
{
id: 29,
name: "Dr. inpatient visit (Dr. Marwa)",
cost: "3000.00",
type: "once",
created_at: "2022-08-23 08:00",
}
]
}
},
mounted() {
if(this.charges && this.charges.length && this.charges.length >=2) {
// charges[1] = second item
this.obj.admission.charges.push(this.charges[1].id)
}
}
})
</script>
</body>
</html>

VUE Props still undefined how to fix it?

productPage
<template>
<div id="products" class="products">
<div class="container">
<h1 class="text-center p-5">熱銷商品</h1>
<div class="row">
<div v-for="product in products" class="col-md-3">
<div class="card product-item">
<swiper :pagination="true" :modules="modules" class="mySwiper">
<swiper-slide v-for="image in product.data().images">
<img :src="image" class="card-img-top" alt="..." />
</swiper-slide>
</swiper>
<div class="card-body">
<div
class="d-flex flex-column justify-content-between text-center"
>
<h5 class="card-title">{{ product.data().name }}</h5>
<h5 class="card-priceS">
{{ currency(product.data().price) }}$
</h5>
<p>{{ product.data().description }}</p>
</div>
<add-to-cart
:name="product.data().name"
:price="product.data().price"
:product-id="product.id"
:product-image="getImage(product.data().images)"
>
</add-to-cart>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'Produtspage',
components: {
Navbar,
Login,
Swiper,
SwiperSlide,
},
props: {
msg: String,
},
setup() {
return {
modules: [Pagination],
}
},
data() {
return {
products: [],
}
},
mounted() {
this.readData()
},
methods: {
currency,
async readData() {
const querySnapshot = await getDocs(collection(db, 'products'))
querySnapshot.forEach((doc) => {
this.products.push(doc)
console.log(doc.id, ' => ', doc.data())
console.log(doc.data())
})
},
getImage(images) {
console.log(images)
return images
},
},
}
</script>
addtocart component
<template>
<div class="add-to-cart">
<button class="btn btn-success fs-6" #click="addToCart">
<i class="fa-solid fa-cart-plus mx-1"></i>加到購物車
</button>
</div>
</template>
<script>
export default {
name: 'AddToCart',
props: {
name: String,
price: String,
productId: String,
image: String,
},
data() {
return {
item: {
productName: this.name,
productPrice: this.price,
product_id: this.productId,
product_image: this.image,
// productQuantity: 1,
},
}
},
}
</script>
I checked the Vue Devtools, only image no props success, other data does have correct props, the image prop is still undefined, the image data is url and when I console.log(images), the data is shown, but props are still undefined.
I use firestore for the project, did I do anything wrong here?
you are using the wrong name for the binded attribute that dosnt match the prop name :
you are using :product-image in productPage
<add-to-cart
:name="product.data().name"
:price="product.data().price"
:product-id="product.id"
:product-image="getImage(product.data().images)"
>
so you have to match it with productImage instead of product-image as a prop name in the addtocart component
props: {
name: String,
price: String,
productId: String,
productImage: String, // appropriate prop name
},

Cannot get click in Vue.js to work the way I'd like

everyone, I am new to vuejs and vuetify and trying to make a book app but the problem is all the code is complete but when I click on the dropdown item it shows all the books item but I want to show only selected book item.
This is my HTML where I am stuck I am doing mistakes here this and I am failed many times cannot get my answer
<v-container fluid>
<v-row aign="center">
<v-col cols="12">
<v-toolbar-title>State Selection</v-toolbar-title>
<div v-on-clickaway="away" class="searchField dropdown">
<v-text-field
:label="labeling"
v-model="search"
#input="waitForSearch"
>
</v-text-field>
<!-- <div class="bookParent" v-for="item in items" :key="item.id"> -->
<!-- <img :src="item.volumeInfo.imageLinks.thumbnail" /> -->
<div
class="clickUpdateElement"
v-for="(item, index) in items"
:key="item.id"
>
<HelloWorld v-show="show">
<template v-slot:contentHandler class="option" id="option1">
<div
#click="clickCard(item, $event.target)"
class="containerForI"
>
<v-img>
<img :src="item.volumeInfo.imageLinks.thumbnail" />
</v-img>
<a class="anchorTag">{{ item.volumeInfo.title }}</a>
<!-- <span>{{ item.volumeInfo.author }}</span> -->
</div>
</template>
</HelloWorld>
<div class="content">
<Content v-show="show2" #load="updateCard(item, $event.target)">
<template v-slot:cardContent>
<v-card class="mx-auto" elevation="2" outlined shaped>
<v-list-item three-line>
<v-list-item-avatar>
<!-- <v-img :src="imageSrc"></v-img> -->
</v-list-item-avatar>
<v-list-item-content>
<v-card-title>
{{ item.volumeInfo.title }}
</v-card-title>
<v-card-subtitle>
{{ index }} {{ item.volumeInfo.description }}
</v-card-subtitle>
</v-list-item-content>
<v-card-actions>
<v-btn primary>Act</v-btn>
</v-card-actions>
</v-list-item>
</v-card>
</template>
</Content>
</div>
</div>
<v-btn #click="show2 = false">Remove</v-btn>
</div>
</v-col>
</v-row>
</v-container>
MY JS
import axios from "axios";
import { directive as onClickaway } from "vue-clickaway";
import HelloWorld from "../components/HelloWorld";
import Content from "../components/Content";
export default {
name: "Home",
directives: {
onClickaway: onClickaway,
},
data() {
return {
BASE_URL: "https://www.googleapis.com/books/v1/volumes",
items: [],
search: "",
timerId: "",
labeling: "Search For Book",
show: false,
show2: false,
imageSrc: "",
showTitle: "",
showDescription: "",
};
},
components: {
HelloWorld,
Content,
},
created() {},
computed: {},
//Fetch the required Information from Google Book Api
watch: {},
methods: {
async getBooks() {
this.show = true;
let response = await axios.get(`${this.BASE_URL}`, {
params: {
q: this.search,
apikey: "",
},
});
this.items = response.data.items;
console.log(this.items);
},
away() {
console.log("clicked away");
this.show = false;
},
clickCard(item, target) {
console.log(item);
console.log(target);
this.show = false;
this.show2 = true;
},
updateCard(item, target) {
console.log(item);
console.log(target);
},
//Method That Take and wait for the Input
waitForSearch() {
// this.search = "";
clearTimeout(this.timerId);
this.timerId = setTimeout(() => {
this.getBooks();
}, 1000);
},
},
Content.vue i just used slot nothing else
<div class="container">
<div class="row">
<slot name="cardContent"></slot>
</div>
</div>
HelloWorld.vue
html
<div class="menu pointerCursor hide">
<slot name="contentHandler"></slot>
</div>
I try many times but failed. Any leads, please?
What I would try is to keep a record of the index that I want to show.
So what you could do is the following:
1.Change the code calling ClickCard
<div #click="clickCard(item, index)" class="containerForI">
2.Assign the value of index to a component variable
clickCard(item, index) {
console.log(item);
this.indexToShow = index;
this.show = false;
this.show2 = true;
},
3.Initialize the aforementioned variable in your component
data() {
return {
BASE_URL: "https://www.googleapis.com/books/v1/volumes",
indexToShow: null,
...
4.Finally, check if the currently selected index is the one to show
<Content v-show="indexToShow === null || indexToShow === index"
If you want to show all items, after showing only 1, you will have to set indexToShow to null. The Content component is checking for it.

vuejs2 el-table-column column prop with computed value

I'm new in vuejs. I don't see how to use a "computed" value in a table of the ui-element librairy. Here is how I tried ..
<template>
<div class="row">
<div class="col-md-12">
<h4 class="title">Commandes en cours</h4>
</div>
<!--<div v-if="$can('manage-order')">You can manage order.</div>-->
<div class="col-12">
<card title="">
<div>
<div class="col-12 d-flex justify-content-center justify-content-sm-between flex-wrap">
<el-select
class="select-default mb-3"
style="width: 200px"
v-model="pagination.perPage"
placeholder="Per page">
<el-option
class="select-default"
v-for="item in pagination.perPageOptions"
:key="item"
:label="item"
:value="item">
</el-option>
</el-select>
<el-input type="search"
class="mb-3"
style="width: 200px"
placeholder="Search records"
v-model="searchQuery"
aria-controls="datatables"/>
</div>
<div class="col-sm-12">
<el-table stripe
style="width: 100%;"
:data="queriedData"
border>
<el-table-column v-for="column in tableColumns"
:key="column.label"
:min-width="column.minWidth"
:prop="column.prop"
:label="column.label">
</el-table-column>
<el-table-column
:min-width="120"
fixed="right"
label="Actions">
<template slot-scope="props">
<a v-tooltip.top-center="'Like'" class="btn-info btn-simple btn-link"
#click="handleLike(props.$index, props.row)">
<i class="fa fa-heart"></i></a>
<a v-tooltip.top-center="'Edit'" class="btn-warning btn-simple btn-link"
#click="handleEdit(props.$index, props.row)"><i
class="fa fa-edit"></i></a>
<a v-tooltip.top-center="'Delete'" class="btn-danger btn-simple btn-link"
#click="handleDelete(props.$index, props.row)"><i class="fa fa-times"></i></a>
</template>
</el-table-column>
</el-table>
</div>
</div>
<div slot="footer" class="col-12 d-flex justify-content-center justify-content-sm-between flex-wrap">
<div class="">
<p class="card-category">Showing {{from + 1}} to {{to}} of {{total}} entries</p>
</div>
<l-pagination class="pagination-no-border"
v-model="pagination.currentPage"
:per-page="pagination.perPage"
:total="pagination.total">
</l-pagination>
</div>
</card>
</div>
</div>
</template>
<script>
import {Table, TableColumn, Select, Option} from 'element-ui'
import LPagination from 'src/components/Pagination.vue'
import Fuse from 'fuse.js'
export default {
components: {
LPagination,
[Table.name]: Table,
[Select.name]: Select,
[Option.name]: Option,
[TableColumn.name]: TableColumn
},
computed: {
clientName(customer){
return customer.firstname + ' '+ customer.lastname
},
pagedData () {
return this.tableData.slice(this.from, this.to)
},
/***
* Searches through table data and returns a paginated array.
* Note that this should not be used for table with a lot of data as it might be slow!
* Do the search and the pagination on the server and display the data retrieved from server instead.
* #returns {computed.pagedData}
*/
queriedData () {
let result = this.tableData
if (this.searchQuery !== '') {
result = this.fuseSearch.search(this.searchQuery)
this.pagination.total = result.length
}
return result.slice(this.from, this.to)
},
to () {
let highBound = this.from + this.pagination.perPage
if (this.total < highBound) {
highBound = this.total
}
return highBound
},
from () {
return this.pagination.perPage * (this.pagination.currentPage - 1)
},
total () {
this.pagination.total = this.tableData.length
return this.tableData.length
}
},
data () {
return {
pagination: {
perPage: 5,
currentPage: 1,
perPageOptions: [5, 10, 25, 50],
total: 0
},
searchQuery: '',
propsToSearch: ['id_order'],
tableColumns: [
{
prop: 'id_order',
label: 'ID',
minWidth: 200
},
{
prop: "clientName(customer)",
label: 'Client',
minWidth: 200,
}
],
fuseSearch: null,
tableData:[]
}
},
methods: {
handleLike (index, row) {
alert(`Your want to like ${row.name}`)
},
handleEdit (index, row) {
alert(`Your want to edit ${row.name}`)
},
handleDelete (index, row) {
let indexToDelete = this.tableData.findIndex((tableRow) => tableRow.id === row.id)
if (indexToDelete >= 0) {
this.tableData.splice(indexToDelete, 1)
}
}
},
mounted () {
this.fuseSearch = new Fuse(this.tableData, {keys: ['id_order']})
},
created (){
this.$store.dispatch('ps_orders/get_ps_orders').then(
this.tableData = this.$store.getters["ps_orders/orders"])
}
}
</script>
<style>
</style>
My object is like (for a row)
{
"id_order": 4641,
"customer": {
"id_customer": 9008,
"firstname": "Pierre",
"lastname": "dupont"
}
}
In the column "Client" I would like to have "customer.firstname + " " + customer.lastname ... but my computed "method" is not working (I guess it is completly wrong)
Thanks for your help
Here the answer : you can't declare a computed with a parameter, here is how to solve
<el-table-column
label="Client" >
<template slot-scope="scope">
{{ clientName(scope.row.customer) }}
</template>
</el-table-column>
AND
computed: {
clientName(){
return (customer) => customer.firstname + ' '+ customer.lastname
},

How to fill out just one list with vuedraggable?

I am using the following library
https://sortablejs.github.io/Vue.Draggable/#/custom-clone
specifically using the example:
https://github.com/SortableJS/Vue.Draggable/blob/master/example/components/clone-on-control.vue
<template>
<v-container fluid>
<div class="row">
<div class="col-3">
<h3>Draggable 1</h3>
<draggable
class="row wrap fill-height align-center sortable-list"
style="background: red;"
:list="list1"
:group="{ name: 'people', pull: pullFunction }"
#start="start"
>
<v-card class="list-group-item" v-for="element in list1" :key="element.id">
{{ element.name }}
</v-card>
</draggable>
</div>
<div class="col-3">
<h3>Draggable 2</h3>
<draggable class="dragArea list-group" :list="list2" group="people">
<v-card class="list-group-item" v-for="element in list2" :key="element.id">
{{ element.name }}
</v-card>
</draggable>
</div>
</div>
</template>
<script>
import draggable from "vuedraggable";
export default {
components: {
draggable
},
data(){
return {
list1: [
{ name: "Jesus", id: 1 },
{ name: "Paul", id: 2 },
{ name: "Peter", id: 3 }
],
list2: [
{ name: "Luc", id: 5 },
{ name: "Thomas", id: 6 },
{ name: "John", id: 7 }
],
controlOnStart: true
}
},
methods:{
pullFunction() {
return this.controlOnStart ? "clone" : true;
},
start({ originalEvent }) {
this.controlOnStart = originalEvent.ctrlKey;
}
}
}
</script>
What I need to do is fill only a list, that is, from Draggable 1 to Draggable 2, currently it is from Draggable 1 to Draggable 2 and from Draggable 2 to Draggable 1 but I don't need it that way.
Thank you