Vuetify: v-text-field with outlined don't display the border - vue.js

I use the Vuetify for Vuejs project. I add v-text-field elements to v-form with outlined property but it don't show the border. Thanks.
Code add Vuetify to project in main.js:
import Vuetify from 'vuetify/lib'
import 'vuetify/src/stylus/app.styl'
import 'vuetify/dist/vuetify.min.css'
import 'material-design-icons-iconfont/dist/material-design-icons.css'
Vue.use(Vuetify, {
iconfont: 'md',
});
Use in the register form:
<v-form #submit.prevent="handleRegister" id="register-form" data-vv-scope="register-form">
<v-text-field outlined v-model="user.email" v-validate="'required|email'"
name="email" :error-messages="errors.collect('register-form.email')"
label="メールアドレス"
:class="{ 'is-invalid': submitted && errors.has('register-form.email')}">
</v-text-field>
<v-text-field v-model="user.password" v-validate="'required|min:8|max:20'"
:error-messages="errors.collect('register-form.password')"
:type="'password'" single-line outlined name="password"
label="パスワード"
:class="{ 'is-invalid': submitted && errors.has('register-form.password') }"
></v-text-field>
<v-text-field v-model="user.password_confirmation"
v-validate="'required|min:8|max:20'"
:error-messages="errors.collect('register-form.password_confirmation')"
label="パスワード確認" name="password_confirmation"
single-line outlined :type="'password'"
:class="{ 'is-invalid': submitted && errors.has('register-form.password_confirmation') }"
></v-text-field>
<v-text-field v-model="user.user_id" v-validate="'required|min:4|max:20'"
:error-messages="errors.collect('register-form.user_id')"
single-line outlined label="ユーザID" name="user_id"
:class="{ 'is-invalid': submitted && errors.has('register-form.user_id') }"
></v-text-field>
</v-form>

You use 1.5.5 vuetify version. You should try outline attribute instead of outlined. They changed it in v 2.0, and i think you've read v2 docs.

Related

Why cannot I hide a div with v-if?

Scenario: I have two options for a signup page. In the second one, I have a few more input elements and I only want to render that div when I click the second checkbox. For that, I wrote a v-if and it does not work properly.
(the project is in Vue)
<v-checkbox v-model="checkboxes" label="Bireysel Üyelik" value="checkbox-1"></v-checkbox>
<v-checkbox v-model="checkboxes" label="Kurumsal Üyelik" value="checkbox-2"></v-checkbox>
<div v-if="checkboxes === 'checkbox2'">
<v-text-field
name="cellPhone"
label="Cep Telefonu"
type="text"
key="cell-phone"
outlined
dense
required
>
</v-text-field>
</div>
data() {
return {
checkboxes: "",
}
}
The Html and JS files are as above. The data is dynamically changed in the Vue instance and there is no problem with that. The problem is with the conditional rendering mentioned above.
In your checkbox you bind a value of checkbox-2
<v-checkbox v-model="checkboxes" label="Kurumsal Üyelik" value="checkbox-2"></v-checkbox>
but then you look for checkbox2
<div v-if="checkboxes === 'checkbox2'">
<v-text-field
name="cellPhone"
label="Cep Telefonu"
type="text"
key="cell-phone"
outlined
dense
required
>
</v-text-field>
change it to:
<div v-if="checkboxes === 'checkbox-2'">
<v-text-field
name="cellPhone"
label="Cep Telefonu"
type="text"
key="cell-phone"
outlined
dense
required
>
</v-text-field>
and it will work :) .
Hope this helps!

Vuetify input autocomplete bug

