How can I submit only form elements in Vue[2].js? - forms

I have a form page and I use it for both create and update
My form fields are like this;
myForm: {
name: (...)
email: (...)
password: (...)
}
I can successfully submit a request.
When we come to the update process, I get the data in this way (this.myForm = response.data)
When I send an update request I just want the form fields to go but it goes like this
myForm: {
name: (...)
email: (...)
password: (...)
createdAt: (...)
updatedAt: (...)
_id: (...)
}
I don't want to send createdAt, updatedAt, _id fields
How can I submit only form fields in Vue.js or Element-ui? (I am using element-ui btw)
Is there something like this.$refs.myForm.fields or this.$refs.myForm.values I couldn't find it
My code: Code picture
<template>
<div class="app-container">
<el-form ref="myForm" label-position="top" :model="myForm">
<el-form-item>
<label>Name</label>
<el-input v-model="myForm.name" />
</el-form-item>
<el-form-item>
<label>Email</label>
<el-input v-model="myForm.email" />
</el-form-item>
<el-form-item>
<label>Password</label>
<el-input v-model="myForm.password" />
</el-form-item>
<el-button type="primary" #click="submitForm('myForm')">Kaydet</el-button>
</el-form>
</div>
</template>
<script>
export default {
name: 'UserForm',
data() {
return {
myForm: {
name: '',
email: '',
password: ''
}
}
},
created() {
if (this.$route.params.id) {
this.getFormData(this.$route.params.id)
}
},
methods: {
submitForm() {
if (!this.$route.params.id) {
this.$store.dispatch('user/create', this.myForm)
} else {
this.$store.dispatch('user/update/', this.myForm)
}
},
getFormData(id) {
this.$store.dispatch('user/get', id).then((response) => {
this.myForm = response.data
})
}
}
}
</script>

Instead of posting the entire 'this.myForm', just specify the fields you want to post in a new object.
submitForm() {
if (!this.$route.params.id) {
this.$store.dispatch('user/create', this.myForm)
} else {
this.$store.dispatch('user/update/', {
name: this.myForm.name,
email: this.myForm.email,
password: this.myForm.password
})
}
}
UPDATE: Following comments from OP, if you're expecting more that 'name', 'email', and 'password', you can just delete the properties you don't want to send.
submitForm() {
if (!this.$route.params.id) {
this.$store.dispatch('user/create', this.myForm)
} else {
delete this.myForm.createdAt,
delete this.myForm.updatedAt,
delete this.myForm._id
this.$store.dispatch('user/update/', this.myForm)
}
}

Related

Vue2 how to only submit form values?

I have a form page and I use it for both create and update
My form fields are like this;
enter image description here
content: (...)
i18n: (...)
image: (...)
name: (...)
orderIndex: (...)
position: (...)
I can successfully submit a request.
When we come to the update process, I get the data in this way and sync it. I'm getting extra data (this.myForm = response.data)
When I send an update request I just want the form fields to go but it goes like this
I don't want to send createdAt, deleted, updatedAt, _id fields
enter image description here
content: (...)
createdAt: (...)
deleted: (...)
i18n: (...)
image: (...)
isEnabled: (...)
name: (...)
orderIndex: (...)
position: (...)
updatedAt: (...)
_id: (...)
How can I submit only form fields? (I am using element-ui btw)
Is there something like this.$refs.myForm.fields or this.$refs.myForm.values I couldn't find it
For example Angular reactive form has something like this --> this.testimonialForm.patchValue(response.data);
data() {
return {
id: null,
testimonialForm: {
name: '',
position: '',
content: '',
orderIndex: '',
i18n: '',
image: {
path: ''
}
}
}
},
computed: {
...mapState({
testimonialData: state => state.testimonial.testimonial
})
},
created() {
if (this.$route.params.id) {
this.id = this.$route.params.id
this.fnGetTestimonialInfo(this.id)
}
},
methods: {
fnCreateTestimonial() {
this.$store.dispatch('testimonial/create', this.testimonialForm).then(() => {
this.$router.push('/testimonial/list')
})
},
fnUpdateTestimonial() {
const data = { id: this.id, data: this.testimonialForm }
this.$store.dispatch('testimonial/update', data).then(() => {
this.$router.push('/testimonial/list')
})
},
fnGetTestimonialInfo(id) {
this.$store.dispatch('testimonial/get', id).then(() => {
this.testimonialForm = this.testimonialData
})
},
}
Solved like this :
const pick = require('lodash/pick')
const formKeys = Object.keys(this.testimonialForm)
this.testimonialForm = pick(this.testimonialData, formKeys)
Thanks to #gguney for the guidance.
First of all, You have to fetch your object from backend. You do not neet to your store.
Just use axios to fetch your resource.
axios.get('/testimonial/get/' + id)
.then(function (response) {
this.testimonialForm = response.data.testimonial
console.log(response);
})
.catch(function (error) {
console.log(error);
});
You can use your inputs like:
<el-input
v-model="testimonialForm.name"
:placeholder="$t('form.name')"
name="name"
type="text"
/>
Then send your testimonialForm to your backend via axios.
You can add underscorejs to your project and use this function
_.pick(testimonialForm, 'name', 'otherField');

