v-on:click not working in a child component - vue.js

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.

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 adding a toggle and method to a button

I have a button that should toggle and also call a method. How do I achieve this? Seems like it can be only one or the other.
new Vue({
el: "#app",
data: {
iExist:false,
iDoNotExist: true,
},
methods: {
iSignedUpforThis: function(){
console.log("step X");
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<p v-show="iExist"> i EXISTS </p>
<p v-show="iDoNotExist">
<strong> You are not found: </strong>
<form >
First name:<br>
<input type="text" name="firstname" value="Mickey">
<br>
Last name:<br>
<input type="text" name="lastname" value="Mouse">
<br><br>
</form>
<BUTTON v-on:click="iExists = iDoNotExist">
TOGGLE MY EXISTENCE
</BUTTON>
</div>
Move
iExists = iDoNotExist to a method:
methods: {
iSignedUpforThis: function(){
this.iExist = this.iDoNotExist
console.log("step X");
}
}
<button v-on:click="iSignedUpForThis">
TOGGLE MY EXISTENCE
</button>
First off to accomplish your desired result you need only one Boolean variable. Then in your method just switch between true and false. Also you have an invalid markup - there is closing tap p but no closing. That's why your example does not work.
Notice: it's bad idea to nest form tag inside p tag, so use div instead. It's considered a good practice to associate your input with it's label using label tag. Also there is shortcut for v-on:click - #click. data should be an function that returns an object, this will prevent . multiple instance to share the same object.
If you follow above recommendations you will make your code much clear and bug-less.
new Vue({
el: '#app',
data: {
isExist: false,
},
methods: {
method() {
this.isExist = !this.isExist
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div v-show="isExist">I exist</div>
<div v-show="!isExist">
<strong>You are not found:</strong>
<form>
<label>First name:<br>
<input type="text" name="firstname" value="Mickey">
</label>
<br>
<label>Last name:<br>
<input type="text" name="lastname" value="Mouse">
</label>
</form>
</div>
<button #click="method">Toggle</button>
</div>
It might be late but I am sure it will help others. Create a component ToggleButton.js and paste the below codes.
<template>
<label for="toggle_button">
<span v-if="isActive" class="toggle__label">On</span>
<span v-if="! isActive" class="toggle__label">Off</span>
<input type="checkbox" id="toggle_button" v-model="checkedValue">
<span class="toggle__switch"></span>
</label>
</template>
<script>
export default {
data() {
return {
currentState: false
}
},
computed: {
isActive() {
return this.currentState;
},
checkedValue: {
get() {
return this.defaultState
},
set(newValue) {
this.currentState = newValue;
}
}
}
}
</script>
Take a look at the article to learn more https://webomnizz.com/create-toggle-switch-button-with-vue-js/

VueJS: class not being bound on button click

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)
}
}
})

Vue add a component on button click

I have three templates. AddCard.vue , ImageCard.vue and VideoCard.vue
AddCard.vue has two buttons on it one is to add the Image Card and Other To Add the video Card.. I need to add components based on the button click. Here are three templates and my index.html file.
index.html
<!doctype html>
<html lang="en">
<head>
</head>
<body>
<div id="app">
<div class="container">
<div id="dynamic_components">
<!-- add components here -->
</div>
<addcard></addcard>
</div>
</div>
<script src="{{ asset('js/app.js') }}"></script>
</body>
</html>
AddCard.vue
<template>
<div class="buttons">
ul class="no-margin-list">
<li #click="imagecard">
<span class="card_icon">
<img :src="'img/image.jpg'" >
</span>
<p>Add Image Card</p>
</a>
</li>
<li #click="videocard">
<span class="card_icon">
<img :src="'img/video.jpg'" >
</span>
<p>Add Video Card</p>
</a>
</li>
</div>
</template>
<script>
export default {
computed: {
},
methods: {
imagecard(val) {
//how to add image card
},
videocard() {
//how to add video card
}
},
}
</script>
ImageCard.vue
<template>
<h1> I am a image Card </h1>
</template>
<script>
</script>
VideoCard.vue
<template>
<h1> I am a Video Card </h1>
</template>
<script>
</script>
I need to add components dynamically one after another in the <div id="dynamic_components"> . User can add as many as cards they want.
How do I add the components dynamically. Please point me to a tutorial.
Uses v-for + dynamic component.
Vue.config.productionTip = false
Vue.component('card1', {
template: '<div>Card:<span style="background-color:green">{{title}}</span></div>',
props: ['title']
})
Vue.component('card2', {
template: '<div>Card:<span style="background-color:blue">{{title}}</span></div>',
props: ['title']
})
Vue.component('card3', {
template: '<div>Card:<span style="background-color:yellow">{{title}}</span></div>',
props: ['title']
})
new Vue({
el: '#app',
data() {
return {
cards: [
{'card': {'title': 'I am one card1'}, 'card-type':'card1'},
{'card': {'title': 'I am one card2'}, 'card-type':'card2'}
]
}
},
computed: {
computedNoCard1: function () {
let availableCards = new Set(['card2', 'card3'])
return this.cards.filter((item) => {
return availableCards.has(item['card-type'])
})
}
},
methods: {
addCard: function () {
let supportedCards = ['card1', 'card2', 'card3']
let seed = Math.floor(Math.random()*supportedCards.length)
this.cards.push({'card': {'title': 'I am new card for ' + supportedCards[seed]}, 'card-type': supportedCards[seed]})
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="app">
<button #click="addCard()">Add Card</button>
<table>
<tr><th>Data Property</th><th>Computed Property</th></tr>
<tr>
<td>
<div v-for="(card, index) in cards" :key="index">
<component :is="card['card-type']" :title="card.card.title">
</component>
</div>
</td>
<td>
<div v-for="(card, index) in computedNoCard1" :key="index">
<component :is="card['card-type']" :title="card.card.title">
</component>
</div>
</td>
</tr>
</table>
</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 = [];
}