Loop inside modal Bootstrap Vue js - vue.js

I have a detail about an object inside my object fetched from the API. I would like to add a loop inside of the modal to show the details when I click.
data: function() {
return {
fields: [
{ key: 'customerOrderDelay', label: this.$t('metricsTable.column-name34'), sortable: true, class: 'text-center' },
{ key: 'supplierOrders', label: "suppllier order", sortable: true, class: 'text-center' },
{ key: 'actions', label: 'Actions' }
]
}
}
SupplierOrders is an object and I want to print the details with a loop inside the modal:
<b-modal :id="infoModal.id" :title="infoModal.item.orderAmount" ok-only #hide="resetInfoModal">
<!-- <pre>{{ infoModal.content }}</pre> -->
<div v-for="foo in infoModal.item.supplierOrders" ><md-card md-with-hover>
<md-ripple>
<md-card-header>
<div class="md-title">{{foo.supplierOrderNumber}}</div>
<div class="md-subhead">{{foo.supplierName}}</div>
</md-card-header>
<md-card-content>
{{foo.sectionName}}
</md-card-content>
<md-card-actions>
</md-card-actions>
</md-ripple>
</md-card>
the table :
<b-table
:tbody-tr-class="rowClass"
:busy="isBusy"
responsive="true"
:sticky-header="stickyHeader"
small
:items="totalOrders"
:fields="fields"
:per-page="300"
:filterIncludedFields="filterOn"
:sort-by="sortBy"
#sort-changed="sortTable"
>
It seems that I cannot access the object inside the object used by bootstrap-vue's table: Does anyone know how to override it?

Related

How to remove active classes from all buttons before making another one active?

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>

How can I modify style of Vue stacked b-table?

I used stacked b-table in bootstrap-vue.
<b-modal :id="infoModal.id" :title="infoModal.title" hide-footer #hide="resetInfoModal;">
<pre>
<b-table stacked sticky-header head-variant="light" :items="infoModal.content" :fields="reviewFields"></b-table>
</pre>
<template>
<div class="overflow-auto">
<b-pagination-nav :link-gen="linkGen" :number-of-pages="10" use-router></b-pagination-nav>
</div>
</template>
</b-modal>
this is result:
First, I want to move the marked baseline to the left.
Second, content in the table exceeds the outline (red line) of the table. I want the content to be scrollable within a fixed column of the table.
How can I get these effects?
You could set style on each columns
reviewFields: [
{ key: 'key0', label: 'label0', class: 'css-class' },
{ key: 'key1', label: 'label1', class: 'css-class' },
{ key: 'key2', label: 'label2', class: 'css-class' },
{ key: 'key3', label: 'label3', class: 'css-class' },
{ key: 'key4', label: 'label4', class: 'css-class' },
]

Vue: add multiple classes inside a v-for, based on array

I need to add classes to an element, based on categories. Here is my example data:
data() {
return {
projects: [
{
title: 'Project 1',
categories: [{ name: 'featured' }, { name: 'category-1' }],
},
{
title: 'Project 2',
categories: [{ name: 'category-2' }],
},
],
};
},
What I need is to add the categories directly as classes on the wrapper div (with the v-for), that will render:
<div class="featured category-1">
<h3>Project 1</h3>
</div>
<div class="category-2">
<h3>Project 1</h3>
</div>
I'm not sure how to do this?
<div v-for="(project, index) in projects" :class="v-for="(category, index) in project.categories???">
{{project.title}}
</div>
Should I do this differently? I can't seem to figure it out. Thanks for your help!
It's simple:
<div v-for="project in projects" :class="classExtraction(project)">
<h3>
{{project.title}}
</h3>
</div>
You need a method that extracts classes from your project's categories:
methods: {
classExtraction(item) {
return item.categories.map(cat => cat.name);
}
}
http://jsfiddle.net/eywraw8t/371192/
Also, please note that you should use :key directive with v-for binding it to a unique property, preferably object's id:
https://v2.vuejs.org/v2/style-guide/#Keyed-v-for-essential

vuejs semantic ui - drop down not displaying on arrow click

