Sort Array by Child Computed Property in Vue - sorting

I'm using Vue to display a list of search results for flights. When a user searches for flights I get flightData which I pass certain data to the components as props. Within the component, I use computed properties to get a totalPrice.
I'd like to sort the components on the parent page by this totalPrice but I'm not sure how to access this information...
// index.vue
<v-flex v-for="flight in filteredFlights" :key="flight.id" xs10 offset-xs1 class="my-2">
<Flights
:id="flight.id"
:price="flight.price"
:flyFrom="flight.flyFrom"
:flyTo="flight.flyTo"
:flyDuration="flight.fly_duration"
:returnDuration="flight.return_duration"
:routes="flight.route"
/>
</v-flex>
computed: {
filteredFlights() {
// right now this only sorts by price, not the totalPrice in the components
return this.flightData.sort((a, b) => b.price - a.price);
}
},
// Flight Component
<template>
<v-card hover id="flightCard" class="d-inline-flex pa-3 ma-2" :href="deeplink" target="_blank">
<v-flex xs12 sm3 class="ml-3 mt-3">
<v-layout column fill-height>
<v-flex class="title">
${{price}}
<span class="caption">Flights</span>
</v-flex>
<v-flex class="title">
${{fees}}
<span class="caption">Fees</span>
</v-flex>
<v-divider></v-divider>
<v-flex class="display-1 mt-2">
${{totalPrice}}
</v-flex>
</v-layout>
</v-flex>
</v-card>
</template>
computed: {
fees() {
let totalFee = 0;
// code to get fees
return totalFee
},
totalPrice() {
return this.price + this.fees;
}
},

I see a couple of ways of handling this.
Compute totalFees in the parent component and then feed this via props to the children. This seems the fastest way
Compute totalFees in children as now, fire and event via emit. Listen for the event on the parent and add totalFees to the correct index in flightData. The emitted event should also pass flight.id so you know what element to be updated.

Related

how to show multiple card in carousal

Could Any one help me...I want to show cards in a carousal.In the first carousal I want three cards to be show and the second carousal I want to show only two cards. my problem is that In first carousal and second carousal total cards are shows..
<v-flex>
<v-carousel hide-delimiters style="box-shadow: 0px 0px" prev-icon>
<v-carousel-item v-for="i in 2" :key="i">
<v-layout row>
<v-flex sm4 v-for="j in color" :key="j" pl-2 pr-2>
<v-card :color="j">
<v-card-title primary-title>
<div>
<h3 class="headline mb-0">Card {{i}}-{{j}}</h3>
<div> Card text </div>
</div>
</v-card-title>
</v-card>
</v-flex>
</v-layout>
</v-carousel-item>
</v-carousel>
</v-flex>
<script>
export default{
data(){
return{
color: ['red','orange','green','primary','error']
}
}
}
</script
Check this codesandbox I made: https://codesandbox.io/s/stack-70202529-v4251?file=/src/components/CarouselExample.vue
I assume that's because you're trying to generate the v-carousel-item with a v-for. Do you want to generate the v-card's dinamically? If so, you'll get the text from an array? If the cards will have static text you could simply create each carousel item manually.

Is it possible to sort Vuetify multiple selection on change?

I have a multiple selection Vue component that feeds items to display in an input box. As of now, it adds items based on the order of selection, but I wanted to template it to sort by sort_order after selection (objective_id, category_id, objective_code, objective_description, disabled_flag, sort_order are all passed into objectiveArray object). Is this possible to do in Vuetify?
<v-flex xs12>
<v-tooltip :disabled="!showTooltip" top>
<v-select
slot="activator"
class="objective-select"
v-model="record.objectives"
:items="objectiveArray"
label="Objective(s)"
placeholder="Enter Objective(s)"
:error-messages="objectiveErrors"
:return-object="true"
item-text="objectiveDescription"
multiple
#blur="v.$each[index].objectives.$touch()">
<template v-slot:selection="{ item, index }">
<v-chip
color="primary"
dark
class="objective-chip"
:class="{
mobile:isMobile,
tablet:isTablet
}">
<span>{{ item.objectiveDescription }}</span>
</v-chip>
</template>
</v-select>
<span>Select one or more procedure objective(s)</span>
</v-tooltip>
</v-flex>
You can sort your bound v-model after the #input event fires. Here is a simple example:
<template>
<div>
<v-select
v-model="selected"
:items="items"
item-text="id"
item-value="id"
multiple
#input="sortSelection"
return-object
>
</v-select>
</div>
</template>
<script>
export default {
data: () => ({
selected: [],
items: [{id:1},{id:2},{id:3},{id:4},{id:5},{id:6}]
}),
methods: {
sortSelection() {
this.selected.sort((x, y) => {
if (x.id > y.id) return 1
else if (y.id > x.id) return -1
else return 0
})
}
}
}
</script>
As long as your sort_order is a number you can just substitute it for the id field in my example.

