Vue.js/Vuetify: How can I make the v-card-actions reactive? - vue.js

I have 4 cards (3 in the first row, 1 in second). Every time I resize my browser window my v-card-actions contents do not react. In pictures, this is when everything is ok:
And this is when I resize my browser window:
And finally here's my code:
.vue
<v-container
grid-list-lg
>
<v-layout
row
wrap
>
<v-flex
v-for="teacher in teachers"
:key="teacher.firstName"
md-4
xs4
>
<v-card
flat
tile
>
<v-img
:src='teacher.src'"
height="260px"
></v-img>
<v-card-title
primary-title
class='blue--text'
>
Dr. {{teacher.firstName}} {{teacher.lastName}}, {{teacher.specialty}}
</v-card-title>
<v-card-text class='body-1'>
M.S at {{teacher.ms}} <br>
M.S.C at {{teacher.msc}}
</v-card-text>
<v-card-actions>
<v-btn
flat
small
color='indigo darken-4'
>
More
</v-btn>
<v-spacer></v-spacer>
<v-btn
flat
small
color='indigo darken-4'
>
Schedule an Appointment
</v-btn>
</v-card-actions>
</v-card>
</v-flex>
</v-layout>
</v-container>
<script>
data() {
return {
teachers:[
{firstName:'Jon', lastName:'Doe', specialty:'PE', ms:' University of Georgia',
msc:'University of Georgia', src:'https://source.unsplash.com/kmuch3JGPUM'},
{firstName:'Maria', lastName:'Doe', specialty:'Philology', ms:'University of Atlanta',
msc:'University of Atlanta ', src:'https://randomuser.me/api/portraits/women/3.jpg'},
{firstName:'Jon', lastName:'Jon', specialty:'Mathematics', ms:'University of Michigan',
msc:'University of Michigan', src:'https://source.unsplash.com/Jy4ELSGPHTc'},
{firstName:'Peter', lastName:'Xavier', specialty:'Mathematics',
ms:'University of Miami', msc:'University of Miami',
src:'https://randomuser.me/api/portraits/men/71.jpg'},
{firstName:'Peter', lastName:'Miros', specialty:'Mathematics', ms:'University of Miami',
msc:'Georgetown University', src:'https://randomuser.me/api/portraits/men/20.jpg'},
}
]
}

The <v-card-actions> element does react to browser width changes.
What you are seeing is an issue with the Vuetify <v-button> element as it does not (by default) wrap text to fit.
You have a few options:
Add custom CSS for your buttons to accommodate - tricky and a bit too much hacking for my liking.
Make your own button element just for this - seems overkill, but I've done this when I also want a button to stand out or look different enough to Vuetify's standard.
Modify your button text to be shorter - Try one word like "Booking" or "Appointments", and even modify the text (or change to an icon) depending on screen size if you want to get fancy.
Personally, I'd recommend option 3.
EDIT: Added xs12 sm6 md4 sizing and some minor formatting changes to highlight different elements
<v-container grid-list-lg>
<v-layout row wrap>
<v-flex v-for="teacher in teachers" :key="teacher.firstName" xs12 sm6 md4>
<v-card>
<v-img :src="teacher.src" height="260px "></v-img>
<v-card-title primary-title class='blue--text'>
Dr. {{teacher.firstName}} {{teacher.lastName}}, {{teacher.specialty}}
</v-card-title>
<v-card-text class='body-1'>
M.S at {{teacher.ms}} <br> M.S.C at {{teacher.msc}}
</v-card-text>
<v-card-actions>
<v-btn outline color='blue'>
More...
</v-btn>
<v-spacer></v-spacer>
<v-btn outline color='green'>
Appointments
</v-btn>
</v-card-actions>
</v-card>
</v-flex>
</v-layout>
</v-container>
I have tested this and there is no size below 300px (minimum for v-card) where the buttons don't look fine.
Made a codepen for you too.

Related

Modify the size of the signup button

This is a form for logging in. As noted in the black screen, the registration button is small. The question is how can I make the registration button as large as in the white image
This is part of the code for the record button
Register.vue:
<v-layout row>
<v-flex xs12>
<v-btn class="red accent-4 margine color myfont">
Sign up
</v-btn>
</v-flex>
</v-layout>
If you check the Vuetify documentation, you'll find, that in order for the button to extend the full width of its container, you give it the block property.
Like such:
<v-btn class="red accent-4 margine color myfont" block>
Sign up
</v-btn>
You'll find it all in the vuetify documentation

Adding Routes to Vuetify Buttons within v-cards?