Why my submit form is not working in Vue3 with BalmUI

I'm trying to make a register page and my sybmit doesn't work. Does anyone know how to fix it? This is my code
<template>
<div>
<h1>Register</h1>
<ui-form
type="|"
item-margin-bottom="16"
action-align="center"
v-on:submit.prevent="register()"
>
<template #default="{ actionClass }">
<ui-form-field>
<ui-textfield
v-model="email"
required
helper-text-id="email-field-helper-text"
input-type="email"
>
Email Address
</ui-textfield>
<ui-textfield-helper
v-if="controls.helperText"
id="email-field-helper-text"
:visible="controls.isVisible"
>
Must be like me#example.com
</ui-textfield-helper>
</ui-form-field>
<ui-form-field>
<label>Password:</label>
<ui-textfield
v-model="password"
input-type="password"
required
pattern=".{8,}"
helper-text-id="pw-validation-msg"
:attrs="{ autocomplete: 'current-password' }"
>Choose password</ui-textfield
>
<ui-textfield-helper id="pw-validation-msg" visible validMsg>
Must be at least 8 characters long
</ui-textfield-helper>
</ui-form-field>
<ui-form-field :class="actionClass">
<ui-button raised nativeType="submit" type="submit">Submit</ui-button>
<ui-button outlined>Cancel</ui-button>
</ui-form-field>
</template>
</ui-form>
<div>
{{ mesaj }}
</div>
</div>
</template>
I've also tried this instead of v-on:submit.prevent="register()"
#submit.prevent="register()" or #submit.prevent.native
Also, if I put #click=register() on my button it does register all the values, even if they are not valid
I've figured it out using validators https://next-material.balmjs.com/#/data-input/validator
This is the code:
<template>
<div>
<h1>Register</h1>
<ui-form type="|" item-margin-bottom="16" action-align="center">
<template #default="{ actionClass }">
<ui-form-field>
<ui-textfield
v-model="formData.email"
required
helper-text-id="email-field-helper-text"
input-type="email"
>
Email address
</ui-textfield>
<ui-textfield-helper
v-if="controls.helperText"
id="email-field-helper-text"
:visible="controls.isVisible"
>
Must be like me#example.com
</ui-textfield-helper>
</ui-form-field>
<ui-form-field>
<label>Password:</label>
<ui-textfield
v-model="formData.password"
input-type="password"
required
pattern=".{8,}"
helper-text-id="pw-validation-msg"
:attrs="{ autocomplete: 'current-password' }"
>Choose password</ui-textfield
>
<ui-textfield-helper id="pw-validation-msg" visible validMsg>
Must be at least 8 characters long
</ui-textfield-helper>
</ui-form-field>
<ui-alert v-if="message" state="error">{{ message }}</ui-alert>
<ui-form-field :class="actionClass">
<ui-button raised #click="register()">Submit</ui-button>
<ui-button outlined>Cancel</ui-button>
</ui-form-field>
</template>
</ui-form>
<div>
{{ mesaj }}
</div>
</div>
</template>
<script>
import utils from "../utils.js";
import { useValidator, helpers } from "balm-ui";
const validations = {
email: {
label: "Email",
validator: "required, email",
email: {
validate(value) {
return /^(([^<>()\]\\.,;:\s#"]+(\.[^<>()\]\\.,;:\s#"]+)*)|(".+"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,24}))$/.test(value);
},
message: "Email address should be like me#example.com",
},
},
password: {
label: "Password",
validator: "required, password, minRule",
password: {
validate(value) {
return /^\w+$/.test(value);
},
message: "%s must be a letter, digit or underline",
},
minRule: {
validate(value) {
return value.trim().length >= 8;
},
message: "%s minLength >= 8",
},
},
};
export default {
name: "Register",
required: {
validate(value) {
return !helpers.isEmpty(value);
},
message: "%s is required",
},
data() {
return {
balmUI: useValidator(),
validations,
formData: {
email: "",
password: "",
},
mesaj: "",
message: "",
controls: {
helperText: true,
isVisible: true,
},
};
},
methods: {
register() {
let result = this.balmUI.validate(this.formData);
let { valid, message } = result;
this.message = message;
console.log(`Vrei sa te inregistrezi cu email: ${this.formData.email}`);
console.log(utils.url);
if (valid) {
let data = {
email: this.formData.email,
password: this.formData.password,
};
let requestParameters = utils.globalRequestParameters;
requestParameters.method = "POST";
requestParameters.body = JSON.stringify(data);
fetch(utils.url + "user", requestParameters).then((res) => {
res.text().then((res) => (this.mesaj = res));
});
}
},
},
};
</script>
<style></style>

Does onCompleted works with useMutation?

I am using useMutation hook in react project. The mutation runs successfully but it's not reaching onCompleted afterwards.
I have set notifyOnNetworkStatusChange to true in the mutation but that doesn't seem to help.
const [createUser] = useMutation(SIGNUP_MUTATION);
createUser({
variables: {
firstname,
lastname,
email
},
notifyOnNetworkStatusChange: true,
onCompleted: (data) => {
// not called
confirm(data);
}
});
Looking at the api of useMutation it seems like you're using onCompleted in the wrong place. it should be part of the useMutation definition.
const [createUser] = useMutation(
SIGNUP_MUTATION,
{
onCompleted(data) {
confirm(data);
}
}
);
return (
<div>
<form
onSubmit={e => {
e.preventDefault();
createUser({ variables: { firstname, lastname, email } }); // assuming `firstname`, `lastname` and `email` are defined somewhere.
}}
>
<input type="text" />
<button type="submit">Signup</button>
</form>
</div>
);
A couple years later -- we can now to do this:
const [saveFormData] = useMutation(SAVE_FORM_DATA_MUTATION);
saveFormData({
variables: {
myVariable: 'test variable'
},
update: (cache, data) => {
//do updates here
}
})

i want to do a dynamic form with v-if

I want to display an additional input if the person clicks yes and clicks on nothing
i try to do that with v-if but i the value never change
this is the entire page in vuejs maybe i need to do a method, i already try without quote and with, i to set value like club = 1 but didn't work to.
I'm not sure if my v-bind is good too
<el-form-item label="Possédez vous un club ?">
<el-radio-group v-model="ruleForm.club">
<el-radio label="Oui" v-bind:value="true"></el-radio>
<el-radio label="Non" v-bind:value="false"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item v-if="'ruleForm.club' == true" label="Nom du club" prop="nClub">
<el-input v-model="ruleForm.nClub" autocomplete="off"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" #click="submitForm('ruleForm')">Submit</el-button>
<el-button #click="resetForm('ruleForm')">Reset</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
export default {
data () {
var validatePseudo = (rule, value, callback) => {
if (value === '' || value !== 'coach') {
callback(new Error('Please input the pseudo'))
} else {
callback()
}
}
var validatePass = (rule, value, callback) => {
if (value === '' || value !== 'password') {
callback(new Error('Please input the password'))
} else {
callback()
}
}
return {
ruleForm: {
nom: '',
prenom: '',
pseudo: '',
email: '',
pass: '',
statue: '',
club: '',
nClub: ''
},
rules: {
pseudo: [
{ validator: validatePseudo, trigger: 'blur' }
],
pass: [
{ validator: validatePass, trigger: 'blur' }
]
}
}
},
methods: {
submitForm (formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
this.$router.push({
name: '/'
})
} else {
console.log('error submit!!')
return false
}
})
},
resetForm (formName) {
this.$refs[formName].resetFields()
},
}
}
</script>
I do not really understand your question, but from what I can tell you would like to add an inputfield if a user selects a certain radio button using v-if. I've recreated this in a jsfiddle. Is this wat your looking for?
Link: https://jsfiddle.net/Mertakus/8wx4h7up/3/