Vuetify: add animation when updating grid size

My component separated to two parts (leftPanel and rightPanel).
When the app start, only leftPanel will be shown, and take up the whole screen width (using xs12).
If user click the button, the left panel will be shown, and rightPanel will resize to xs6 to take up half of the screen.
The functionality here is working well, but I would like to add animation(transition) when the panels size are changing.
I tried to add with different css, but none of them are showing animation.
<template>
<v-container grid-list-sm fluid>
<transition name="MyPanel">
<v-layout align-space-around row fill-height>
<v-flex id="leftPanel" :xs6="!showRightPanel" :xs12="showRightPanel">
<v-layout align-space-around column fill-height>
<v-flex xs12>
<v-btn v-if="extendable" #click="openRightPanel"> show more information </v-btn>
</v-flex>
</v-layout>
</v-flex>
<v-flex id="rightPanel" v-if="showRelatedCard" xs6>
<v-layout align-space-around column fill-height>
...
</v-layout>
</v-flex>
</v-layout>
</transition>
</v-container>
</template>
<script>
export default {
...
data() {
return {
showRightPanel : false
}
},
methods: {
removeLargeImage() {
this.showRightPanel = !this.showRightPanel;
}
}
};
</script>
<style scoped>
...
</style>
If you're using an v-if statement it is not possible to solve with CSS. As the element isn't rendered at all. Setting the width initially to 0 or using v-show you probably could solve it with CSS, but I would recommend to look to the vue-transitions: https://v2.vuejs.org/v2/guide/transitions.html
Maybe also to https://vuetifyjs.com/en/styles/transitions with I wonder if you could solve yout problem with the vuetify transitions

Vuetify : fixed blocks : left and right

In my application, the results page is composed of three blocks :
left : summary of the search
middle : results
right : map of the results
I don't know how to fix the position (position: fixed) of the left and right blocks with Vuetify.
My goal is to keep the left and right blocks displayed while scrolling the list of results (in the middle).
<v-content>
<v-container style="max-width:1264px" class="pa-0">
<v-layout row wrap>
<v-flex xs12 sm5 md3 class="">
<div style="background-color:red;color:white;height:300px">SEARCH FIXED</div>
</v-flex>
<v-flex xs12 sm7 md4 class="pt-3 pa-2 green">
RESULTS:<br/> ...
</v-flex>
<v-flex class="" xs12 md5>
<div style="background-color:blue;color:white;height:200px">MAP FIXED</div>
</v-flex>
</v-layout>
</v-container>
</v-content>
Here is the codepen of my application

Vuetify grid system. How to make block placed on rest of height?

How to I can make block "pink-box", placed on rest of height in Vuetify grid system? "height: 100%" work incorrect. Column flex direction and "flex: 1" break xs6 layout.
<div id="app">
<v-app>
<v-content>
<v-container grid-list-md fill-height>
<v-layout row wrap align-content-start>
<v-flex xs6 v-for="x in 10">Text: Example {{x}}</v-flex>
<v-flex xs12 class="pink-box">Rest height box</v-flex>
</v-layout>
</v-container>
</v-content>
</v-app>
</div>
See worked code snippet on Codepen:
https://codepen.io/profsoft/pen/wmQRvm
We must use in container two nested layouts.
First - column, for text block and rest height box.
Second, nested - row wrap, for correct 12 point grid system placed in text block.
<div id="app">
<v-app>
<v-content>
<v-container grid-list-md fill-height>
<v-layout column>
<v-flex>
<v-layout row wrap align-content-start>
<v-flex xs6 v-for="x in 10">Text: Example {{x}}</v-flex>
</v-layout>
</v-flex>
<v-flex xs12 class="pink-box">Rest height box</v-flex>
</v-layout>
</v-container>
</v-content>
</v-app>
</div>
See solution code snippet on Codepen:
https://codepen.io/profsoft/pen/KoLMrz

Resources