I tried to google it a couple of times but got no luck, basically, when the page loads since the password is on autosave the v-text-field doesn't understand it and renders the password content in front of the label, is there any workaround or fix for that?
Here is a ss:
The login component:
<template>
<div>
<v-card class="elevation-12">
<v-toolbar color="primary" dark flat>
<v-toolbar-title>Login</v-toolbar-title>
</v-toolbar>
<v-card-text>
<v-form>
<v-text-field
label="E-mail"
name="email"
type="text"
:rules="emailRules"
:autofocus="'autofocus'"
></v-text-field>
<v-text-field
id="password"
label="Senha"
name="password"
type="password"
></v-text-field>
</v-form>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="primary" block>Logar</v-btn>
</v-card-actions>
</v-card>
</div>
</template>
<script>
export default {
name: "LoginForm",
data: () => ({
valid: true,
email: '',
password:'',
emailRules: [
v => !!v || 'Digite um e-mail',
v => /.+#.+\..+/.test(v) || 'O e-mail precisa ser válido.',
]
})
}
</script>
<style lang="scss">
#import "LoginForm.scss";
</style>
The place where I use the login component:
<template>
<v-content>
<v-container fluid fill-height>
<v-layout align-center justify-center>
<v-flex xs12 sm8 md4>
<LoginForm></LoginForm>
</v-flex>
</v-layout>
</v-container>
</v-content>
</template>
<script>
import LoginForm from "../components/login/LoginForm";
import Logo from '~/components/Logo.vue'
import VuetifyLogo from '~/components/VuetifyLogo.vue'
export default {
name: 'Index',
components: {
LoginForm,
Logo,
VuetifyLogo
},
data: () => ({
}),
}
</script>
Update June 4, 2021. Tested on Vuetify 2.5.3 and Google Chrome 90:
You can still use placeholder prop with one space in combination with persistent-placeholder prop.
...
<v-text-field
label="Login"
v-model="loginItem.login"
placeholder=" "
persistent-placeholder
:rules="rules.login"
/>
Old answer. This solution stopped working starting from vuetify 2.4.0 (thanks #saike for the info):
As a simple workaround you could add placeholder prop with one space:
...
<v-text-field
label="Login"
v-model="loginItem.login"
placeholder=" "
:rules="rules.login"
></v-text-field>
...
<v-text-field
label="Password"
placeholder=" "
v-model="loginItem.password"
type="password"
:rules="rules.password"
></v-text-field>
...
That's how it looks like when login/password was saved in your browser (in my case it's Google Chrome 80):
And with empty values:
The solution that works for me is generating a random name attribute. With my solution I used uuid v4 method. If you rely on name then obviously this might not work for you unless you keep a map of names -> v4 output.
import { v4 } from 'uuid'
<v-text-field
v-model="card"
class="card-input"
outlined
:name="v4()"
label="Credit Card Number"
:rules="creditCardNumberRules"
v-mask="[' #### #### #### ####', ' #### #### ##### ###']"
/>

v-slot:badge and v-if does not work with a computed property

I'm working on a CMS project and I have an issue I can't figure out.
I Have a component where I'm showing IP's. On change I want a badge to appear, so the user knows "this field is changed".
But the thing is the badge won't show if I'm using "v-slot:badge".
In the v-if is a computed property, If I inspect the page with vue devtools ‘isStartIpValueChanged’ will be true on a change. So, it should work right?
Template
<v-list-item-content>
<v-form ref="form" v-model="valid">
<v-hover v-slot:default="{ hover }">
<v-row align-content="center" no-gutters>
<v-col>
<v-badge overlap color="red" right>
<template v-slot:badge v-if="isStartIpValueChanged">
<v-avatar color="red" size="6"></v-avatar>
</template>
<v-text-field
dense
:rules="apiIpRules"
v-model="apiIp.startIp"
#input="valueChanged()"
ref="startIp"
:class="hover ? 'hover-text-color' : ''"
placeholder="###.###.###.###">
</v-text-field>
</v-badge>
</v-col>
<v-col cols="1" class="text-center" align-self="center">
<p>-</p>
</v-col>
<v-col cols="1" class="text-center" align-self="center">
<v-btn v-show="hover" #click="deleteIp()" icon small color="red"><v-icon>mdi-minus-circle</v-icon></v-btn>
</v-col>
</v-row>
</v-hover>
</v-form>
Created and Computed (apiIp is a prop I get from the parent component)
created () {
this.apiIpsOriginalValueStartIp = this.apiIp.startIp
this.apiIpsOriginalValueEndIp = this.apiIp.endIp
this.apiIp.uuid = this.GenerateUUID()
},
computed: {
isStartIpValueChanged () {
return this.apiIp &&
(this.apiIp.startIp !== this.apiIpsOriginalValueStartIp ||
this.apiIp.uuid === null)
},
isEndIpValueChanged () {
return this.apiIp &&
(this.apiIp.endIp !== this.apiIpsOriginalValueEndIp ||
this.apiIp.uuid === null)
}
},
Anyone know what is going wrong here?
As according to Vuetify's own documentation, you should be using the v-model, directly on the v-badge, to show it only when you want it to.
<v-badge overlap color="red" right v-model="isStartIpValueChanged">
<template v-slot:badge>
<v-avatar color="red" size="6"></v-avatar>
</template>
<v-text-field
dense
:rules="apiIpRules"
v-model="apiIp.startIp"
#input="valueChanged()"
ref="startIp"
:class="hover ? 'hover-text-color' : ''"
placeholder="###.###.###.###">
</v-text-field>
</v-badge>
Doc: https://vuetifyjs.com/en/components/badges#show-on-hover