This should be a simple fix but not sure where to start.
I have..
<template>
<div class="mx-5 mb-5 Weapons">
<h1 class="green--text">Weapons</h1>
<v-container class="my-5">
<v-layout row wrap>
<v-flex xs12 s6 m4 lg3 v-for="weapon in assaultrifles" :key="weapon.weapontype">
<v-card class="text-md-center ma-3 black">
<v-responsive class="pt-4">
<v-img contain :src="weapon.images"></v-img>
</v-responsive>
<v-card-title class="justify-center">
<div class="heading font-weight-black white--text">{{ weapon.WeaponType}}</div>
</v-card-title>
<v-card-actions class="justify-center">
<v-btn flat class="green black--text ma-3">View Weapons</v-btn>
</v-card-actions>
</v-card>
</v-flex>
</v-layout>
</v-container>
</div>
</template>
I then have data in arrays with images and "titles" for these cards. I have about 8 cards , each representing its own "category" which is represented by the "title" data in my array.
What I am trying to do is make it so if I click on a card with the category/title "Handgun" or click on a card "rifle", I will be routed to a new page where I list out items for that specific category.. however I am not sure where to start because I am simply passing {{weapon.WeaponType}} into 1 card object, and then using 1 button ( with the text "view weapon"), across all the cards.
My understanding is that if I make a route for the 1 button I made, then the route will be the same for all buttons, despite the cards representing its own category, which would be bad because I don't want to see "handguns" when I click on the "shotgun" card’s button.
I want to somehow keep my current structure ( using 1 object and passing a loop of data ) and 1 btn, so that my code stays around the same length/structure).
Thanks for reading.
You will need additional property in your objects - for the route of the button:
<v-btn
flat
class="green black--text ma-3"
:to="weapon.route"
>
View Weapons
</v-btn>
The weapon.route can be a string or an object.
Another option is to provide just the category IDs and then
<v-btn
flat
class="green black--text ma-3"
:to="{name: 'weaponItems', params: {categoryID: weapon.categoryID}}"
>
View Weapons
</v-btn>

Unable to add template text to v-textarea with Vue and Vuetify

I have inherited an existing app written in Vue/Vuetify and it has an existing v-textarea element that I am trying to modify. The issue is that we now want to pre-populate this element with sample text that the user can edit to their needs. I have tried adding value and placeholder properties to the v-textarea element and not gotten the sample text to show in the v-textarea.
Here is the dialog that contains the troublesome v-textarea:
<v-dialog v-model="dialogAddComment"
hide-overlay
persistent
max-width="600px">
<v-toolbar card color="blue-grey lighten-4" dense elevation="16">
<v-toolbar-title color='black' class="body-2 ml-3">Add Comment</v-toolbar-title>
<v-spacer></v-spacer>
<v-icon #click.stop="closeDialogAddComment">close</v-icon>
</v-toolbar>
<v-form ref="form" v-model="valid" lazy-validation>
<v-card>
<v-flex>
<v-layout column>
<v-flex xs12 sm6 d-flex mx-3>
<v-select
:items="engagement.allIncidentTypes"
item-text="incidentCategoryText"
item-value="incidentCategoryKey"
label="Category"
:rules="[v => !!v || 'Category is required']"
required
v-model="incident.incidentCategoryKey"
></v-select>
</v-flex>
<v-flex xs12 sm6 d-flex mx-3>
<v-select
:items="zeroTo8"
label="Impact (Hours)"
:rules="[v => (v === 0 || v <9) || 'Impact is required']"
required
v-model="incident.numberOfHours"
></v-select>
</v-flex>
<v-flex xs12 sm6 d-flex mx-3>
<v-textarea
name="input-7-1"
label="Comment"
:rules="[v => !!v || 'Comment is required']"
required
v-model="incident.incidentFreeText"
counter=1024
maxLength=1024
rows=3
value='U Good lockers\nV Damaged lockers\nW Lockers replaced\nX (=U+V+W) Lockers installed\nY Lockers returned to warehouse'
></v-textarea>
<!-- -->
</v-flex>
</v-layout>
</v-flex>
<v-card-actions>
<v-spacer/>
<v-btn :disabled="!valid" color="primary" small #click="addIncident">Submit</v-btn>
<v-spacer/>
</v-card-actions>
</v-card>
</v-form>
</v-dialog>
I have tried setting the placeholder and value properties and seen nothing. I initially tried setting a text property but then found the documentation on the vuetify.js site. They even have a simple example that does exactly what I want to do. But my implementation is not working. and I am stumpped!
You should not set both v-model and value at the same time.
One possible solution is removing v-model and update incident.incidentFreeText in #input event
<v-textarea
name="input-7-1"
label="Comment"
:rules="[v => !!v || 'Comment is required']"
required
counter=1024
maxLength=1024
rows=3
value='U Good lockers\nV Damaged lockers\nW Lockers replaced\nX (=U+V+W) Lockers installed\nY Lockers returned to warehouse'
#input="onInput"
>
</v-textarea>
methods: {
onInput(value) {
this.incident.incidentFreeText = value
}
}
Another possible solution is keeping v-model, remove value, but you need to set
this.incident.incidentFreeText='U Good lockers\nV Damaged lockers\nW Lockers replaced\nX (=U+V+W) Lockers installed\nY Lockers returned to warehouse'
somewhere in your code.

