vue.js basic function not working as wanted - vue.js

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>

Related

Vue 3 : Event, emit and props

I have a problem with event, emit and props (and probably some logic too)
I have a component A in which I have a loop with a component B.
In this loop, I have a method to open the modal (which is a component C) but this method is not part of component B.
Like this :
<a>
<!-- MODAL-->
<div v-if="showModal">
<modal-cat #cat="catId = getCatId($event)" #addTx="addTx($event)"></modal-cat>
</div>
<div v-if="transactions.length != 0" class="mx-auto">
<div v-for="tx in transactions" :key="tx">
<div class="mb-2 border border-gray-600 rounded-lg bg-white pt-2 pb-4">
<div class="flex justify-end">
<span
class="inline-flex items-center justify-center h-6 w-6 rounded-full text-lg bg-blue-800 text-white"
#click="showModal = true, txToAdd = tx">
<i class='bx bx-plus'></i>
</span>
</div>
<transaction-data :transaction="tx" :address="walletAddress"></transaction-data>
</div>
</div>
</div>
</a>
In this modal, I fetch some data (in fact, a array of categories) that I also display in a loop.
Like this :
<div class="modal-container">
<div v-for="(categorie) in categories" :key="categorie">
<p #click="$emit('cat', categorie.id)">{{ categorie.name}}</p>
</div>
<div class="modal-footer">
<slot name="footer">
<button class="modal-default-button" #click="$emit('addTx', 'ok')">
OK
</button>
</slot>
</div>
</div>
I need some data from my modal in my component A but I also need some data from my component B in my component A (to add a transactions to a category)
I managed to get the data I wanted like this (And I can get it):
const showModal = ref(false);
const txToAdd = ref({});
const catId = ref(0);
function getCatId(event) {
return event
}
const addTx = (value) => {
if (value === "ok") {
//console.log(txToAdd.value); <= the value are well displayed in the console.
let data = {
tx: txToAdd.value,
catId: catId.value
}
store.dispatch("categories/addTxToCategories", data);
}
}
But in my store, when I try to get the payload, I can't access to the data and I only get the payload object.
Is there something wrong with my logic ? What am I doing wrong ?
EDIT
I just need to wrap the result in spread operator, like this :
const addTx = (value) => {
if (value === "ok") {
//console.log(txToAdd.value);
let data = {
tx: {...txToAdd },
catId: catId.value
}
store.dispatch("categories/addTxToCategories", {...data });
}
}
And in my store, the payload MUST be the second argument :
async addTxToCategories({ commit }, payload) {}

How to bind change on text area to v-model value?

I have this checkbox that will generate raw HTML on textarea, then generate whatever contain in textarea to the picture on top of the form, on that textarea, I want to be able to edit the text to customize the data position on the image.
The checkbox and the pic work fine, but when I edit data on the textarea, it reverts back, and of course, the rendered HTML reverts back too. And 1 more thing, I have to open the vue extension on inspecting menu to get all DOM rendered
Pic render code
<template>
<div class="card-item container-fluid mt--7">
<div class="card-item__cover">
<img v-if="form.img" :src="background" class="imageBackground" />
<div
v-if="previewImage"
class="imageBackground"
:style="{ 'background-image': `url(${previewImage})` }"
></div>
</div>
<span v-html="htmlBaru"></span>
</div>
</template>
Textarea
<div class="form-group">
<label class="col-form-label form-control-label">HTML</label>
<textarea
ref="htmlInput"
rows="4"
class="form-control col-sm-10"
v-model="htmlBaru"
#change="pantek"
></textarea>
</div>
Checkbox
checkboxCond() {
var sendKeyData = [];
var newHtml = [];
for (var a = 0; a < this.keyData.length; a++) {
if (this.keyData[a].status) {
newHtml.push(
`<tr>
<td >` +
this.keyData[a].key_readable +
` : {` +
this.keyData[a].key +
`}</td>
</tr>`
);
sendKeyData.push(this.keyData[a].key);
}
}
this.htmlBaru = this.html + newHtml.join("\r\n") + this.footer;
this.sendKeyData = sendKeyData;
console.log(this.htmlBaru);
// return this.htmlBaru;
}
Onchange
methods: {
pantek() {
// console.log(this.htmlBaru);
this.htmlBaru = this.$refs.target.value;
// this.$emit("change", this.htmlBaru);
},
}

how to patchvalue in edit page of nested array in angular8?

html code:(Here i added the html code to iterate the nested array which i want to get the value in edit page ) getMaterialListArray(i) => this method should iterate the array values when i click the select+ button.
<p>Sub Recipes</p>
<div formArrayName="recipeArray" *ngFor="let item of recipeArray.controls; let i = index;">
<div [formGroupName]="i" class="add-div" >
<mat-accordion>
<mat-expansion-panel>
<mat-expansion-panel-header>
<mat-panel-title>
Sub Recipe{{i+1}}
</mat-panel-title>
</mat-expansion-panel-header>
<div class="add-div">
Material
<mat-list role="list" formcontrolName="material">
<mat-list-item role="listitem" *ngFor="let data of getMaterialListArray(i)">
<div class="file-name">
<span>{{data.title}}</span>
<div>{{item.wt_in_kgs_per_unit}}{{item.uom}}</div>
<div class="btn-custom" (click)="deleteMaterial(data, i)">Delete</div>
</div>
</mat-list-item>
</mat-list>
</div>
<div class="btn-custom" (click)="addMaterial(i)">select+</div>
<br><br>
<div class="add-div">
otherFormulation
<mat-list role="list">
<mat-list-item role="listitem" *ngFor="let form of getFormulationListArray(i)">
<div class="file-name">
<span>{{form.title}}</span>
<div>{{form.batch_qty}}{{form.unit_type}} </div>
<div class="btn-custom"(click)="deleteOtherFormulation(form, i)">Delete</div>
</div>
</mat-list-item>
</mat-list>
</div>
<div class="btn-custom" (click)="addOtherFormulation(i)">select+</div>
</mat-expansion-panel>
</mat-accordion>
</div>
</div>
component.ts:(commented lines are gives an error. please give me an solution to patch value from nested array) the pattern of an array)
List : [] = array[{
internalCode:Fo-3684,
title:biscuit,
refer_subrecipe:[{
material_id:[{ title:biscuit,
internalCode:Fo-3434
},
{
title:cake,
internalCode:Fo-3488
}]
}],
Refer_packaging:[{
material_id:[{
title:candywrapper,
uom:10kg
},
{
title:candypack,
uom:20kg
}]
}] like this....
this.formulationForm.patchValue({internalCode : result.internalCode,
myCode:result.myCode,
title : result.title,
unitsOfMeasurement:result.unit_type,
batchQuantity:result.batch_qty,
productType:result.product_type,
// recipeArray: {
// material:result.Refer_SubRecipe.material_id.title,
// otherformulations:result.Refer_SubRecipe.material_id.title
// },
// packageArray:{
// packMaterial:result.Refer_Packaging.material_id.title,
// UOM:result.Refer_Packaging.material_id.uom,
// weight:result.Refer_Packaging.material_id.wt_in_kgs_per_unit,
// Quantity:result.Refer_Packaging.material_id.quantity
// },
allergen:this.alergenList,
shelf_life:this.alergenList,
operational_instruction:result.ops_instructions,
version_no:result.version,
version_date:result.version_date,
approved_by:result.approved_by,
remarks: result.remarks });
}
})
this.recipeArray = this.formulationForm.get('recipeArray') as FormArray;
this.packageArray = this.formulationForm.get('packageArray') as FormArray;
}

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

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 = [];
}