Vuetify timepicker return value to model

I'm using Vuetify timepicker within my project, however after selecting a time it doesn't appear to be updating my model, how can I get it to do this?
This is my component which is using the timepicker:
time-select.vue
<template>
<v-layout row wrap>
<v-flex>
<v-menu
ref="menu"
v-model="menu2"
:close-on-content-click="false"
:nudge-right="40"
:return-value.sync="time"
lazy
transition="scale-transition"
offset-y
full-width
max-width="290px"
min-width="290px">
<v-text-field
slot="activator"
v-model="time"
:label="this.label"
:name="this.name"
prepend-icon="access_time"
readonly></v-text-field>
<v-time-picker
v-if="menu2"
v-model="time"
full-width
#click:minute="$refs.menu.save(time)"
></v-time-picker>
</v-menu>
</v-flex>
</v-layout>
</template>
<script>
export default {
props: [ 'label', 'name', 'value' ],
data () {
return {
time: this.value,
menu2: false,
modal2: false
}
}
}
</script>
And this is how I'm adding the timepicker to my page, as you can see I'm using v-model so the value is updated.
<time-select v-model="hours.open_time"
name="businessHoursTimeFrom[]"
label="Open Time"></time-select>
Don't forget that v-model="someVar" used with custom components is just a shortcut for:
:value="someVar" #input="someVar = $event"
Thus, this:
<time-select v-model="hours.open_time" />
Under the hood is:
<time-select :value="hours.open_time" #input="hours.open_time = $event" />
That means that your custom component should trigger input event itself.
Like this:
<v-time-picker
v-if="menu2"
:value="time"
#input="$emit('input', $event)"
full-width
#click:minute="$refs.menu.save(time)" />
Useful link: Vue.js → Using v-model on components

Is there is a better way to capture erros from Vuetify components?

I'm using the Vue.js library Vuetify to add a few text field components inside on a component that I create. In order to provide input validation I would like to capture the hasError property of the text field components. I know the path of the property is: this.$children[3]._computedWatchers.hasError.active. But I would like to know if there is another way to access theses properties. Maybe I'm missing something?
<template>
<div class="register">
<form>
<div>
<v-text-field name="new-user-email"
label="Email"
type="email"
single-line
required></v-text-field>
</div>
<div>
<v-text-field name="user-user-password"
label="Password"
type="password"
single-line
required>
</v-text-field>
</div>
<div>
<v-text-field name="new-user-password-confirmation"
label="Confirm Password"
type="password"
single-line
required>
</v-text-field>
</div>
<div #click="registerNewUser">
<v-btn>Register</v-btn>
</div>
</form>
</div>
</template>
<script>
export default {
name: 'register-new-user',
data() {
return {
checked: false
};
},
methods: {
registerNewUser() {
console.log(this.$children[3]._computedWatchers.hasError.active)
console.log('Register a new user')
}
}
};
</script>
Add a ref attribute to the v-text-field component like this:
<v-text-field
ref="password-confirmation"
name="new-user-password-confirmation"
label="Confirm Password"
type="password"
single-line
required
></v-text-field>
Then you can reference the VueComponent instance of the Vuetify text field component (along with its properties and methods) like so:
methods: {
registerNewUser() {
console.log(this.$refs['password-confirmation'].hasError)
}
}
Here's documentation on refs.