I have a problem with my code. I can't find a reason why my GET parameters are empty when the form is submitted.
What I'm trying to achieve is to submit the form after validation and be redirected to http://someurl.com/?service=3&propert_type=2. Is it even possible? Or do I need to stringify it and then use window.location?
I'm a newbie at Vue, but can't find the internet for a solution so I guess it's something to do with my code.
<template>
<ValidationObserver v-slot="{ valid }" ref="getanoffer">
<v-form
class="form form--getanoffer"
ref="form"
>
<ValidationProvider
rules="required"
v-slot="{ errors }"
name="service"
>
<v-select
v-model="service"
name="service"
:items="services"
placeholder="Select Service"
:error-messages="errors"
solo
></v-select>
</ValidationProvider>
<ValidationProvider
rules="required"
v-slot="{ errors }"
name="property_type"
>
<v-select
v-model="property_type"
:items="property_types"
name="property_types"
item-text="name"
item-value="id"
placeholder="Select Property Type"
:error-messages="errors"
solo
></v-select>
</ValidationProvider>
<v-btn
color="primary"
width="100%"
#click="validate"
class="v-btn--submit v-btn--no-gutter"
:loading="loading"
:disabled=" ! valid"
>
Continue
</v-btn>
</v-form>
</ValidationObserver>
</template>
<script>
import {ValidationProvider, ValidationObserver} from "vee-validate";
export default {
components: {
ValidationProvider,
ValidationObserver,
},
data() {
return {
service: null,
property_type: null,
form: {
},
loading: false,
}
},
props: {
services: {
type: Array,
},
property_types: {
type: Array,
}
},
methods: {
async validate() {
let form = await this.$refs.getanoffer.validate();
if (form) {
this.loading = true;
this.submit();
this.$refs.form.$el.submit();
}
},
submit() {
}
}
}
</script>
Lets simplify your code
Instead of calling validate() on button click, you can add type="submit" to your button and in your form you can add #submit:prevent="validate". This doesn't solve the problem but allows you to submit with Enter and every submit button will trigger the validation.
Now for the solution
1- To navigate to external scope you can use windows.open(). Vuetify lets you navigate to an url but you had to put href on your button and control it manually
windows.open('http://someurl.com/')
CodePen
Vuetify vee-validate docs
Javacript standards say that you should use camelCase for js variables (this.propertyType)
JS standard
ESlint Rules
Related
In my vue application I need to observe an element getting enabled/disabled (It binds to a function) and by looking that I need to trigger an onEnabled/onDisabled event which will clean up some other data nodes.
So is there a listener like #click, #enabled or something?
Eg:
<v-checkbox :value="getValue(layout.responseNode)" #change="setValue(layout.responseNode, $event)" :label="expression(layout.label)" :disabled="expression(layout.enableIf)" ></v-checkbox>
This is the code so far with me. here enableIf will be a dynamic expression from server.
Its properly working now.
Now I need to run some more expression like
<v-checkbox :value="getValue(layout.responseNode)" #change="setValue(layout.responseNode, $event)" :label="expression(layout.label)" :disabled="expression(layout.enableIf)" #onDisabled="expression(layout.disableCommand)" ></v-checkbox>
Is there an event matching onDisabled?
i would recommend watchers you can bind a variable/computed to :disabled of the checkbox and watch the value changing
exp.
<template>
<div>
<p>{{ checkboxState }}</p>
<input type="checkbox" :disabled="checkboxState" />
<button #click="checkboxChanged()">Disable Checkbox!</button>
</div>
</template>
<script>
export default {
name: "App",
data: () => {
return {
checkboxState: true,
};
},
methods: {
checkboxChanged() {
this.checkboxState = !this.checkboxState;
},
},
watch: {
checkboxState() {
// this is fired when the checkboxState changes
console.log("fired when checkboxState changes");
},
},
};
</script>
note: the function name and the variable must have the same name for watchers to work.
Like this Sandbox
I'm trying to figure out how to allow users to copy their login details when they click the copy icon. How to get the value of the relevant v-text-field?
I thought I should use #click:append and link it to a method. However, I struggle how to get a value.
<template>
<v-card class="col-12 col-md-8 col-lg-6 p-6 px-16" elevation="4">
<div class="title h2 mb-10 text-uppercase text-center">
Success
<v-icon color="green" x-large>
mdi-check-circle
</v-icon>
</div>
<v-text-field
:value="newAccount.login"
label="Login"
outlined
readonly
append-icon="mdi-content-copy"
#click:append="copy('login')"
></v-text-field>
<v-text-field
:value="newAccount.password"
label="Password"
outlined
readonly
append-icon="mdi-content-copy"
></v-text-field>
</v-card>
</template>
<script>
export default {
props: ["newAccount"],
data() {
return {
copied: false,
};
},
methods: {
copy(target) {
if (target === "login") {
console.log("login is clicked");
}
},
},
computed: {},
};
</script>
The value of the v-text-field is available from its value property. Apply a template ref on the v-text-field to get a reference to the component programmatically from vm.$refs, then use .value off of that:
<template>
<v-text-field
ref="login"
#click:append="copy('login')"
></v-text-field>
</template>
<script>
export default {
methods: {
copy(field) {
console.log('value', this.$refs[field].value)
}
}
}
</script>
Alternatively, you could access the nested template ref of v-text-field's <input>, which has a ref named "input", so copy() would access it from this.$refs[field].$refs.input. Then, you could select() the text value, and execute a copy command:
export default {
methods: {
copy(field) {
const input = this.$refs[field].$refs.input
input.select()
document.execCommand('copy')
input.setSelectionRange(0,0) // unselect
}
}
}
demo
I use vue-select in my Vue app. I created a component as a wrapper for v-select. To return only a specific column of the options array, I use the :reduce prop of vue-select.
<template>
<span>
<label v-if="title">{{title}}</label>
<v-select
:options="options"
:label="label"
:placeholder="placeholderText"
:close-on-select="closeOnSelectValue"
:disabled="isDisabled"
:multiple="multiple"
:value="value"
#input="handleInput($event)"
:loading="isLoading"
:reduce="option=> option.val"
></v-select>
</span>
This code works, but I would like to have the static val string to be the dynamic prop returnKey. This would be passed to the component as a prop.
props: {
returnKey: {
type: String,
default: null,
},
}
What syntax should I use to make a combination of the 'option' string and the dynamic value of 'returnKey' in the function passed to :reduce to get this working?
You can use the bracket notation and do option => option[returnKey].
And as what Richard has suggested, in order to avoid runtime error you might want to provide some kind of fallback, or enforce that returnKey must be a required prop.
You can try something like this
<template>
<span>
<label v-if="title">{{title}}</label>
<v-select
:options="options"
:label="label"
:placeholder="placeholderText"
:close-on-select="closeOnSelectValue"
:disabled="isDisabled"
:multiple="multiple"
:value="value"
#input="handleInput($event)"
:loading="isLoading"
:reduce="reduceKey"
></v-select>
</span>
</template>
<script>
export default
{
props: {
returnKey: {
type: String,
default: null,
},
},
methods:
{
reduceKey(option)
{
return option[this.returnKey] || option;
}
}
}
I have the following Vue view named "PasswordResetView":
<template>
<v-content>
<v-card>
<v-card-title primary-title>
Passwort ändern
</v-card-title>
<v-card-text>
<v-text-field
id="password"
label="Passwort"
name="password"
prepend-icon="mdi-lock"
type="password"
/>
<v-text-field
id="passwordRepeated"
label="Passwort wiederholen"
name="passwordRepeated"
prepend-icon="mdi-lock"
type="password"
/>
<v-text-field
id="mail"
label="E-Mail"
name="mail"
prepend-icon="mdi-lock"
type="text"
/>
</v-card-text>
</v-card>
</v-content>
</template>
<script>
import axios from "axios";
export default {
name: "passwordreset",
data() {
return {
password: "",
passwordRepeated: "",
mail: "",
errormessage: "",
};
},
methods: {
changePassword() {
let payload = {mail: this.mail, password:this.password, passwordRepeated: this.passwordRepeated};
axios({
method: "post",
url: "/api/anonymous/register/pwreset",
data: payload,
}).then(() => {
this.$props.passwortresetkey = "good"
})
},
}
};
</script>
<style scoped/>
The view is imported by another vue component "PasswordReset" as following:
<template>
<div>
<PasswordReset v-if="pwresetkey === 'good'"></PasswordReset>
<div v-else>
<v-card>
<v-card-title primary-title>
Passwort ändern
</v-card-title>
<v-card-text>
Leider ist der Link ungültig.
</v-card-text>
</v-card>
</div>
</div>
</template>
<script>
import PasswordReset from "../../../components/anon/PasswordReset";
export default {
name:"passwordreset",
components: PasswordReset
};
</script>
The corresponding router:
{
path: "/pwreset",
name: "pwreset",
meta: {
requiresDisponent: false,
requiresRecurring: false,
requiresOneTime: false,
requiresAnon: true
},
component: () => import("#/views/recurring/account/PasswordReset"),
props: true
},
However, when I start the application, only the content from "PasswordReset" is shown (the v-card), but not the input fields.
Also, in the component "PasswordReset" it says that export default is ununsed.
Why is this marked as unused and the view not imported?
From vuejs docs:
If you use kebab-case
Vue.component('my-component-name', { /* ... */ })
When defining a component with kebab-case, you must also use kebab-case when referencing its custom element, such as in .
if you use PascalCase
Vue.component('MyComponentName', { /* ... */ })
When defining a component with PascalCase, you can use either case when referencing its custom element. That means both and are acceptable. Note, however, that only kebab-case names are valid directly in the DOM (i.e. non-string templates).
Try changing your password reset component like so:
<script>
import PasswordReset from "../../../components/anon/PasswordReset";
export default {
name:"passwordreset",
components: {PasswordReset}
};
</script>
VueJS Component Registration
i'm trying my form data submit. when i try my code
form.append('subject',"hello"),
It is good working. but form.append('subject', 'this.subject') => return 'undefined'. how do i solve it?
form.append('subject',"hello"), it is good working. but form.append('subject', 'this.subject') => return 'undefined'.
My Write.vue is :
<template>
<v-form #submit.prevent="sendPost" id="WriteForm" method="post">
<v-btn icon type="submit" form="WriteForm"><v-icon>send</v-icon></v-btn>
<v-text-field name="subject"></v-text-field>
<v-textarea name="context"></v-textarea>
</v-form>
</template>
<script>
export default {
data(){
return{}
},
methods: {
sendPost: function(){
console.log(this.subject); //==> undefined :(
console.log(this.context); //==> undefined :(
}
}
</script>
You should add that properties to your data object and bind them to the v-text-field as follows :
data(){
return{
subject:'',
context:''
}
}
and bind them using v-model directive in your template fields like :
<v-text-field name="subject" v-model="subject"></v-text-field>
<v-textarea name="context" v-model="context"></v-textarea>