VueJS: class not being bound on button click - vue.js

I have written a function that binds an active class to a popup when an image has been clicked. However, while the expandedImageActive and expandedImage data properties are updated correctly when toggleExpand() runs, the class isn't bound to the popup correctly. What am I doing wrong? Below is the relevant code (assuming mainImage has a value):
HTML
<section class="product__images">
<div class="product__images-main">
<a #click="toggleExpand(mainImage)">
<img :src="mainImage.url" :alt="mainImage.description ? mainImage.description : product.title.value" />
</a>
</div>
<div class="popup" :class="{ active: expandedImageActive }">
<div v-if="expandedImage">
<a #click="toggleExpand()">close</a>
<img :src="expandedImage.url" />
</div>
</div>
</section>
JS
var app = new Vue({
el: '#app',
data () {
return{
mainImage: null,
expandedImage: null,
expandedImageActive: false
}
}
methods: {
toggleMainImage (image){
this.mainImage = image;
},
toggleExpand (image){
image ? this.expandedImage = image: this.expandedImage = null;
this.expandImageActive = !this.expandImageActive;
console.log(this.expandImageActive)
}
}
})

Related

How do i get the value from radio button and use it inside a url

all. I want to have some knowledge on how do i fetch a value from the radio button and use that inside a url
Here is the code:
HTML
<b-form-radio name="radio" v-model="selectedAge" value="30">
Hub
</b-form-radio>
<b-form-radio name="radio" v-model="selectedAge" value="40">
Point
</b-form-radio>
<button href="localhost/test/exam/names?age={selectedAge}"></button>
SCRIPT
data () {
return {
selectedAge: '',
}
}
I am not able to get the value from the radio button here. Please advise
Thank you
You can do the following ......
var app = new Vue({
el: '#app',
methods: {
onChange(event) {
var data = event.target.value;
console.log(data);
document.getElementById('btn_1').href = 'localhost/test/exam/names?age=' + data;
}
}
})
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<div id="app">
<b-form-radio name="radio" v-model="selectedAge" #change="onChange($event)" value="30">
Hub
</b-form-radio>
<b-form-radio name="radio" v-model="selectedAge" #change="onChange($event)" value="40">
Point
</b-form-radio>
<br />
<a id="btn_1" href="localhost/test/exam/names?age={selectedAge}">Button</a>
</div>

vue.js basic function not working as wanted

