I have a nested loop in a vue component. The first loop is to create four dropdown boxes, the second loop is to create three options within each dropdown box. I have attached the image to illustrate. They work correctly in that if I select the checkbox for any of the options within any dropdown box then the correct outcome occurs. The problem is that if I click the word next to the checkbox then always the corresponding option in the first dropdown box is selected, which is not acceptable. So, if I click the checkbox next to 3b then everything is fine; if I click the 'b' next to the checkbox (which is likely for a user to do), then 1b will be selected.
How can I make clicking the 'b' in this case select 3b instead of 1b?
template code
<b-list-group v-for="number in numbers" v-bind="number">
<b-button v-b-toggle=number class="m-1 flood-button">{{ number }} </b-button>
<b-collapse :id="number">
<b-card>
<b-list-group>
<b-list-group-item v-for="letter in letters" v-bind="letter" class="list-group-item">
<label :for=letter>
<input :id="letter" type="checkbox" #change="toggleLayerVisibility({
'floodType': ft,
'risk': $event.target.id,
'display': $event.target.checked
})">
{{ letter }}
</label>
</b-list-group-item>
</b-list-group>
</b-card>
</b-collapse>
</b-list-group>
component data
data () {
return {
letters: ["a", "b", "c"],
numbers: ["1", "2", "3", "4"]
}
}
screenshot
It happens because the input id was the same for all inputs with the same letter, so 1b and 3b have the same id. Try to modify the id attribute, e.g. add a number to differentiate ids.
new Vue({
el: '#app',
data() {
return {
letters: ["a", "b", "c"],
numbers: ["1", "2", "3", "4"]
}
},
methods: {
toggleLayerVisibility() {},
}
});
<link type="text/css" rel="stylesheet" href="https://unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
<link type="text/css" rel="stylesheet" href="https://unpkg.com/bootstrap-vue#latest/dist/bootstrap-vue.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.14/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-vue/2.21.2/bootstrap-vue.min.js"></script>
<div id="app">
<b-list-group v-for="number in numbers" v-bind="number">
<b-button v-b-toggle=number class="m-1 flood-button">{{ number }} </b-button>
<b-collapse :id=number>
<b-card>
<b-list-group>
<b-list-group-item v-for="letter in letters" v-bind="letter" class="list-group-item">
<label :for="letter + number">
<input :id="letter + number" type="checkbox" #change="toggleLayerVisibility({
'floodType': ft,
'risk': $event.target.id,
'display': $event.target.checked
})">
{{ letter }}
</label>
</b-list-group-item>
</b-list-group>
</b-card>
</b-collapse>
</b-list-group>
</div>
Related
when I edit a dict in a array which has been cloned from another dict,the value of the other cloned dictionaries also changes. Is there a way where i can change only the specified dictionary value??
<template v-for="stage in clonedstages">
<p v-text="stage.name" #click="stagedisplay=true" > </p>
<stage header="Stage Edit" :visible.sync="stagedisplay" :modal="true">
<div>
<div class="form-group">
<label for="stagename">Stage name </label>
<input type="text" class="form-control" id="stagename" v-model="[index]clonedstages.name">
</div>
</div>
<button class="btn btn-secondary" #click="stagedisplay=false">Done</button>
</stage>
</template>
<div class="col-sm">
<button class="btn-sm btn-primary" #click="Gd">GD</button>
`
interview: {
stage_type : 1,
description : "something",
name : "Interview"
},
clonedstages: [],
this is the dict,
Interview(){
vue_create.clonedstages.push(vue_create.interview);
},
this is the method.
I am new to this.
I have a downpayment form that have two inputs. One for dollar amount and one for percentage. I also have a slider that changes the percentage.
<div class="form-group">
<label for="">Down Payment</label>
<div class="flex-row d-flex">
<input class="form-control" type="text" v-model="downPaymentComputed" />
<input class="form-control" type="text" v-model="dpPercent">
</div>
<div class="mt-3 pt-4">
<vue-slider
v-model="dpPercent"
:tooltip="'always'"
:min="0"
:max="100"
:tooltip-formatter="formatter1"
></vue-slider>
</div>
</div>
in the script
let app = new Vue({
el: '#app',
delimiters: ['${', '}'],
components: {
VueSlider: window['vue-slider-component']
},
data: {
formatter2: v => `$${('' + v).replace(/\B(?=(\d{3})+(?!\d))/g, ',')}`,
formatter1: '{value}%',
payment:null,
downPayment: {{ property.price*0.2 }},
dpPercent:'20',
price: {{ property.price }}
},
computed:{
downPaymentComputed(){
return this.price*(this.dpPercent/100)
}
},
In this configuration when I use the slider or enter the percentage, the downpayment changes. But when I enter new downpayment, nothing happens.
How do I bind so that when I change either the downpayment or the percent or the slider all inputs get updated?
EDIT: Thanks Phil, you pointed me in the right direction. I binded the values and then used on:change methods to update the other values
<input class="form-control" type="text" v-on:keyup="updateDP()" v-model="price" />
<input class="form-control" type="text" v-on:keyup="updatePercent()" v-model="downPayment" />
<input type="text" class="form-control" v-on:keyup="updateDP()" v-model="dpPercent">
I have a couple of fields, that are rendered through v-for loop:
<div v-for="element in elements" class="uk-form-row uk-margin-small-top">
<input class="uk-width-1-1 uk-form-small" type="text" placeholder="element" style="width:50%">
</div>
And I need to pass them through a POST request.
elements is just an array, that contains a different number of:
value: ""
and after submitting the form, an array is just a collection of empty objects
How can I change my code to pass an array of values from those fields?
Try to bind your inputs to your array items using v-model directive like :
<div v-for="element in elements" class="uk-form-row uk-margin-small-top">
<input v-model="element.value" class="uk-width-1-1 uk-form-small" type="text" placeholder="element" style="width:50%">
</div>
after that you could use your elements array directly in the POST request.
new Vue({
el: '#app',
data: {
elements: []
},
methods: {
addElement: function() {
this.elements.push({
value: ''
});
}
}
});
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="app">
<h1>Elements</h1>
<div v-for="element in elements">
<input class="form-control" v-model="element.value" type="text" />
</div>
<button class="btn btn-primary" #click="addElement">
New Element
</button>
<pre>{{ $data | json }}</pre>
</div>
I'd like to make default checked on radio buttons inside a v-for loop.
Here is the code:
<ul v-for="p in photos">
<li>
<div>
<div>
<div>
Visibility: {{p.visible}}
</div>
<strong>Visibility setting</strong><br>
<input type="radio" v-model="p.visible" name="visibility" value="all" :checked="p.visible == 'all'"> All <br>
<input type="radio" v-model="p.visible" name="visibility" value="fav" :checked="p.visible == 'fav'"> My favorites <br>
<input type="radio" v-model="p.visible" name="visibility" value="none" :checked="p.visible == 'none'"> No one
</div>
<div><img" v-bind:src="BASE_URL +'/uploads/' + userId + '/'+ p.imgId" /> </div>
</div>
</li>
</ul>
I followed this answer.
While I can see Visibility of each item is being printed, the default radio buttons of each photo are not checked as expected.
Here is the photos array which I receive from the server when the component is created:
[
{
"id" : "5bcebb6efeaea3147b7a22f0",
"imgId" : "12710.png",
"visible" : "all"
},
{
"id" : "5bcebbf0feaea3147b7a22f1",
"imgId" : "62818.png",
"visible" : "fav"
},
{
"id" : "5bcec010feaea3147b7a22f2",
"imgId" : "36740.png",
"visible" : "none"
}
],
What is wrong here and how can I fix it?
Don't use :checked:
v-model will ignore the initial value, checked or selected attributes found on any form elements. It will always treat the Vue instance data as the source of truth. You should declare the initial value on the JavaScript side, inside the data option of your component.
If v-model is the same as value it will return true for that checkbox. Your fixed fiddle:
new Vue({
el: '#app',
data: {
photos: [{
"id": "5bcebb6efeaea3147b7a22f0",
"imgId": "12710.png",
"visible": "all"
},
{
"id": "5bcebbf0feaea3147b7a22f1",
"imgId": "62818.png",
"visible": "fav"
},
{
"id": "5bcec010feaea3147b7a22f2",
"imgId": "36740.png",
"visible": "none"
}
],
}
})
<script src="https://unpkg.com/vue"></script>
<div id="app">
<ul v-for="(p, index) in photos">
<li>
<div>
Visibility: {{p.visible}}
</div>
<strong>Visibility setting</strong><br>
<input type="radio" v-model="photos[index].visible" :name=`visibility-${index}` value="all"> All <br>
<input type="radio" v-model="photos[index].visible" :name=`visibility-${index}` value="fav"> My favorites <br>
<input type="radio" v-model="photos[index].visible" :name=`visibility-${index}` value="none"> No one
</li>
</ul>
</div>
Now each radio group has it's own name, with v-model targeting that group (note the index).
How to show different component on radio button select.
<input type="radio" name="book" value="One" checked="checked">
<input type="radio" name="book" value="Round">
<div> // this should show show default, One is selected
<p>Value One</p>
</div>
<div> // this should show show on radio change to Round selected
<p>Value Round</p>
</div>
How about something like this?
new Vue({
el: '#app',
data: {
x: 'one',
},
});
<script src="https://rawgit.com/vuejs/vue/dev/dist/vue.js"></script>
<div id="app">
<input type="radio" v-model="x" value="one">
<input type="radio" v-model="x" value="two">
<div v-show="x === 'one'">One</div>
<div v-show="x === 'two'">Two</div>
</div>
i have done it with javascript .onclick it calls each function which hides & show element vice versa
function rdone(){
document.getElementById('one').style.display ='block';
document.getElementById('round').style.display ='none';
}
function rdround(){
document.getElementById('round').style.display = 'block';
document.getElementById('one').style.display ='none';
}
#round{
display:none;
}
<input type="radio" name="book" value="One" checked="checked" onclick="rdone();">
<input type="radio" onclick="rdround();" name="book" value="Round">
<div id=one> // this should show show default, One is selected
<p>Value One</p>
</div>
<div id=round> // this should show show on radio change to Round selected
<p>Value Round</p>
</div>