Vuejs show/hide condition - javascript

Adding and removing dynamic items is functioning. I'm wanting to additionally show/hide elements under each. However, when I "show/hide" it toggles all. How can I call only the current index (toggle method?)
var app = new Vue({
el: '#app',
data: {
inputProject: [],
counter:0,
active : false
},
methods: {
addInput: function() {
this.inputProject.push(this.counter);
this.counter++
},
removeInput: function(index) {
this.inputProject.splice(index,1);
},
toggle: function (index) {
this.active = !this.active;
}
}
})
Jsfiddle here: https://jsfiddle.net/rhgz83e2/30/

What you are doing wrong is that you change active property and it is reflected for all elements.
The solution is to assign active property for every object and use v-show directive.
<p v-show="elem.active" v-bind:id="elem.id">show {{push}}</p>
working fiddle.
var app = new Vue({
el: '#app',
data: {
inputProject: [],
counter:0
},
methods: {
addInput: function() {
this.inputProject.push({id:this.counter,active:false});
console.log(this.inputProject);
this.counter++
},
removeInput: function(index) {
this.inputProject.splice(index,1);
},
toggle: function (index) {
var item= this.inputProject.filter(a=>a.id==index)[0];
item.active=!item.active;
}
}
})

Related

vue.js multi select change options inside axios GET

Hi I'm using this modified wrapper to handle a multiple select for vue.js. I'm trying to change value of this inside vue component. Here is my code.
<select2-multiple :options="car_options" v-model="input.classification">
<option disabled value="0">Select one</option>
</select2-multiple>
And this is my script,
Vue.component('select2Multiple', {
props: ['options', 'value'],
template: '#select2-template',
mounted: function () {
var vm = this
$(this.$el)
// init select2
.select2({ data: this.options })
.val(this.value)
.trigger('change')
// emit event on change.
.on('change', function () {
vm.$emit('input', $(this).val())
})
},
watch: {
value: function (value) {
alert(value);
if ([...value].sort().join(",") !== [...$(this.$el).val()].sort().join(","))
$(this.$el).val(value).trigger('change');
},
options: function (options) {
// update options
$(this.$el).select2({ data: options })
}
},
destroyed: function () {
$(this.$el).off().select2('destroy')
}
});
var vm = new Vue({
el: '#el',
delimiters: ["[[", "]]"],
data: {
input: {
classification: []
},
},
created: function () {
var vm = this;
axios.get('http://jsonplaceholder.typicode.com/todos')
.then(function (response) {
$.each(response.data, function (i, item) {
response.data[i].id = String(response.data[i].id);
response.data[i].text = String(response.data[i].title);
vm.car_options.push(response.data[i]);
});
vm.input.classification = ["2"];
})
.catch(function (error) {
console.log(error);
});
}
});
I need to get vm.input.classification = ["2"] selected by default. And it's not working and no error message displays. I'm no expert in vue components but I feel like issue relies on vue component.
Here is a js fiddle for my example,
Finally I found the answer. We need to swapp the positions of options and value of component watch.
watch: {
options: function (options) {
// update options
$(this.$el).select2({ data: options })
},
value: function (value) {
if ([...value].sort().join(",") !== [...$(this.$el).val()].sort().join(","))
$(this.$el).val(value).trigger('change');
}
},

Vue watcher executed before the new data is bound?

I am using this code:
var vueApp = new Vue({
el: '#app',
data: {
modalKanji: {}
},
methods: {
showModalKanji(character) {
sendAjax('GET', '/api/Dictionary/GetKanji?character=' + character, function (res) { vueApp.modalKanji = JSON.parse(res); });
}
},
watch: {
'modalKanji': function (newData) {
setTimeout(function () {
uglipop({
class: 'modalKanji', //styling class for Modal
source: 'div',
content: 'divModalKanji'
});
}, 1000);
}
}
});
and I have an element that when clicked on, displays a popup with the kanji data inside:
<span #click="showModalKanji(kebChar)" style="cursor:pointer;>
{{kebChar}}
</span>
<div id="divModalKanji" style='display:none;'>
<div v-if="typeof(modalKanji.Result) !== 'undefined'">
{{ modalKanji.Result.literal }}
</div>
</div>
It works, but only when used with a setTimeout delay to "let the time for Vue to update its model"...if I remove the setTimeout so the code is called instantaneousely in the watch function, the popup data is always "1 iteration behind", it's showing the info of the previous kanji I clicked...
Is there a way for a watcher function to be called AFTER Vue has completed is binding with the new data?
I think you need nextTick, see Async-Update-Queue
watch: {
'modalKanji': function (newData) {
this.$nextTick(function () {
uglipop({
class: 'modalKanji', //styling class for Modal
source: 'div',
content: 'divModalKanji'
});
});
}
}