I have create a set of pairs of divs, that use the v-for method to get data from a set of dummy objects in an array. The goal is for each pair of divs when I click on the visible div it opens the corresponding relevant div. At the moment my function which I have attached as a property of a method object only opens the invisible div of the first pair of divs even if I click on the 3rd visible div it still displays the invisible div. i am using the vue framework.
I have attached pictures of my code then the actual code.
[The div I am trying to open is session-on-click details atm it is opening only that for the first index][1]
<div class = "rowuserlog" id="log-container" v-for="session in sessions" :key="session.id"
>
<div id="log-container-user-row-1">
<div id="profile-log-title" #click="logToggler()"> {{session.name}} </div>
<div id="profile-log-date"> {{session.date}}</div>
<div id="user-log-metric-container">
<div id ="user-log-hr" class="log-metric">{{session.hr}}</div>
<div id ="user-log-time" class="log-metric"> {{session.time}}</div>
<div id ="user-log-meters" class="log-metric"> {{session.distance}} </div>
<div id="session-onclick-details">
<div id="log-comments">
{{session.comments}}
</div>
<div id="log-edit-buttons">
<button id="log-save" class="log-edit-button"> Save </button>
<button id="log-delete" class="log-edit-button"> Delete </button>
<button id="log-cancel" class="log-edit-button"> Cancel </button>
<button id="log-edit" class="log-edit-button"> Edit </button>
</div>
</div>
```
My method
The toggler is the method I want:Here is the code
methods:{
logToggler () {
const extraInfoLog = document.getElementById("session-onclick-details");
return extraInfoLog.style.display="block";
}
]
[2]
[1]: https://i.stack.imgur.com/ddrYo.png
[2]: https://i.stack.imgur.com/evriF.png
data() {
return {
sessions:[
{ name:'test',
value:false,
id:1
},
{ name:'test1',
value:false,
id:2
},
{ name:'test2',
value:false,
id:3
}
]
}
}
methods:{
logToggler(_index) {
for(let index=0;index<sessions.length;index++) {
if(index == _index)
sessions[index].value = true
else
sessions[index].value = false
}
}
}
Template
<div class = "rowuserlog" id="log-container" v-for="(session,index) in sessions" :key="session.id"
>
<div id="profile-log-title" #click="logToggler(index)" v-if="session.value"> {{session.name}} </div>

Click Event on Dynamically Generated Button Don't get fired in Vue

I am adding a button dynamically and attaching the click event but it doesn't seem to fire.
I see something similar on link below but its not exactly what I am looking for.
Vue: Bind click event to dynamically inserted content
let importListComponent = new Vue({
el: '#import-list-component',
data: {
files: [],
},
methods: {
// more methods here from 1 to 5
//6. dynamically create Card and Commit Button
showData: function (responseData) {
let self = this;
responseData.forEach((bmaSourceLog) => {
$('#accordionOne').append(`<div class="main-card mb-1 card">
<div class="card-header" id=heading${bmaSourceLog.bmaSourceLogId}>
${bmaSourceLog.fileName}
<div class="btn-actions-pane-right actions-icon-btn">
<input type="button" class="btn btn-outline-primary mr-2" value="Commit" v-on:click="commit(${bmaSourceLog.bmaSourceLogId})" />
<a data-toggle="collapse" data-target="#collapse${ bmaSourceLog.bmaSourceLogId}" aria-expanded="false" aria-controls="collapse${bmaSourceLog.bmaSourceLogId}" class="btn-icon btn-icon-only btn btn-link">
</a>
</div>
</div>
<div id="collapse${ bmaSourceLog.bmaSourceLogId}" class="collapse show" aria-labelledby="heading${bmaSourceLog.bmaSourceLogId}" data-parent="#accordionOne">
<div class="card-body">
<div id="grid${ bmaSourceLog.bmaSourceLogId}" style="margin-bottom:30px"></div>
</div>
</div>
</div>`);
});
},
//7. Commit Staging data
commit: function (responseData) {
snackbar("Data Saved Successfully...", "bg-success");
},
}});
I am adding button Commit as shown in code and want commit: function (responseData) to fire.
I was able to achieve this by pure Vue way. So my requirement was dynamically add content with a button and call a function from the button. I have achieved it like so.
Component Code
const users = [
{
id: 1,
name: 'James',
},
{
id: 2,
name: 'Fatima',
},
{
id: 3,
name: 'Xin',
}]
Vue.component('user-component', {
template: `
<div class="main-card mb-1 card">
<div class="card-header">
Component Header
<div class="btn-actions-pane-right actions-icon-btn">
<input type="button" class="btn btn-outline-primary mr-2" value="Click Me" v-on:click="testme(user.id)" />
</div>
</div>
<div class="card-body">
{{user.name}}
</div>
<div class="card-footer">
{{user.id}}
</div>
</div>
`
,props: {
user: Object
}
,
methods: {
testme: function (id) {
console.log(id);
}
}});
let tc = new Vue({
el: '#test-component',
data: {
users
},});
HTML
<div id="test-component">
<user-component v-for="user in users" v-bind:key="user.id" :user="user" />
</div>

Can't get a reset button to clear out a checkbox

I'm using Vue.js v2 and I've defined a single-file component, RegionFacet.vue. It lists some regions that relate to polygons on a map (click a value, the corresponding polygon appears on the map).
Separately, I have a reset button. When that gets clicked, I call a method in RegionFacet to unselect any checkboxes displayed by RegionFacet. The model does get updated, however, the checkboxes remain checked. What am I missing?
<template>
<div class="facet">
<div class="">
<div class="panel-group" id="accordion">
<div class="panel panel-default">
<div class="panel-heading">
<a data-toggle="collapse"v-bind:href="'#facet-' + this.id"><h4 class="panel-title">Regions</h4></a>
</div>
<div v-bind:id="'facet-' + id" class="panel-collapse collapse in">
<ul class="list-group">
<li v-for="feature in content.features" class="list-group-item">
<label>
<input type="checkbox" class="rChecker"
v-on:click="selectRegion"
v-bind:value="feature.properties.name"
v-model="selected"
/>
<span>{{feature.properties.name}}</span>
</label>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: ['content'],
data: function() {
return {
id: -1,
selected: []
}
},
methods: {
selectRegion: function(event) {
console.log('click: ' + event.target.checked);
if (event.target.checked) {
this.selected.push(event.target.value);
} else {
var index = this.selected.indexOf(event.target.value);
this.selected.splice(index, 1);
}
this.$emit('selection', event.target.value, event.target.checked);
},
reset: function() {
this.selected.length = 0;
}
},
created: function() {
this.id = this._uid
}
}
</script>
<style>
</style>
You are directly setting the array length to be zero, which cannot be detected by Vue, as explained here: https://v2.vuejs.org/v2/guide/list.html#Caveats
Some more info: https://v2.vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats
To overcome this, you may instead set the value of this.selected as follows:
reset: function() {
this.selected = [];
}

v-on:click not working in a child component

First thing first I'm new to vue.js.
what I'm trying to do when the user click on the expander anchor tag in the item-preview component the item-details will display and the item-preview will be hide. Now the problem occurs when the item-preview displayed and i'm trying to toggle it by clicking its own expander anchor tag. I do not whats wrong with this.
Here is my HTML templates.
<script type="text/x-template" id="grid">
<div class="model item" v-for="entry in data">
<item-preview v-bind:entry="entry" v-if="entry.hide == 0">
</item-preview>
<item-details v-bind:entry="entry" v-if="entry.hide == 1">
</item-details>
</div>
</script>
<script type="text/x-template" id="item-preview">
<header class="preview">
<a class="expander" tabindex="-1" v-on:click="toggle(entry)"></a>
<span class="name rds_markup">
{{ entry.name }}
</span>
</header>
</script>
<script type="text/x-template" id="item-details">
<div class="edit details">
<section class="edit" tabindex="-1">
<form action="#">
<fieldset class="item name">
<a class="expander" v-on:click="toggle(entry)"></a>
{{ entry.name }}
</fieldset>
</form>
</section>
</div>
</script>
And here how I called the grid component on my view.
<grid
:data="packages">
</grid>
And for my Vue implementation
var itemPreview = Vue.component('item-preview',{
'template':"#item-preview",
'props':{
entry:Object
},
methods:{
toggle:function(entry){
entry.hide = !!entry.hide;
return true;
}
}
});
var itemDetails = Vue.component('item-details',{
'template':"#item-details",
'props':{
entry:Object
},
methods:{
toggle:function(entry){
entry.hide = !!entry.hide;
return true;
}
}
});
var grid = Vue.component('grid',{
'template':"#grid",
'props':{
data:Array,
},
components:{
'item-preview': itemPreview,
'item-details': itemDetails
},
methods:{
toggle:function(entry){
entry.hide = !!entry.hide;
return true;
}
}
});
var vm = new Vue({
el:'#app',
data:{
message:'Hello',
packages:{}
},
ready:function(){
this.fetchPackages();
},
methods:{
fetchPackages:function(){
this.$http.get(url1,function( response ){
this.$set('packages',response);
});
},
}
});
Silly me. It took me 30minutes to figure out what is wrong with this code.
What I did to fix this is instead of entry.hide = !!entry.hide; I use entry.hide = true in item-preview component and in the item-details entry.hide = false. this fix my issue.