Vuetify v-flex offset-*(1-12) not working properly

I am using Vuetify 1.5.0 at time of writing this. But when ever I am trying to use offset for any breakpoint on v-flex, its adding offset on that breakpoint and up for Example in this case it is adding offset on md and up as well . Below is my code. Please what am i doing wrong here and how can correct this.
<v-container class="teal">
<v-layout row wrap class="red">
<v-flex sm12 md8 lg7 offset-md2 class="blue">
<h1>Hello</h1>
</v-flex>
<v-flex sm12 md8 lg5 offset-md2 class="orange">
<h1>Hello Hi</h1>
</v-flex>
</v-layout>
</v-container>
And is the screenshot taken on lg screen.
as you can see, its wrapping column in new line even though it should not.
Thanks,
Amit
The offset-md2 being applied on md and up is expected behaviour if you don't specify any "upper" offset (like offset-lg*). Likewise when you specify sm8 (for small) and don't specify any md* or lg*, the sm8 would be applied for sm and up.
If you want to ignore the offsets on a large screen, you could use offset-lg0, like so:
<v-container class="teal">
<v-layout row wrap class="red">
<v-flex sm12 md8 lg7 offset-md2 offset-lg0 class="blue">
<h1>Hello</h1>
</v-flex>
<v-flex sm12 md8 lg5 offset-md2 offset-lg0 class="orange">
<h1>Hello Hi</h1>
</v-flex>
</v-layout>
</v-container>

How to display card components in loop with Vuetify grid system?

Note: Using Vue.js and Vuetify.js for functionality and styling
I have card components dynamically generated with v-for, and I want to display them in 1/3/4 card(s) in a row depending on screen size (sm/md/lg). When I place them in Vuetify's grid system, with v-flex and v-layout elements, the cards are minimized, instead of moving to the second row.
Is there another way to go about this?
<v-content>
<v-card class="d-inline-flex" v-for="company of companies" :key="company.name">
<v-layout >
<v-flex md6 lg6>
<img class="company-logo" src="../assets/img/example-logo.png" alt="company logo">
</v-flex>
<v-flex md6 lg6>
<v-card-title class="headline pl-0">{{company.name}}</v-card-title>
<article class="text-md-left text-lg-left">
<v-btn #click="selectDashboard(href('stats', company.name))" :value="company.name"><v-icon>local_offer</v-icon></v-btn>
<v-btn #click="selectDashboard(href('process', company.name))" :value="company.name"><v-icon>notifications</v-icon></v-btn>
<v-btn #click="selectDashboard(href('example', company.name))" :value="company.name"><v-icon>rate_review</v-icon></v-btn>
<v-btn #click="selectDashboard(href('alerts', company.name))" :value="company.name"><v-icon>explore</v-icon></v-btn>
<v-btn #click="selectDashboard(href('profile', company.name))" :value="company.name"><v-icon>room</v-icon></v-btn>
</article>
</v-flex>
</v-layout>
</v-card>
</v-content>
For a visual, this codepen shows the images width size decreases (but height size stays the same) - https://codepen.io/johnjleider/pen/aLXBez?editors=1111
The accepted answer did not work for me with v2 of Vuetify.
Now we can use <v-col> and you would do something like below.
<v-row>
<v-col cols="12" sm="3" md="4" v-for="(something, index) in somethingsArray" :key="index" >
<my-component :my-data="something" />
</v-col>
</v-row>
Where cols="12" is the same as xs="12" and the column would take up the full 12 spaces.
The sizing scales up starting with the smallest screens. Then on small screens each column would take up 4 spaces resulting in 3 columns and then for medium and larger screens use 3 spaces resulting in 4 columns.
|__|__|__|__|__|__|__|__|__|__|__|__| 12 spaces in the grid
|-----------------------------------| <-cols=12 (1 column)
|--------|--------|--------|--------| <-sm=3 (4 columns)
|-----------|-----------|-----------| <-md=4 and larger (3 columns)
The <v-flex> grid maxes out at 12. So if you set xs12 (extra small breakpoint) on the <v-flex xs12> it will take up all of the grid width until it hits the next breakpoint (If you don't set another breakpoint the lowest one will be applied to all screen widths). So then set <v-flex xs12 md6>, now when you hit the medium breakpoint each card will take up 6 grid spaces, which will allow you to have 2 cards side by side. Setting lg3, will allow you to fit 4 cards in the same space.
You can see it working in this modification to your example
https://codepen.io/twandy/pen/JrxamB?editors=1001