How do I handle click event on the button inside toastr?

I want to handle the button click event inside the toastr. I am using this library: https://www.npmjs.com/package/vue-toastr-2
This is my code:
var app = new Vue({
el: '#app',
data: {
message: 'vue-toastr-2'
},
created: function() {
this.$toastr.success('Click here to fire an event <button #click="clickMe">Hello</button>', 'Title');
},
methods: {
clickMe() {
alert('Clicked');
// write some more code
}
}
})
Basically I want that when clickMe is clicked, my function inside the component should get called. How would I do this?
This is my jsfiddle: https://jsfiddle.net/75154x8w/2/
var app = new Vue({
el: '#app',
data: {
message: 'vue-toastr-2'
},
created: function() {
this.$toastr.success('Click here to fire an event <button onclick="app.clickMe()">Hello</button>', 'Title');
},
methods: {
clickMe() {
alert('Clicked');
}
}
})

Update dynamic MathJax with Vuejs 2?

P.S: Now i know how to fix this. bind data with v-html
<div id="app">
<h1 v-html="math"></h1>
<button #click='change'>Change</button>
</div>
var vm = new Vue({
el: '#app',
data: function() {
return {
math: '`sum`'
}
},
methods : {
change : function() {
this.math = '`a '+Math.floor((Math.random() * 10) + 1)+'`';
this.$nextTick(function() {
MathJax.Hub.Queue(["Typeset", MathJax.Hub]);
});
}
}
})
When i update data, it duplicate element ???
I dont know why, how to update MathJax with vuejs 2 ?
This is my app: Image
var vm = new Vue({
el: '#app',
data: function() {
return {
math: 'sum'
}
},
methods : {
change : function() {
this.math = 'sum_'+Math.floor((Math.random() * 10) + 1);
this.$nextTick(function() {
MathJax.Hub.Queue(["Typeset", MathJax.Hub]);
});
}
}
})
You could replace the entire contents of the MathDiv element and call MathJax.Hub.Typeset(), but there is a more efficient approach, which is to ask MathJax for the element jax for the mathematics, and call its method for replacing the formula shown by that element. So the updated code will look like:
<div id="app">
<h1 >{{ math }}</h1>
<button #click='change'>Change</button>
</div>
<script>
var vm = new Vue({
el: '#app',
data: function() {
return {
math: '`sum_1`'
}
},
mounted: function () {
this.$nextTick(function () {
MathJax.Hub.Typeset()
})
},
methods : {
change : function() {
this.math = 'sum_'+Math.floor((Math.random() * 10) + 1);
this.$nextTick(function() {
var math = MathJax.Hub.getAllJax("MathDiv")[0];
MathJax.Hub.Queue(["Text", math, this.math]);
});
}
}
})
</script>
Refer: http://docs.mathjax.org/en/latest/advanced/typeset.html#manipulating-individual-math-elements
OR
You could use v-html to bind the data to the element.

Run component method on load vue.js

hey I'm pretty new to Vue.js and I'm trying to accomplish what seems to be a simple thing but I'm, having trouble. Essentially, I need it so every time a component is loaded into the DOM, one of it's methods fire. Here is my current code, I've tried to use v-on:load but it doesn't seem to work.
Vue.component('graph', {
props:['graphId','graphData'],
template: '<canvas v-on:load="{{populateGraph()}}"></canvas>',
methods: {
initGraph: function () {
var settlementBalanceBarChart = new Chart(this.graphId, {
type: "bar",
data: settlementBalanceBarData,
options: settlementBalanceBarOptions
});
},
//this is the function I would like to run
populateGraph: function () {
alert('{{graphId}}');
}
}
});
var vm = new Vue({
el: "#app",
mounted: function(){
}
});
The same code functions fine if I use the v-on:click event
There are instance lifecycle hooks that you can use for that. For example:
Vue.component('graph', {
props:['graphId','graphData'],
template: '<canvas></canvas>',
created: function () {
alert('{{graphId}}');
},
methods: {}
});
You have to call the function prefixed by "this" as following:
var data =
{
cashiers: []
}
var vm = new Vue({
el: '#app',
data: data,
created: function () {
this.getCashiers();
},
methods: {
getCashiers: function () {
vm.cashiers = [];
}
}
});

Categories

Resources