Hi everyone I'm doing this project where I'm going to store data into a table. The data itself is from a backend server with different table which have a different field name but meant to be stored in one same column on the front-end.
The first data will be like:
{
student_name: "John Doe",
birthday: "Aug, 4 2008"
}
And the second data will be like:
{
name: "Jane Doe",
birthday: "Dec, 25 2003"
}
and this is the code I tried but obviously didn't work:
<template>
<b-table>
<template v-slot:cell(name)=data items="student_data" :fields="fields">
<div class="text-truncate" style="max-width: 150px;">
{{data.name}}
</div>
</template>
</b-table>
</template>
<script>
export default {
data(){
return {
student_data: [
{
student_name: "John Doe",
birthday: "Aug, 4 2008"
},
{
name: "Jane Doe",
birthday: "Dec, 25 2003"
},
],
fields: [
{
key: "no",
label: "No",
sortable: false
},
{
key: ["student_name", "name"],
label: "Name",
sortable: true
},
{
key: "birthday",
label: "Birthday",
sortable: true
},
]
}
}
}
</script>
How can I put both John doe and Jane Doe in one same column with their different field name? Thanks in advance
You can simply achieve it by just iterating the array in mounted() hook and making the Object keys with same name.
Live Demo :
new Vue({
el: '#app',
data: {
items: [
{
student_name: "John Doe",
birthday: "Aug, 4 2008"
},
{
name: "Jane Doe",
birthday: "Dec, 25 2003"
}
]
},
mounted() {
this.items.forEach(obj => {
if (obj.hasOwnProperty('name')) {
obj['student_name'] = obj['name'];
delete obj['name'];
}
})
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap-vue#2.0.0-rc.11/dist/bootstrap-vue.common.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.2/css/bootstrap.css"/>
<div id="app">
<b-container class="mt-2">
<template>
<div>
<b-table striped hover :items="items"></b-table>
</div>
</template>
</b-container>
</div>
Related
I'm new to vue, I still don't understand everything, tell me. I have buttons that I display through v-for, I need to get the active class of only one button when pressed, all the others need to be turned off, tell me, preferably visually, how can I do it better?
I am using the method activeBtn, but this doesn't turn off the active class from the previous buttons
activeBtn(event, index) {
this.buttons[index].isActive = !this.buttons[index].isActive;
<script>
data() {
return {
buttons: [
{
label: "A",
isActive: false,
type: "border-left",
name: "BorderLeftComonent",
},
{
label: "A",
isActive: false,
type: "text-balloon",
name: "TextBalloonComponent"
},
{
label: "A",
isActive: false,
type: "dashed",
name: "DashedComponent"
},
],
};
},
methods: {
activeBtn(event, index) {
this.buttons[index].isActive = !this.buttons[index].isActive;
}
</script>
<template>
<div id="btn-box">
<button
v-for="(button, index) in buttons"
:key="index"
:class="button.isActive ? 'on' : 'off'"
#click="component = button.name, activeBtn($event, index)">
<div :class="`btn btn-${button.type}`">{{ button.label }}</div>
</button>
</div>
</template>
Since you only want to get one active button at any one point, it doesn't make sense to manage the active state inside each button.
Instead, you should manage it at group level by storing the currently selected button's id. A button would then be active when its id matches the currently selected id.
Here's an example:
new Vue({
el: '#app',
data: () => ({
buttons: [
{
id: "button-1",
label: "A",
type: "border-left",
name: "BorderLeftComonent"
},
{
id: "button-2",
label: "A",
type: "text-balloon",
name: "TextBalloonComponent"
},
{
id: "button-3",
label: "A",
type: "dashed",
name: "DashedComponent"
}
],
activeButtonId: "button-1"
}),
methods: {
activate(id) {
this.activeButtonId = id;
}
}
})
.on {
background-color: red
}
.off {
background-color: blue
}
.on, .off {
color: white
}
<script src="https://unpkg.com/vue#2/dist/vue.min.js"></script>
<div id="app">
<div>
<button
v-for="{id, type, label} in buttons"
:key="id"
:class="activeButtonId === id ? 'on' : 'off'"
#click="activate(id)"
>
<div :class="`btn btn-${type}`" v-text="label" />
</button>
</div>
</div>
I am facing an issue where I need to display one select field two times in the form and while saving the form it will save the data in an array.
What I have done is created a form and added a select form and I want it to display two times (two select form) and it will be able to select different values for two select displays
I have created a sandbox here
Any ideas are much appreciated.
You could create new variable to second value with same options as first select input and save it as array.
<template>
<div>
<b-form-select
class="mb-2 mr-sm-2 mb-sm-0"
:options="optQuality"
v-model="slcQuality"
#input="changeQuality"
>
</b-form-select>
<div>slcQuality: {{ slcQuality }}</div>
<b-form-select
class="mb-2 mr-sm-2 mb-sm-0"
:options="optQuality"
v-model="slcQuality2"
#input="changeQuality"
>
</b-form-select>
<div>slcQuality: {{ slcQuality2 }}</div>
<div>
<button #click="submit">Submit</button>
</div>
<div>submitted Data: {{ JSON.stringify(submittedData) }}</div>
</div>
</template>
<script>
export default {
data() {
return {
optQuality: [
{ value: 1, text: "Original" },
{ value: 2, text: "Kw-1" },
{ value: 3, text: "Kw-2" },
],
slcQuality: null,
slcQuality2: null, // new variable
submittedData: [],
};
},
methods: {
changeQuality() {
console.log("test");
console.log(this.slcQuality);
},
submit() {
const data = [this.slcQuality, this.slcQuality2]; //save data as array
this.submittedData = data;
console.log(data);
},
},
};
</script>
EDIT
To avoid massive code you could use an array of objects as variable or nested array like this, then loop twice in template (nested v-for).
<template>
<div>
<div v-for="(quality, i) in slcQualities" :key="i">
<div v-for="(selection, j) in quality.values" :key="j">
<div>{{ selection.name }}</div>
<b-form-select
class="mb-2 mr-sm-2 mb-sm-0"
:options="quality.options"
v-model="selection.value"
#input="changeQuality"
/>
<div>slcQuality: {{ quality.value }}</div>
</div>
</div>
<div>
<button #click="submit">Submit</button>
</div>
<div>submitted Data: {{ JSON.stringify(submittedData) }}</div>
</div>
</template>
<script>
// array of data
const qualities = [
{
options: [
{ value: 1, text: "Original" },
{ value: 2, text: "Kw-1" },
{ value: 3, text: "Kw-2" },
],
values: [
{ name: "Select 1-1", value: null },
{ name: "Select 1-2", value: null },
],
},
{
options: [
{ value: 1, text: "Original" },
{ value: 2, text: "Kw-3" },
{ value: 3, text: "Kw-4" },
],
values: [
{ name: "Select 2-1", value: null },
{ name: "Select 2-2", value: null },
],
},
];
export default {
data() {
return {
slcQualities: qualities,
submittedData: [],
};
},
methods: {
changeQuality() {
console.log("test");
console.log(this.slcQuality);
},
submit() {
const data = this.slcQualities.map((i) => i.values.map((j) => j.value)); //map the values
this.submittedData = data;
console.log(data);
},
},
};
</script>
Here's the sandbox
Is there a way to sort a v-data-table by the selection column?
I would like to multisort my v-data-table. First by selection, so the selected ones are always on top and second by name. So far I got this:
<template>
<v-app>
<div id="app">
<v-data-table
:headers="tableHeaders"
:items="selectables"
:show-select="true"
:sort-by="['isSelected', 'name']"
multi-sort
v-model="output"
return-object
>
</v-data-table>
</div>
</v-app>
</template>
<script>
export default {
data() {
return {
output: {},
tableHeaders: [
{
text: "name",
value: "name",
},
],
selectables: [
{
name: "toni",
},
{
name: "hans",
},
{
name: "fritz",
},
],
};
},
};
</script>
I have an option array which is shown in the multi-select options. But I need to select a default option which id is provided. In my code I need to select the default option which id = 2 . How to do that with multi-select in vue.js?
<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/vue-multiselect#2.1.0"></script>
<link rel="stylesheet" href="https://unpkg.com/vue-multiselect#2.1.0/dist/vue-multiselect.min.css">
<div id="vue-app2">
<div>
<label class="typo__label">Single select / dropdown</label>
<multiselect v-model="value" deselect-label="Can't remove this value" track-by="id" label="name"
placeholder="Select one" :options="options" :searchable="false" :allow-empty="false">
<template slot="singleLabel" slot-scope="{ option }"><strong>{{ option.name }}</strong> is written
in<strong> {{ option.language }}</strong></template>
</multiselect>
<pre class="language-json"><code>{{ value }}</code></pre>
</div>
</div>
<script >
Vue.component('multiselect', window.VueMultiselect.default);
new Vue({
el: '#vue-app2',
data: {
id:2,
value:null,
options: [
{ id:1, name: 'Vue.js', language: 'JavaScript' },
{ id:2, name: 'Rails', language: 'Ruby' },
{ id:3,name: 'Sinatra', language: 'Ruby' },
{ id:4,name: 'Laravel', language: 'PHP', $isDisabled: true },
{ id:5,name: 'Phoenix', language: 'Elixir' }
]
}
});
</script>
If you need to take default value id from data then find and set default value on mounted;
new Vue({
el: '#vue-app2',
data: {
id: 2,
value: null,
options: [
{ id: 1, name: 'Vue.js', language: 'JavaScript' },
{ id: 2, name: 'Rails', language: 'Ruby' },
{ id: 3, name: 'Sinatra', language: 'Ruby' },
{ id: 4, name: 'Laravel', language: 'PHP', $isDisabled: true },
{ id: 5, name: 'Phoenix', language: 'Elixir' }
]
},
mounted() {
this.value = this.options.find(option => option.id === this.id);
}
});
Suppose I want to display a List of Questions. For each question, there is a list of answers, none of which are right or wrong. For each question, the user can choose an answer. I'm wondering how to create two-way binding on the selected answer.
The Vue:
new Vue(
{
el: "#app",
data:
{
questions: [{}]
}
}
Example Question Model:
{
id: 1,
name: "Which color is your favorite?",
selectedAnswerId: null,
selectedAnswerName: null,
answers:
[
{id: 1, name: red, photoUrl: ".../red", selected: false},
{id: 2, name: green, photoUrl: ".../green", selected: false},
{id: 3, name: blue, photoUrl: ".../blue", selected: false},
]
}
Components:
var myAnswer =
{
props: ["id", "name", "url", "selected"],
template:
`
<div class="answer" v-bind:class="{selected: selected}">
<img class="answer-photo" v-bind:src="url">
<div class="answer-name">{{name}}</div>
</div>
`
};
Vue.component("my-question",
{
props: ["id", "name", "answers"],
components:
{
"my-answer": myAnswer
},
template:
`
<div class ="question">
<div class="question-name">{{name}}</div>
<div class="question-answers">
<my-answer v-for="answer in answers" v-bind:id="answer.id" v-bind:name="answer.name" v-bind:url="answer.photoUrl" v-bind:selected="answer.selected"></my-answer>
</div>
</div>
`
});
When the user selects an answer to a question by clicking on the div, I want the Question model's selectedAnswerId/selectedAnswerName along with the answers selected property to be set accordingly. Therefore, what do I need to add to my components in order to accomplish this two-way binding? I believe it requires input elements and v-model, but I couldn't quite figure it out. Also, I am only one day into Vue.js and have no experience with related frameworks. So if I am doing anything blatantly wrong or against best practice, that would be good to know as well. Thanks in advance!
The answer will handle a click event and emit a (custom) selected-answer event. The question will have its own data item to store the selected answer ID; the answer component's selected prop will be based on that. The question will handle the selected-answer event by setting its selectedId.
var myAnswer = {
props: ["id", "name", "url", "selected"],
template: `
<div class="answer" v-bind:class="{selected: selected}"
#click="setSelection()"
>
<img class="answer-photo" :src="url">
<div class="answer-name">{{name}}</div>
</div>
`,
methods: {
setSelection() {
this.$emit('selected-answer', this.id);
}
}
};
Vue.component("my-question", {
props: ["id", "name", "answers"],
data() {
return {
selectedId: null
};
},
components: {
"my-answer": myAnswer
},
template: `
<div class ="question">
<div class="question-name">{{name}}</div>
<div class="question-answers">
<my-answer v-for="answer in answers"
:id="answer.id" :name="answer.name" :url="answer.photoUrl"
:selected="answer.id === selectedId" #selected-answer="selectAnswer"></my-answer>
</div>
</div>
`,
methods: {
selectAnswer(answerId) {
this.selectedId = answerId;
}
}
});
new Vue({
el: '#app',
data: {
questions: [{
id: 1,
name: "Which color is your favorite?",
answers: [{
id: 1,
name: 'red',
photoUrl: ".../red"
},
{
id: 2,
name: 'green',
photoUrl: ".../green"
},
{
id: 3,
name: 'blue',
photoUrl: ".../blue"
},
]
}]
}
});
.answer {
cursor: pointer;
}
.selected {
background-color: #f0f0f0;
}
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.2.6/vue.min.js"></script>
<div id="app">
<my-question v-for="q in questions" :name="q.name" :answers="q.answers"></my-question>
</div>