Reactjs how to get value from selected element

so I have this code for posting to my backend API. Normal form perfectly fine; I managed to post to my database. So I add a Cascader from Ant Design CSS Framework, and every time I selected the value, it produced an error
TypeError: Cannot read property 'value' of undefined
Here is the code:
import React from 'react';
import axios from 'axios';
import { Button, Cascader, Form, Input, Modal } from 'antd';
const FormProduct = Form.Item;
const computerType = [
{
value: 'computer',
label: 'Computer',
},
{
value: 'laptop',
label: 'Laptop',
}
]
export default class FormInventory extends React.Component {
state = {
category: '',
productname: '',
};
handleCategoryChange = event => { this.setState({ category: event.target.value }) }
handleProductNameChange = event => { this.setState({ productname: event.target.value }) }
handleSubmit = event => {
event.preventDefault();
axios.post('myapi',
{
category: this.state.category,
productname: this.state.productname,
})
.then(
function success() {
const modal = Modal.success({
title: 'Success',
content: 'Data successfully add',
});
setTimeout(() => modal.destroy(), 2000);
}
)
}
render() {
return (
<Form onSubmit={this.handleSubmit}>
<FormProduct {...formProductLayout} label="Computer Category">
<Cascader options={computerType} category={this.state.value} onChange={this.handleCategoryChange} />
</FormProduct>
<FormProduct {...formProductLayout} label="Product Name">
<Input type="text" productname={this.state.productname} onChange={this.handleProductNameChange} />
</FormProduct>
<FormProduct wrapperCol={{ span: 12, offset: 2 }}>
<Button type="primary" htmlType="submit">
Add Item
</Button>
</FormProduct>
</Form>
)
}
}
You need to either bind your event handlers in the constructor or use arrow function.
Option 1: Bind
constructor(props) {
// This binding is necessary to make `this` work in the callback
this.handleClick = this.handleClick.bind(this);
}
Option 2: Arrow function
<Input onChange={(e) => this.handleChange(e)} />
According to antd docs you don't need event.target.
https://ant.design/components/cascader/
handleCategoryChange = category => { this.setState({ category }) }
The code above will work fine.