I'm faced with an issue where my semantic drop down in my vue project won't activate when clicking on the arrow icon but works when I click on the rest of the element. The drop down also works when I set the dropdown to activate on hover, but just not on click. Solutions I've tried:
tested if the dynamic id are at fault
tested if the back ticks are confusing things
placed the values directly into the semantic drop down
Aside from the dropdown not activating, the code below works as intended and brings back the selected value to the parent component and can be displayed.
Dropdown.vue:
<template>
<div class="ui selection dropdown" :id="`drop_${dropDownId}`">
<input type="hidden" name="gender" v-model="selected">
<i class="dropdown icon"></i>
<div class="default text">Gender</div>
<div class="menu">
<div class="item" v-for="option in options" v-bind:data-value="option.value">
{{ option.text }}
</div>
</div>
</div>
</template>
<script>
export default {
data: function () {
return {
selected: {}
}
},
watch: {
selected: function (){
this.$emit("dropDownChanged", this.selected)
}
},
props: {
options: Array, //[{text, value}]
dropDownId: String
},
mounted () {
let vm = this;
$(`#drop_${vm.dropDownId}`).dropdown({
onChange: function (value, text, $selectedItem) {
vm.selected = value;
},
forceSelection: false,
selectOnKeydown: false,
showOnFocus: false,
on: "click"
});
}
}
</script>
The component usage:
<vue-drop-down :options="dropDownOptions" dropDownId="drop1" #dropDownChanged="dropDownSelectedValue = $event"></vue-drop-down>
The data in the parent:
dropDownOptions: [
{ text: 'One', value: 'A' },
{ text: 'Two', value: 'B' },
{ text: 'Three', value: 'C' }
],
dropDownSelectedValue: ""
Here is a fiddle of the above but simplified to use a flatter project. However the problem doesn't reproduce :(
https://jsfiddle.net/eywraw8t/210520/
I'm not sure what is causing your issue (as the examples on the Semantic Ui website look similar), but there is a workaround. For you arrow icon:
<i #click="toggleDropDownVisibility" class="dropdown icon"></i>
And then in the methods section of your Vue component:
methods: {
toggleDropDownVisibility () {
$(`#drop_${this.dropDownId}`)
.dropdown('toggle');
}
},

How to trigger methods on created() instead of v-on:click for tags with conditions?

With the code bellow I'm displaying an element's info on click.
Right now when I click an element on the page it gets all the details about this object using this method:
<div #click="getFolderDetails(props.item)>
...
</div>
The question is, how do I get that data (run the method) not on #click but when the element is loaded (on created())?
Method:
getFolderDetails (value) {
this.objectTypeClicked = 'folder'
this.folderDetails = [
{title: "name", value: value.name},
{title: "type", value: "folder"},
{title: "created", value: this.$options.filters.prettyDateTime(value.stat.birthtime)},
{title: "modified", value: this.$options.filters.prettyDateTime(value.stat.mtime)},
{title: "path", value: value.path}
]
}
Then it displays it within other elements on the page:
<!-- display folder image if clicked has property value "folder" -->
<div v-if="objectTypeClicked == 'folder'">
<img src="/static/folder.png" alt="">
</div>
...
<!-- display specified properties of the clicked object -->
<div v-if="objectTypeClicked == 'folder'">
<div v-for="n in folderDetails" :key="n.id">
<h2 v-if="n.title == 'name'">{{n.value}}</h2>
<h3 v-if="n.value == 'folder'">folder</h3>
</div>
</div>
...
<!-- display only some of the values of the clicked object (cut off the first 2) -->
<div v-if="objectTypeClicked == 'folder'">
<div v-for="(i, index) in folderDetails" :key="index.id">
<h3 v-if="index > 1">
{{i.title}} - {{i.value}}
</h3>
</div>
</div>
Computed (takes data from store):
folderDetails: {
get () {
return this.$store.state.Info.folderDetails
},
set (value) {
this.$store.commit('loadFolderDetails', value)
}
},
objectTypeClicked: {
get () {
return this.$store.state.Info.objectTypeClicked
},
set (value) {
this.$store.commit('getObjectTypeClicked', value)
}
}
I know the code is far from optimal, but I'm still learning Vue.
I would suggest to use a computed for this. Use the method to change the folder you want to display, let's say currentFolder and assign a default on mount, like folderDetails[0], directly in the computed if this.currentFolder is null.
The computed would look like:
folderDetails() {
let value = this.folderDetails[0];
if (this.currentFolder != null) {
value = this.currentFolder;
}
return [
{title: "name", value: value.name},
{title: "type", value: "folder"},
{title: "created", value: this.$options.filters.prettyDateTime(value.stat.birthtime)},
{title: "modified", value: this.$options.filters.prettyDateTime(value.stat.mtime)},
{title: "path", value: value.path}
]
}
and the method to set on click it would become
getFolderDetails (value) {
this.objectTypeClicked = 'folder';
this.currentFolder = value;
}
In general, I always prefer to set a default state of the loaded component so that everything "works" from start.