How do I use one input to control the other in vuejs - javascript

I need to find a way to basically show "per Month" in the assessments_period input if the assessments fee input has a typed-in value.
I've tried bindings and components but can't pull this off.
<div class="col-lg-6">
<div class="form-group">
<label>Assessment Fee <span class="note">C</span></label>
<input type="text" class="form-control" v-model="document.assessments_fee" placeholder="$">
</div>
</div>
<div class="col-lg-6">
<div class="form-group">
<label>Assessment Period <span class="note">C</span></label>
<input type="text" class="form-control" v-model="document.assessments_period" placeholder="(per month/quarter/etc.)">
</div>
</div>
data() {
return {
now: new Date().toISOString(),
document: {
assessments_fee: '',
assessments_period: '',
}
}
},
components: {
assessments_fee: function() {
if(this.assessments_fee != null || '') this.assessments_period = "per Month";
}
},

you can create a watcher for assessments_fee so when its not null assessments_period= 'per Month'.
Here is how you can do it:
new Vue({
el: '#app',
data() {
return {
now: new Date().toISOString(),
document: {
assessments_fee: '',
assessments_period: '',
}
}
},
computed: {
assessmentsFee() {
return this.document.assessments_fee
}
},
watch: {
assessmentsFee() {
this.document.assessments_fee ?
this.document.assessments_period = "per Month" :
this.document.assessments_period = ""
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div class="col-lg-6">
<div class="form-group">
<label>Assessment Fee <span class="note">C</span></label>
<input type="text" class="form-control" v-model="document.assessments_fee" placeholder="$">
</div>
</div>
<div class="col-lg-6">
<div class="form-group">
<label>Assessment Period <span class="note">C</span></label>
<input type="text" class="form-control" v-model="document.assessments_period" placeholder="(per month/quarter/etc.)">
</div>
</div>
</div>

Related

Vue.js post checkbox empty data or full data

I am trying to make a checkbox with vue js, so that the method is not written. I want the checkbox to be false in the first place, the next step is that when the checkbox is posted, I want "opening_balance" to be sent as an empty array.
or vice versa, if the checkbox is checked, I want it to appear in "opening_balance" when the data is posted.
For example:
POST
No Checkbox
opening_balance: {}
POST
Checked
opening_balance: {date: "2021-08-30", net_total: "1000.00", currency: "USD"}
new Vue({
el: '#app',
data() {
return {
attributes: {
opening_balance: {
net_total: 0,
date: new Date(),
currency: USD,
},
}
}
}
});
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.14/vue.js"></script>
<div id="app" style="padding: 1rem;">
<div class="d-flex">
<input class="form-check-input" type="checkbox" value="false" #click="attributes.opening_balance" v-model="attributes.opening_balance">
<label class="form-check-label"><b> opening balance</b></label>
</div>
<div v-if="attributes.opening_balance">
<input type="text" id="Detaylari" class="form-control" v-model="attributes.opening_balance.date">
<input type="text" class="form-control" v-model="attributes.opening_balance.net_total">
<input type="text" class="form-control" v-model="attributes.opening_balance.currency">
</div>
</div>
If i understand you correctly please look at snippet bellow:
const app = new Vue({
el: '#app',
data() {
return {
attributes: {
opening_balance: {
},
}
}
},
methods: {
setBalance(e) {
if(!e.target.checked) {
this.attributes.opening_balance= {}
}
}
}
});
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app" style="padding: 1rem;">
<div class="d-flex">
<input class="form-check-input" type="checkbox" #click="setBalance">
<label class="form-check-label"><b> opening balance</b></label>
</div>
<div v-if="attributes.opening_balance">
<input type="text" id="Detaylari" class="form-control" v-model="attributes.opening_balance.date">
<input type="text" class="form-control" v-model="attributes.opening_balance.net_total">
<input type="text" class="form-control" v-model="attributes.opening_balance.currency">
<p>{{ attributes.opening_balance }}</p>
</div>
</div>
You can use a watcher to set a empty object when checked is false.
new Vue({
el: '#app',
watch: {
isPosted: function(val) {
// on posted unchecked set empty object
if (!val) {
this.attributes.opening_balance = {};
} else {
this.$set(this.attributes.opening_balance, "date", "2021-08-30");
this.$set(this.attributes.opening_balance, "net_total", "1000.00");
this.$set(this.attributes.opening_balance, "currency", "USD");
}
},
},
data() {
return {
isPosted: false,
attributes: {
opening_balance: {},
}
}
}
});
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.14/vue.js"></script>
<div id="app" style="padding: 1rem;">
<div class="d-flex">
<input class="form-check-input" type="checkbox" v-model="isPosted">
<label class="form-check-label"><b> opening balance</b></label>
</div>
<div v-if="isPosted">
<input type="text" id="Detaylari" class="form-control" v-model="attributes.opening_balance.date">
<input type="text" class="form-control" v-model="attributes.opening_balance.net_total">
<input type="text" class="form-control" v-model="attributes.opening_balance.currency">
</div>
</div>

How to use template inside a form in vue js

I have created a vue instance for the form
var formObject = new Vue({
el: '#amount_form',
data: {
logdate: '',
amount:'',
description:''
},
methods: {
processForm :function(event)
{
var data = {"logdate":this.logdate,"amount":parseFloat(this.amount),"description":this.description};
console.log(data);
var parameters =
{
"data":data,
"url":"save",
"type":"post",
"data_type":"JSON",
"callback":function(data)
{
alert(data);
}
}
sendDataToSErver(parameters);
}
}
});
i have a template for categories
var categorySelect = Vue.component('category-select',
{
data()
{
return{
options:[],
cat:""
}},
template:'<select class="form-control form-control-sm" v-model="cat">' +
' <option v-for="option in options" v-bind:value="option.id">{{option.name}}</option></select>',
created :function()
{
var templateObject = this;
var parameters =
{
"url":"getCategories",
"type":"GET",
"async":true,
"data_type":"JSON",
"callback":function(data)
{
templateObject.options = data;
}
}
sendDataToSErver(parameters);
}
});
i am using this template inside the form
<div class="row">
<div class="col-3">
<div class="form-group">
<label for="log_date" class="sr-only">Date</label>
<input v-model="logdate" type="datetime-local" id="log_date" class="form-control form-control-sm" aria-label="Sizing example input" aria-describedby="inputGroup-sizing-sm">
</div>
</div>
<div class="col-3">
<div class="form-group">
<label for="amount" class="sr-only">Amount</label>
<input v-model="amount" type="text" class="form-control form-control-sm" aria-label="Sizing example input" aria-describedby="inputGroup-sizing-sm">
</div>
</div>
<div class="col-3">
<div class="form-group">
<label for="category" class="sr-only">Category</label>
<category-select></category-select>
</div>
</div>
</div>
<div class="row">
<div class="col-12">
<div class="form-group">
<label for="description" class="sr-only">Description</label>
<textarea v-model="description" class="form-control" id="description" aria-label="With textarea"></textarea>
</div>
</div>
</div>
</form>
Now how can get the value in form.
You can emit an event from the child. The parent needs to listen for the custom event and get the data from there. You also need to listen for onChange on your select to emit the event.
The template for categories should be something like this
var categorySelect = Vue.component('category-select',
{
data()
{
return {
options:[],
cat:""
}
},
template:'<select class="form-control form-control-sm" v-model="cat" #change="handleUpdateSelectedValue($event)">' +
' <option v-for="option in options" v-bind:value="option.id">{{option.name}}</option></select>',
methods: {
handleUpdateSelectedValue(event) {
this.$emit('selectedValue', event.target.value) //emitting the event here
}
}
created :function()
{
var templateObject = this;
var parameters =
{
"url":"getCategories",
"type":"GET",
"async":true,
"data_type":"JSON",
"callback":function(data)
{
templateObject.options = data;
}
}
sendDataToSErver(parameters);
}
});
And now you need to listen for the event in the parent
<div class="col-3">
<div class="form-group">
<label for="category" class="sr-only">Category</label>
<category-select #selectedValue="handleSelectedValue"></category-select>
</div>
</div>
Now, the only thing that remains to do is to define handleSelectedValue in your parent component and do something with that value.
var formObject = new Vue({
el: '#amount_form',
data: {
logdate: '',
amount:'',
description:''
},
methods: {
handleSelectedValue(value) {
}
}
...

Need the value (subtraction of value) to effect the value of another input

I'm trying to the value of money_due and have the value for deposit subtracted from it if the deposit input is holding a value. So far, it is adding it on just fine, but it is not removing it when I empty the value.
<div class="col-sm-12 col-md-6 col-lg-4">
<div class="form-group">
<label>Total Sum Due <span class="note">2</span></label>
<input type="text" class="form-control" v-model="document.money_due" placeholder="">
</div>
</div>
<div class="col-sm-12 col-md-6 col-lg-4">
<div class="form-group">
<label>Deposit <span class="note">2</span></label>
<input type="text" class="form-control" #change="hasDeposit" v-model="document.deposit" placeholder="">
</div>
</div>
data() {
return {
now: new Date().toISOString(),
document: {
deposit: '',
money_due: '',
}
}
},
this.document.deposit = this.listing.price;
this.document.money_due = this.document.last_month + this.document.security_deposit,
methods: {
hasDeposit() {
if(this.document.deposit == '') {
return this.document.money_due = this.document.money_due + this.document.deposit;
} else {
return this.document.money_due = this.document.money_due;
}
},
mounted() {
this.hasDeposit();
},
Sorry, but it's a bit unclear what you want to achieve with your code.
I created a snippet where I tried to model the deposit and the money_due relations.
new Vue({
el: "#app",
data: {
listing: {
price: 10
},
document: {
last_month: -20,
security_deposit: 10,
deposit: 0,
money_due: 0
},
},
computed: {
hasDeposit() {
return Number(this.document.money_due) + Number(this.document.deposit)
}
},
mounted() {
this.document.deposit = this.listing.price;
this.document.money_due = this.document.last_month + this.document.security_deposit
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<label>Total Sum Due <span class="note">2</span>
<input type="text" class="form-control" v-model="hasDeposit" placeholder=""></label><br />
<label>Deposit <span class="note">2</span>
<input type="text" class="form-control" v-model="document.deposit" placeholder=""></label>
</div>
I mocked the data that's referenced in your code
Moved hasDeposit() from being a method to computed (it only returns a calculated value)
Changed what's in mounted
I hope this is what you were after.

Vuelidate errors return true but elements don't render

I have a contact form that uses vuelidate to validate fields. The problem is - the validation works, but the errors don't render.
$v.name.dirty is TRUE and $v.name.required is FALSE.
Logging $v.name.dirty && !$v.name.required returns TRUE which is the same condition in the v-if directive but the error elements still don't show.
However, when .$touch() is called and $v.name.dirty becomes true and $v.name.required false, anything I type in the input fields will show the errors.
JS:
import translationsBus from "../../app/translations";
export default {
name: "contactForm",
beforeMount() {
this.$store.dispatch("updateTranslations", translationsBus.translations);
},
data: function () {
return {
name: '',
email: '',
subject: '',
message: ' ',
errors: [],
isSuccessful: ''
}
},
mounted() {
var my_axios = axios.create({
baseURL: '/'
});
Vue.prototype.$http = my_axios;
},
computed: {
isLogged: function () {
return isLoggedOn;
},
shouldShowSubjectOption: function () {
return showSubjectOption;
},
translations: function () {
return this.$store.state.translations.translations;
},
},
methods: {
onContactUsClick: function onContactUsClick() {
const _this = this;
this.$v.$touch();
if (!this.$v.$error) {
let model = {
senderName: _this.name,
senderEmail: _this.email,
subject: _this.subject,
message: _this.message
};
this.$http.post('/home/contactus', model)
.then(response => {
console.log(response);
_this.isSuccessful = response.data;
})
.catch(e => {
console.log(e);
});
}
}
},
validations: {
email: {
required: required,
isValidEmail: function isValidEmail(value) {
var re = /^\w+([\.-]?\w+)*#\w+([\.-]?\w+)*(\.\w{2,3})+$/;
return re.test(value);
}
},
name: {
required: required
},
subject: {
required: required
},
message: {
required: required
}
}
}```
HTML:
<div v-bind:class="{ 'col-lg-6' : shouldShowSubjectOption, 'col-lg-12' : !shouldShowSubjectOption }">
<div id="form-contact">
<h1 class="lead">Get in touch...</h1>
<form class="text-center" >
<div class="form-group">
<label for="name">{{translations['contact_Form_Name']}}</label>
<div class="input-group">
<span class="input-group-addon"><span class="fa fa-user"></span></span>
<input type="text" class="form-control" name="senderName" id="senderName" v-model:bind="name" v-bind:placeholder="translations['contact_Form_NamePlaceholder']" />
</div>
<div class="has-error" v-cloak>
<label class="control-label" v-if="$v.name.$dirty && !$v.name.required">{{translations['shared_Validation_ReuiredField']}}</label>
</div>
</div>
<div class="form-group">
<label for="email">{{translations['contact_Form_EmailAddress']}}</label>
<div class="input-group">
<span class="input-group-addon"><span class="fa fa-envelope"></span></span>
<input type="email" class="form-control" name="senderEmail" id="senderEmail" v-model:bind="email" v-bind:placeholder="translations['contact_Form_EmailAddressPlaceholder']" />
</div>
<div class="has-error" v-cloak>
<label class="control-label" v-if="$v.email.$dirty && !$v.email.required">{{translations['shared_Validation_ReuiredField']}}</label>
<label class="control-label" v-if="$v.email.$dirty && $v.email.required && !$v.email.isValidEmail">{{translations['contact_Form_EmailAddressValidationMessage']}}</label>
</div>
</div>
<div class="form-group" v-if="shouldShowSubjectOption">
<label for="subject">{{translations['contact_Form_Subject']}}</label>
<select id="subject" name="subject" class="form-control" v-model:bind="subject" v-bind:title="translations['contact_Form_SubjectPickerText']">
<option value="service">1</option>{{translations['contact_Form_SubjectOption_GCS']}}
<option value="suggestions">2</option>{{translations['contact_Form_SubjectOption_Suggestions']}}
<option value="product">3</option>{{translations['contact_Form_SubjectOption_ProductSupport']}}
</select>
</div>
<div class="has-error" v-cloak>
<label class="control-label" v-if="$v.subject.$dirty && !$v.subject.required" v-cloak>{{translations['shared_Validation_ReuiredField']}}</label>
</div>
<div class="form-group">
<label for="name">{{translations['contact_Form_Message']}}</label>
<textarea name="message" id="message" class="form-control" v-model:bind="message" rows="9" cols="25"
placeholder="">{{translations['contact_Form_Message']}}</textarea>
</div>
<div class="has-error" v-cloak>
<label class="control-label" v-if="$v.message.$dirty && !$v.message.required">{{translations['shared_Validation_ReuiredField']}}</label>
</div>
<div class="form-group" v-if="isLogged">
<div class="g-recaptcha" data-sitekey=""></div>
</div>
<button type="button" class="btn btn-primary btn-block" v-on:click="onContactUsClick" id="btnContactUs">{{translations['contact_Form_SendMessageButton']}}</button>
</form>
</div>
</div>
</div>
</div>
I expect error elements to appear on submit.

how to set value form input vue js from json

please have a problem here. I want to display the value from the input form: name and position. but the data is in the form of json.
{"id":5,"name":"the name","pos":"the position"}
This is template html vue js
<template>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">
Edit <b>{{name}}</b>
</div>
<div class="card-body">
<form #submit="edit()" method="post" onclick="return false">
<div class="form-group">
<label for="">Name</label>
<input v-model="input.nameInput" type="text" value="?" autocomplete="off" class="form-control">
</div>
<div class="form-group">
<label for="">Position</label>
<input v-model="input.posInput" value="?" type="text" autocomplete="off" class="form-control">
</div>
<button type="submit" class="btn btn-primary">Edit</button>
</form>
</div>
</div>
</div>
</div>
</div>
</template>
And this is java script of template file vue js
<script>
export default {
data(){
return{
name:'',
pos:'',
input:{
nameInput:'',
posInput:''
}
}
},
methods:{
getEmploye(){
axios.get('/employes_api/'+this.$route.params.id).then(response => {
this.name = response.data.name;
this.pos = response.data.pos;
});
},
edit(){
axios.put('/employes_api/'+this.$route.params.id, {
name: this.name,
pos: this.position,
}).then(response => {
this.$route.employe;
});
}
},
mounted(){
this.getEmploye();
}
}
</script>
Thanks for your help.
As described in your question, if the data received is
{"id":5,"name":"the name","pos":"the position"}
then you getEmploye method should be :
getEmploye(){
axios.get('/employes_api/'+this.$route.params.id).then(response => {
this.name = response.name;
this.pos = response.pos;
});
On element’s value, you may use the following to display data you have received from the api:
value=“{{name}}”
That means you are getting the value from name data.
Also, to test if that works, you may assign first a dummy data/value to name.
You don't need to make two separate variables one for the inputs and the other for the display, just keep the same variable for both, it will be automatically updated on the display and in the inputs while the user is typing, that's the beauty of Vue.
So instead of
data(){
return{
name:'',
pos:'',
input:{
nameInput:'',
posInput:''
}
}
},
Just keep
data(){
return{
name:'',
pos:''
}
},
For the template inputs use :
<input v-model="name" type="text" autocomplete="off" class="form-control">
...
<input v-model="pos" type="text" autocomplete="off" class="form-control">
The overall result should look like this :
<template>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">
Edit <b>{{name}}</b>
</div>
<div class="card-body">
<form #submit="edit()" method="post">
<div class="form-group">
<label for="">Name</label>
<input v-model="name" type="text" autocomplete="off" class="form-control">
</div>
<div class="form-group">
<label for="">Position</label>
<input v-model="position" type="text" autocomplete="off" class="form-control">
</div>
<button type="submit" class="btn btn-primary">Edit</button>
</form>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data(){
return{
name:'',
pos:''
}
},
methods:{
getEmploye(){
axios.get('/employes_api/'+this.$route.params.id).then(response => {
this.name = response.data.name;
this.pos = response.data.pos;
});
},
edit(){
axios.put('/employes_api/'+this.$route.params.id, {
name: this.name,
pos: this.pos,
}).then(response => {
this.$route.employe;
});
}
},
created(){
this.getEmploye();
}
}
Ps : Didn't test the code, if there is any error just let me know
Use :value=“name”, e.g <input :value="name"/>.

Categories

Resources