I am trying to show the dynamically elapsed time from a start time
<template>
<div class="dashboard-editor-container">
<div class="wrapper__body">
<el-row :gutter="30">
<el-col v-for="item in options" :key="item.value" align="middle" :xs="24" :sm="24" :md="24" :lg="4" :xl="24" style="margin-bottom:10px">
<el-button type="primary" style="width: 180px;height:120px ;" >{{item.label}} - {{getTimer(item.FechaHora)}}</el-button>
</el-col>
</el-row>
</div>
</div>
</template>
js
<script>
export default {
data() {
return {
options: [{
value: '01',
label: 'Room 1',
FechaHoraInicio:'2020-02-18T18:17:53.56',
FechaHoraSalida:'2020-02-18T18:17:53.56',
}, {
value: '02',
label: 'Room 2',
FechaHoraStartTime:'2020-02-18T18:17:53.56',
FechaHoraSalida:'2020-02-18T18:17:53.56',
}, {
value: '03',
label: 'Room 2',
FechaHoraStartTime:'2020-02-18T18:17:53.56',
FechaHoraSalida:'2020-02-18T18:17:53.56',
},
}
}
},
computed: {
getTimer : function(FechaHoraInicio) {
setInterval(function(){
return Date.now()-new Date(FechaHoraInicio)
}, 3000);
},
},
}
</script>
the buttons are created dynamically and will have a start time, and after that I want to calculate dynamically
I dynamically create each button with its respective start time, and I need that dynamically as a clock the time that elapses is shown, subtracting the current time with the start time
the time that has elapsed, since the room was rented
i hope this works for you:
new Vue({
el: "#app",
data() {
return {
options: [
{
value: "01",
label: "Room 1",
FechaHoraStartTime: "2020-02-18T18:17:53.56",
FechaHoraSalida: "2020-02-18T18:17:53.56"
},
{
value: "02",
label: "Room 2",
FechaHoraStartTime: "2020-02-18T18:17:53.56",
FechaHoraSalida: "2020-02-18T18:17:53.56"
},
{
value: "03",
label: "Room 2",
FechaHoraStartTime: "2020-02-18T18:17:53.56",
FechaHoraSalida: "2020-02-18T18:17:53.56"
}
],
intervalEvents: []
};
},
created() {
this.setTimers();
},
beforeDestroy() {
this.intervalEvents.map(intervalEvent => {
clearInterval(intervalEvent)
})
},
methods: {
setTimers() {
this.options = this.options.map(option => ({
...option,
elapsed: "",
startTimeAsDate: new Date(option.FechaHoraStartTime)
}));
this.options.map(option => {
const event = setInterval(() => {
option.elapsed = new Date(new Date().getTime() - option.startTimeAsDate).toLocaleTimeString();
}, 1000);
this.intervalEvents.push(event)
});
}
}
});
<link
rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.min.js"></script>
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<div id="app">
<div class="dashboard-editor-container">
<div class="wrapper__body">
<el-row :gutter="30">
<el-col
v-for="(option, index) in options"
:key="index"
align="middle"
:xs="24" :sm="24" :md="24" :lg="4" :xl="24"
style="margin-bottom:10px"
>
<el-button type="primary" style="width:180px;height:120px ;">
{{option.label}} {{ option.elapsed }}
</el-button>
</el-col>
</el-row>
</div>
</div>
</div>
Related
I'm trying to pass data from vue component to vue view file. I tried creating props but it didn't work. I have one component file on path src/components/list.vue and another file on path src/views/select.vue
The flow goes like this: User lands on select.vue page, here on click of input box a pop-up appears which have have list of elements in <ul> <li> tag from list.vue (component file).
What I want to achieve:
Whenever user select any option from list.vue file, modal pop-up should close and selected element should be displayed in input box of select.vue file.
Below is code:
src/views/select.vue
<label class="primary-label mb-2">First Question</label>
<div class="form-block">
<label class="secondary-label mb-1">Question</label>
<b-form-input placeholder="Select Question" v-model="questions.first" class="form-control l-input" #click="onOptionChanged"></b-form-input>
</div>
<div class="form-block">
<label class="secondary-label mb-1">Answer</label>
<b-form-input v-model="answers.first" placeholder="Enter answer" class="form-control l-input"></b-form-input>
</div>
<script>
export default {
data() {
return {
questions: {
first: null,
},
answers: {
first: null,
},
options: [
{ value: null, text: 'Select Question', disabled:true },
{ value: 1, text: 'In what city were you born?' },
{ value: 2, text: 'What is the name of your favorite pet?' },
{ value: 3, text: 'What is your mother\'s maiden name?' },
{ value: 4, text: 'What high school did you attend?' },
{ value: 5, text: 'What is the name of your first school?' },
{ value: 6, text: 'What was the make of your first car?' },
{ value: 7, text: 'What was your favorite food as a child?' },
{ value: 8, text: 'Where did you meet your spouse?' },
],
}
},
methods: {
onOptionChanged() {
var modal_ref = 'myModalRef';
this.$refs[modal_ref].show();
},
},
components: {
SecurityQuestionsList,
},
}
src/components/list.vue
<template>
<main>
<div class="container">
<div class="row">
<div class="col-md-6">
<div class="search-block">
<span class="s-icon fa fa-search"></span>
</div>
<ul class="l-group" v-if="filteredQuestions.length > 0">
<li class="d-flex align-items-center" :key="item.id" v-for="item in filteredQuestions" #click="onOptionSelect(item.question)"
:class="selected === item.id ? 'my-selected-item-class':null">
{{item.question}}
</li>
</ul>
</div>
</div>
</div>
</main>
</template>
<script>
export default {
data() {
return {
search: '',
selected: null,
questions: [
{ id: 1, question: 'In what city were you born?' },
{ id: 2, question: 'What is the name of your favorite pet?' },
{ id: 3, question: 'What is your mother\'s maiden name?' },
{ id: 4, question: 'What high school did you attend?' },
{ id: 5, question: 'What is the name of your first school?' },
{ id: 6, question: 'What was the make of your first car?' },
{ id: 7, question: 'What was your favorite food as a child?' },
{ id: 8, question: 'Where did you meet your spouse?' },
],
}
},
computed: {
filteredQuestions() {
return this.questions.filter(item => {
return item.question.toLowerCase().includes(this.search.toLowerCase());
});
}
},
methods: {
onOptionSelect(selectedId) {
this.selected = selectedId;
console.log(this.selected);
this.$emit('questions-selected', this.selected);
},
}
}
</script>
I am getting selected value in console but not sure how to catch it in search.vue file.
Thanks!
You need to connect your components and pass props, try like following snippet:
Vue.component('list', {
template: `
<main>
<div class="container">
<div class="row">
<div class="col-md-6">
<div class="search-block">
<span class="s-icon fa fa-search"></span>
</div>
<ul class="l-group" v-if="filteredQuestions.length > 0">
<li class="d-flex align-items-center" :key="item.id" v-for="item in filteredQuestions" #click="onOptionSelect(item.question)"
:class="selected === item.id ? 'my-selected-item-class':null">
{{item.question}}
</li>
</ul>
</div>
</div>
</div>
</main>
`,
props: ['search'],
data() {
return {
selected: null,
questions: [
{ id: 1, question: 'In what city were you born?' },
{ id: 2, question: 'What is the name of your favorite pet?' },
{ id: 3, question: 'What is your mother\'s maiden name?' },
{ id: 4, question: 'What high school did you attend?' },
{ id: 5, question: 'What is the name of your first school?' },
{ id: 6, question: 'What was the make of your first car?' },
{ id: 7, question: 'What was your favorite food as a child?' },
{ id: 8, question: 'Where did you meet your spouse?' },
],
}
},
computed: {
filteredQuestions() {
if (this.search) {
return this.questions.filter(item => {
return item.question.toLowerCase().includes(this.search.toLowerCase());
});
} return this.questions
}
},
methods: {
onOptionSelect(selectedId) {
this.selected = selectedId;
this.$emit('questions-selected', selectedId);
},
}
})
new Vue({
el: "#demo",
name: 'select',
data() {
return {
questions: {
first: null,
},
answers: {
first: null,
},
selected: false
}
},
methods: {
onOptionChanged() {
this.selected = true
},
onSelected(val) {
this.questions.first = val
this.selected = false
},
},
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<link type="text/css" rel="stylesheet" href="https://unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
<link type="text/css" rel="stylesheet" href="https://unpkg.com/bootstrap-vue#latest/dist/bootstrap-vue.min.css" />
<script src="https://unpkg.com/bootstrap-vue#latest/dist/bootstrap-vue.min.js"></script>
<script src="https://unpkg.com/bootstrap-vue#latest/dist/bootstrap-vue-icons.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css" integrity="sha512-KfkfwYDsLkIlwQp6LFnl8zNdLGxu9YAA1QvwINks4PhcElQSvqcyVLLD9aMhXd13uQjoXtEKNosOWaZqXgel0g==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<div id="demo">
<div>
<label class="primary-label mb-2">First Question</label>
<div class="form-block">
<label class="secondary-label mb-1">Question</label>
<b-form-input placeholder="Select Question" v-model="questions.first" class="form-control l-input" #click="onOptionChanged()"></b-form-input>
</div>
<div class="form-block">
<label class="secondary-label mb-1">Answer</label>
<b-form-input v-model="answers.first" placeholder="Enter answer" class="form-control l-input"></b-form-input>
<list :search="questions.first" #questions-selected="onSelected" v-if="selected"></list>
</div>
</div>
</div>
I'm trying to create a cascading dropdown using vue.js.
I want to set the data on the second dropdown based on the item chosen from the first dropdown.
I don't know how to filter the data based on the chosen item.
I've tried to use computed property but didn't succeed.
I need some help please.
Thanks in advance.
<template>
<b-container class="my-2">
<b-row>
<b-col col="12" md="6" lg="3">
<b-form-group id="fieldset" :label="$t('tradingCalculators.fields.currencyPair')" label-for="currency-first" label-size="lg">
<v-select
id="assetPair"
#click="changeAssetClass(assetPair)"
v-model="assetPair"
:searchable="true"
:options="assetSymbols"
/>
</b-form-group>
</b-col>
<b-col cols="12" md="6" lg="3">
<b-form-group id="fieldset-1" :label="$t('tradingCalculators.fields.currencyPair')" label-for="currency-pair" label-size="lg">
<v-select id="symbolsPair" v-model="symbolsPair" :searchable="true" :options="currencyArray" />
</b-form-group>
</b-col>
</b-row>
</b-container>
</template>
export default {
data() {
assetPair: 'Forex',
symbolsPair: '',
currencyArray: [],
assetsSymbols: [{
text: 'Forex',
id: 1
},
{
text: 'Metal',
id: 2
},
{
text: 'Indices',
id: 3
},
],
symbolsPair: {
1: [{
text: 'AUDCAD',
id: 1,
},
{
text: 'AUDCHF',
id: 2,
},
{
text: 'AUDJPY',
id: 3,
},
],
2: [{
text: 'XAUUSD',
id: 1,
},
{
text: 'XAGUSD',
id: 2,
},
],
3: [{
text: 'GER30Cash',
id: 1,
},
{
text: 'US30Cash',
id: 2,
},
{
text: 'EU50Cash',
id: 3,
},
],
}
},
computed() {
changeAssetClass(e) {
return this.currencyArray.push(this.symbolsPair[e])
}
}
}
One observation : You are updating the source array this.currencyArray on first dropdown select. Hence, the cascading dropdown will not contain the filtered data.
Working Demo :
new Vue({
el: '#app',
data: function() {
return {
assetsSymbols: [{
text: 'Forex',
id: 1
}, {
text: 'Metal',
id: 2
}, {
text: 'Indices',
id: 3
}
],
selectedSymbol: '',
selectedSymbolPair: '',
symbolsPairArr: [],
symbolsPair: {
1: [{
text: 'AUDCAD',
id: 1,
},
{
text: 'AUDCHF',
id: 2,
},
{
text: 'AUDJPY',
id: 3,
},
],
2: [{
text: 'XAUUSD',
id: 1,
},
{
text: 'XAGUSD',
id: 2,
},
],
3: [{
text: 'GER30Cash',
id: 1,
},
{
text: 'US30Cash',
id: 2,
},
{
text: 'EU50Cash',
id: 3,
},
]}
}
},
watch: {
selectedSymbol: function() {
this.symbolsPairArr = [];
if (this.selectedSymbol > 0) {
this.symbolsPairArr = this.symbolsPair[this.selectedSymbol];
}
}
},
mounted() {
this.selectedSymbol = 2;
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div class="cascading-dropdown">
<div class="dropdown">
<span>Symbol :</span>
<select v-model="selectedSymbol">
<option value="">Select a Symbol</option>
<option v-for="symbol in assetsSymbols" :value="symbol.id" :key="symbol.id">{{ symbol.text }}</option>
</select>
</div>
<div class="dropdown">
<span>Symbol Pair:</span>
<select :disabled="!selectedSymbol" v-model="selectedSymbolPair">
<option value="">Select a Pair</option>
<option v-for="pair in symbolsPairArr" :value="pair.id" :key="pair.id">{{ pair.text }}</option>
</select>
</div>
</div>
</div>
Note : I created this snippet to demonstrate you how it will work as per your requirement. You can modify it as per the need if required.
i have two tasks:
Displaying the items of the item list 3 per row
Add a input field used to edit the title field in the currently selected element (selection should be made by clicking).
So, I made the first task based on this solving V-if inside v-for - display list of items in two columns and now i have a problem with my second task selecting method. It should be working for every item but on click selects an items from every list and can to edit only from first list. I think that problem can be in onItemClick(index) method but don't know why.
Any ideas about that?
Vue.component('item-list', {
template: '#item-list-template',
data() {
return {
items: [{
title: 'item 1'
},
{
title: 'item 2'
},
{
title: 'item 3'
},
{
title: 'item 4'
},
{
title: 'item 5'
},
{
title: 'item 6'
}
],
activeIndex: -1,
rowArray: []
}
},
mounted(){
this.fakeFetchData();
},
methods: {
// new method from example solving
fakeFetchData(){
var cloned = this.items.slice();
while (cloned.length > 0) {
let chunk = cloned.splice(0,3);
this.rowArray.push(chunk);
}
},
onItemClick(index) {
this.activeIndex = this.activeIndex === index ? -1 : index;
},
setActiveItemValue(event) {
const foundItem = this.items[this.activeIndex];
if (!foundItem) return;
return this.items[this.activeIndex].title = event.currentTarget.value;
}
},
computed: {
activeItemValue() {
return this.items[this.activeIndex]?.title ?? '';
}
}
});
Vue.component('item', {
template: '#item-template',
props: {
isActive: Boolean,
title: String
}
});
new Vue({
el: '#app'
});
li.active {
background-color: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<item-list></item-list>
</div>
<script type="text/x-template" id="item-list-template">
<div>
<input type="text" placeholder="Edit selected items" :value="activeItemValue" #input="setActiveItemValue" />
<div class="items-col">
<ul class="items-list" v-for="(row, rowIndex) in rowArray" :key="rowIndex">
<item v-for="(item, i) in row" :key="i" :title="item.title" :isActive="activeIndex === i" #click.native="onItemClick(i)" />
</ul>
</div>
</div>
</script>
<script type="text/x-template" id="item-template">
<li class="item" :class="{ active: isActive }">{{ title }}</li>
</script>
<style>
.items-list {
display: flex;
}
</style>
I have modified and moved the fakeFetchData() from mounted to inside computed and modified the inner v-for inside the template. Check it out
Vue.component('item-list', {
template: '#item-list-template',
data() {
return {
items: [{
title: 'item 1'
},
{
title: 'item 2'
},
{
title: 'item 3'
},
{
title: 'item 4'
},
{
title: 'item 5'
},
{
title: 'item 6'
}
],
activeIndex: -1,
rowArray: []
}
},
methods: {
// new method from example solving
onItemClick(index) {
this.activeIndex = this.activeIndex === index ? -1 : index;
},
setActiveItemValue(event) {
const foundItem = this.items[this.activeIndex];
if (!foundItem) return;
return this.items[this.activeIndex].title = event.currentTarget.value;
}
},
computed: {
activeItemValue() {
return this.items[this.activeIndex]?.title ?? '';
},
fakeFetchData(){
// ********* Changes done below ************
var cloned = this.items.map((item, index) => {
return {title: item.title, id: index}
});
this.rowArray = [];
while (cloned.length > 0) {
let chunk = cloned.splice(0,3);
this.rowArray.push(chunk);
}
return this.rowArray;
// ******* End of changes ********
},
}
});
Vue.component('item', {
template: '#item-template',
props: {
isActive: Boolean,
title: String
}
});
new Vue({
el: '#app'
});
li.active {
background-color: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<item-list></item-list>
</div>
<script type="text/x-template" id="item-list-template">
<div>
<input type="text" placeholder="Edit selected items" :value="activeItemValue" #input="setActiveItemValue" />
<div class="items-col">
<ul class="items-list" v-for="(row, rowIndex) in fakeFetchData" :key="rowIndex">
<!-- Changes done --><item v-for="item in row" :key="item.id" :title="item.title" :isActive="activeIndex === item.id" #click.native="onItemClick(item.id)" />
</ul>
</div>
</div>
</script>
<script type="text/x-template" id="item-template">
<li class="item" :class="{ active: isActive }">{{ title }}</li>
</script>
<style>
.items-list {
display: flex;
}
</style>
From documentation of bootsrap-vue (based on bootstrap 4):
<b-input-group>
<b-input-group-prepend is-text>
<input type="radio" aria-label="Radio for following text input">
</b-input-group-prepend>
<b-form-input aria-label="Text input with radio button"></b-form-input>
</b-input-group>
And get this input:
I want to do a component to choosed one of 2 or more values based on this input.
For example,
selectedValue: null,
compareOptions: [{text: "Value1", value: option1}, {text: "Value2", value: option2}]
But documentation says it:
Note: you must use native radio and checkbox inputs, as
and include additional markup not required in input
groups.
How I should use code from docs to set a v-model and options to make it work as intended.
If it's interesting somebody the solution is:
Child Component
<template>
<b-container fluid>
<b-form-group
:label="formLabel"
class="mb-1"
label-class="text-center">
<b-row>
<b-col class="pl-2 pr-1">
<b-input-group
size="sm"
сlass="mb-1">
<b-input-group-prepend is-text>
<input
v-model="selectedValue"
:value="oldValue"
type="radio"
#change="sendSelected">
</b-input-group-prepend>
<b-form-input
:value="oldValue"
#input="changeValue('old', $event)" />
</b-input-group>
</b-col>
<b-col class="pl-1 pr-2">
<b-input-group
size="sm"
class="mb-1">
<b-input-group-prepend is-text>
<input
v-model="selectedValue"
:value="newValue"
type="radio"
#change="sendSelected">
</b-input-group-prepend>
<b-form-input
:value="newValue"
#input="changeValue('new', $event)" />
</b-input-group>
</b-col>
</b-row>
</b-form-group>
</b-container>
</template>
<script>
export default {
props: {
value: {
type: Object,
required: true
}
},
data () {
return {
selectedValue: null
}
},
computed: {
newValue () {
return this.value.new
},
oldValue () {
return this.value.old
},
formLabel () {
return this.value.label
}
},
created () {
},
methods: {
sendSelected () {
this.$emit('change', this.selectedValue)
},
changeValue (path, event) {
this.selectedValue = null
this.emitMutationEvent(path, event) //custom event
}
}
}
</script>
Parent Component
<template>
<b-container fluid>
<compare-component
v-for="documentField in documentFields"
:key="documentField.id"
:value="documentField"
#change="setSelectedValue(documentField, ...arguments)"
#mutate="editOriginValues(documentField, ...arguments)" />
</b-container>
</template>
<script>
import CompareComponent from './CompareComponent'
export default {
components: {
CompareComponent
},
mixins: [PropMutationEventMixin],
data () {
return {
reviewDocument: null,
newSessionDocument: null,
oldSessionDocument: null,
documentFields: [
{
id: 1,
old: 'old value 1',
new: 'new value 1',
label: 'value1',
selected: ''
},
{
id: 2,
old: 'old value 2',
new: 'new value 2',
label: 'value 2',
selected: ''
},
{
id: 3,
old: 'old value 3',
new: 'new value 3',
label: 'value 3',
selected: ''
}
]
}
},
methods: {
setSelectedValue (documentField, event) {
documentField.selected = event
},
editOriginValues (documentField, path, newValue) {
documentField[path] = newValue
}
}
}
</script>
I have been looking for a way to drag and drop rows on a Bootstrap Vue table.
I was able to find a working version here: Codepen
I have tried to implement this code to my own table:
Template:
<b-table v-sortable="sortableOptions" #click="(row) => $toast.open(`Clicked ${row.item.name}`)" :per-page="perPage" :current-page="currentPage" striped hover :items="blis" :fields="fields" :filter="filter" :sort-by.sync="sortBy" :sort-desc.sync="sortDesc" :sort-direction="sortDirection" #filtered="onFiltered">
<template slot="move" slot-scope="row">
<i class="fa fa-arrows-alt"></i>
</template>
<template slot="actions" slot-scope="row">
<b-btn :href="'/bli/'+row.item.id" variant="light" size="sm" #click.stop="details(cell.item,cell.index,$event.target)"><i class="fa fa-pencil"></i></b-btn>
<b-btn variant="light" size="sm" #click.stop="details(cell.item,cell.index,$event.target)"><i class="fa fa-trash"></i></b-btn>
</template>
<template slot="priority" slot-scope="row">
<input v-model="row.item.priority" #keyup.enter="row.item.focussed = false; updatePriority(row.item), $emit('update')" #blur="row.item.focussed = false" #focus="row.item.focussed = true" class="form-control" type="number" name="priority" >
</template>
</b-table>
Script:
import Buefy from 'buefy';
Vue.use(Buefy);
const createSortable = (el, options, vnode) => {
return Sortable.create(el, {
...options
});
};
const sortable = {
name: 'sortable',
bind(el, binding, vnode) {
const table = el.querySelector('table');
table._sortable = createSortable(table.querySelector('tbody'), binding.value, vnode);
}
};
export default {
name: 'ExampleComponent',
directives: { sortable },
data() {
let self = this;
return {
blis: [],
currentPage: 1,
perPage: 10,
pageOptions: [ 5, 10, 15 ],
totalRows: 0,
sortBy: null,
sortDesc: false,
sortDirection: 'asc',
sortableOptions: {
chosenClass: 'is-selected'
},
filter: null,
modalInfo: { title: 'Title', content: 'priority' },
fields: [
{
key: 'move',
sortable: true
},
///...rest of the fields
]
}
};
Now I have been getting this error: Error in directive sortable bind hook: "TypeError: Cannot read property 'querySelector' of null"
Why is it not able to find the <tbody> ?
Edit: https://jsfiddle.net/d7jqtkon/
In line const table = el.querySelector('table'); you are trying to get the table element. The var el is the table element. That is why it return null when you use querySelector
after assigning the correct table variable the error disappears
const table = el;
table._sortable = createSortable(table.querySelector("tbody"), binding.value, vnode);
Link to working fiddle
new Vue({
el: "#app",
directives: {
sortable: {
bind(el, binding, vnode) {
let self =el
Sortable.create(el.querySelector('tbody'),{
...binding.value,
vnode:vnode,
onEnd: (e) => {
let ids = el.querySelectorAll("span[id^=paper_]")
let order = []
for (let i = 0; i < ids.length; i++) {
let item = JSON.parse(ids[i].getAttribute('values'))
//extract items checkbox onChange v-model
let itemInThisData = vnode.context.items.filter(i => i.id==item.id)
order.push({
id:item.id,
paper: item.paper,
domain:item.domain,
platform: item.platform,
country:item.country,
sort_priority: item.sort_priority,
selectpaper:itemInThisData[0].selectpaper
})
}
binding.value = []
vnode.context.items = []
binding.value = order
vnode.context.items = order
console.table(vnode.context.items)
},
});
},
}
},
mounted() {
this.totalRows = this.items?this.items.length: 0
},
methods:{
onFiltered(filteredItems) {
// Trigger pagination to update the number of buttons/pages due to filtering
this.totalRows = filteredItems.length
this.currentPage = 1
},
log(){
console.table(this.items)
console.log(this)
},
},
data(){
return {
rankOption:'default',
totalRows: 1,
currentPage: 1,
filter: null,
filterOn:[],
sortBy:'paper',
sortDesc: false,
sortableOptions: {
chosenClass: 'is-selected'
},
perPage: this.results_per_page==='Todo' ? this.items.length : this.results_per_page?this.results_per_page:50,
pageOptions: [10, 50, 100, 500,'Todo'],
sortDirection: 'asc',
fields : [
{ key: 'paper', label: 'Soporte', sortable: true},
{ key: 'domain', label: 'Dominio', sortable: true},
{ key: 'platform', label: 'Medio', sortable: true},
{ key: 'country', label: 'País', sortable: true},
{ key: 'sort_priority', label: 'Rank', sortable: true},
{ key: 'selectpaper', label: 'Selección', sortable: true},
],
items : [
{
id:12,
paper: 'Expansion',
domain:'expansion.com',
platform: 'p',
country:'España',
sort_priority: '',
selectpaper:false
},
{
id:13,
paper: 'El economista',
domain:'eleconomista.es',
platform: 'p',
country:'España',
sort_priority: '',
selectpaper:false
},
{
id:14,
paper: 'El país',
domain:'elpais.es',
platform: 'p',
country:'España',
sort_priority: '',
selectpaper:false
}
]
}
}
})
<div id="app">
<template id="">
<b-table
:sort-by.sync="sortBy"
:sort-desc.sync="sortDesc"
v-sortable="items"
show-empty
small
stacked="md"
:items="items"
:fields="fields"
:current-page="currentPage"
:per-page="perPage"
:filter="filter"
:filterIncludedFields="filterOn"
:sort-direction="sortDirection"
#filtered="onFiltered"
>
<template v-slot:cell(selectpaper)="row">
<span :id="'paper_'+row.item.id" :values="JSON.stringify(row.item)"></span>
<b-form-group>
<input type="checkbox" #change="log" v-model="row.item.selectpaper" />
</b-form-group>
</template>
<template v-slot:cell(sort_priority)="row" v-if="rankOption==='foreach-row'">
<b-form-group>
<b-form-input type="number" #change="log"
size="sm" placeholder="Rank" v-model="row.item.sort_priority">
</b-form-input>
</b-form-group>
</template>
</b-table>
</template>
</div>
<script src="//unpkg.com/vue#latest/dist/vue.min.js"></script>
<script src="//unpkg.com/bootstrap-vue#latest/dist/bootstrap-vue.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/sortablejs#latest/Sortable.min.js"></script>