alpine js how to total x-for items - sum

thought this was going to be pretty simple but how could i iterate through template x-for items -doing a sum calculation to output at the end.. [or even if i already have the total in the sourcedata - how to output as the last row? i.e how to x-if last row ]
e.g.
<template x-for="catalogxbdata in catalogxbdatax" :key="catalogxbdata.Part">
<div class="table-row">
<Div class="table-cell"></div>
<Div class="table-cell" x-text="catalogxbdata.Price"></div>
<Div class="table-cell" x-text="?total here"></div> <--- but only if last row
</Div>
</template>
<Div class="table-cell"> </div>
<Div class="table-cell" x-text="?total here"></div> <-- or here, but this is outside of template

posting the answers in case someone has the same ..
<script>
function setVals() {
return {
total_c1:0,
total_c2:0,
settotalifindata(valx)
{
this.total_c1=valx;
},
//or
settotal(valx)
{
this.totalc2+=valx;
}
}
}
</script>
<div id="a0" class="p-1" x-data="setVals()">
<template x-for="catalogxbdata in catalogxbdatax" :key="catalogxbdata.Part">
<div class="table-row">
<Div class="table-cell"></div>
<Div class="table-cell" x-text="catalogxbdata.Price"></div>
<div class="table-cell" x-show="false" x-text="settotalifindata(catalogxbdata.total)"></div>
<div class="table-cell" x-show="false" x-text="settotal(catalogxbdata.Price)"></div>
<Div class="table-cell" x-text="total_c1"></div> <--- but only if last row
</Div>
</template>
<Div class="table-cell"> </div>
<Div class="table-cell" x-text="total_c2"></div>
</div>

I also work like this! But functions settotal was undefined!
So, I fix the issue. The issue was version of alpinejs.
https://unpkg.com/alpinejs#3.x.x/dist/cdn.min.js
Hopefully your problem will be solve!

Related

Jquery to Vue js need traversing child nodes

I need help to convert jQuery code to Vue js
<div class="single-why" v-for="(single, index) in data" :key="index">
<div class="content">
<h5 class="mt-3">100% Certified </h5>
</div>
<div class="hover-content" style="display:none">
<h5>100% Certified Jewellery</h5>
</div>
</div>
Here I need: when hover on .single-why , need to show .hover-content
as in jQuery
$('.single-why').on('hover', function (){
$(this).children('.hover-content').show()
})
Please suggest me using vue.
Thanks
You use #mouseover and #mouseleave events. In a loop you have to account for element index, so instead of using a boolean to show the hovered element, you use its index.
<div
class="single-why"
v-for="(single, index) in data"
:key="index"
#mouseover="hoverIndex = index"
#mouseleave="hoverIndex = null"
>
<div class="content">
<h5 class="mt-3">100% Certified </h5>
</div>
<div class="hover-content" v-show="hoverIndex === index">
<h5>100% Certified Jewellery</h5>
</div>
</div>
data(){
return {
hoverIndex: null
}
}

Nuxt.js/Vue.js dynamic images is not working

I'm getting some data from an API that contains an image and some other information. Now there's a problem in Nuxt js or maybe I'm wrong. Whenever I supply the path to the image in the :src it just doesn't work.
Here's my code:
<div v-for="(project, index) in projects" :key="project.p_id" class="swiper-slide">
<div :id="`index_${index}`" class="slide_wrapper">
<div class="background">
<img :src="getImgUrl(project.p_img_path)" alt="project cover image" />
</div>
<div class="details">
<div>
<div class="left">
<h2 style="color: black !impor tant">{{ project.p_label }}</h2>
<small>{{ project.p_date }}</small>
</div>
<div class="right">
<nuxt-link class="btn btn-secondary" to="/" #click="readMore">
<i class="fas fa-ellipsis-h"></i>
</nuxt-link>
</div>
</div>
</div>
</div>
</div>
script:
props: ['projects'],
methods: {
readMore() {},
getImgUrl(path) {
return '../../../' + path
},
},
Last thing, whenever I use required required('./assets/'+image.jpg') nuxt.js crushes in compilation always stops at 69%. I also tried required.context but it didn't work as well.
Any help will be appreciated. Thanks in advance.
In your template, change:
<img :src="getImgUrl(project.p_img_path)" alt="project cover image">
To:
<img :src="require(`../assets/${project.p_img_path}`)" alt="project cover image">
You shouldn’t need a method to return the path as a string, just use a template literal as above.
Ps. This assumes project.p_img_path = img/project_img/filename.jpg, so adjust as necessary.
The solution is that I had to put all the images inside the assets folder directly. Thank you all for your time.

How to make iterations using v-for directive on nested array (array in array)

I am new to Vue and I came upon a situation that I would like to have some advice on.
In my js file I have some arrays that contain some data that I would like to insert in a table:
const d1=[{col1:"aaa1",col2:"bbb1",col3:"ccc1",col4:"ddd1",col5:"eee1"},
{col1:"aaa2",col2:"bbb2",col3:"ccc2",col4:"ddd2",col5:"eee2"}]
const d2=[{col1:"fff1",col2:"ggg1",col3:"hhh1",col4:"iii1",col5:"jjj1"},
{col1:"aaa2",col2:"bbb2",col3:"ccc2",col4:"ddd2",col5:"eee2"}]
then I saved the two arrays in another variable called availableData
const availableData=[d1,d2];
my vue instance as follows:
new Vue({
el: '#c1',
data: {
availableData,
}
});
In my HTML I am trying to add a for loop(v-for) in my row div so the row can display each of data in my availableData variable, but I am having some problems trying to pass d1 to the first row and d2 to the second,
<div id="c1" class="columns">
// ...some code
<div class="row" v-for="data in availableData">
<div class="cell">
{{data.col1}}
</div>
<div class="cell">
{{data.col2}}
</div>
<div class="cell">
{{data.col3}}
</div>
<div class="cell">
{{data.col4}}
</div>
<div class="cell">
{{data.col5}}
</div>
</div>
</div>
Of course, the v-for statement is not correct since I am trying to iterate through the availableData array, if I were to write
v-for="data in availableData[i]"
then is there a way to pass a varaible like i to achieve iteration, or is this method not a plausible way to conduct?
You have several solutions to do what you want.
Solution # 1 :
You can alter the availableData to display all data like you want. You have just to flat you array like this : const availableData=[...d1, ...d2];
With such a code your availableData variable will have :
const availableData = [{col1:"aaa1",col2:"bbb1",col3:"ccc1",col4:"ddd1",col5:"eee1"},
{col1:"aaa2",col2:"bbb2",col3:"ccc2",col4:"ddd2",col5:"eee2"},
{col1:"fff1",col2:"ggg1",col3:"hhh1",col4:"iii1",col5:"jjj1"},
{col1:"aaa2",col2:"bbb2",col3:"ccc2",col4:"ddd2",col5:"eee2"}]
Solution # 2
You can make a double iteration in your template :
<div class="data" v-for="data in availableData">
<div class="row" v-for="row in data">
<div class="cell">
{{row.col1}}
</div>
<div class="cell">
{{row.col2}}
</div>
<div class="cell">
{{row.col3}}
</div>
<div class="cell">
{{row.col4}}
</div>
<div class="cell">
{{row.col5}}
</div>
</div>
</div>

adding component on add button

i am a absolute beginner in vuejs,i have a feature of adding dynamic input fields on click of a button it will keep on adding rows and keeping in mind the counter should be incrementing also so that i can validate on backend, this is my code so far
<div id="settlement_container" class="container-fluid mt-4">
<div class="card rounded-0 shadow-lg">
<div class="card-body p-0">
<div class="card-header px-2">
<div class="row wow fadeIn">
<div class="col-5">
<h3>Add Store Status</h3>
</div>
</div>
</div>
<form class="custom-form-group" action="{{url('stores/addStoreStatusDB')}}" method="POST">
<div class="form-group col-6">
<label for="exampleInputEmail1">Tax</label>
<input type="text" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" name="tax" placeholder="Tax" required>
</div>
<div class="display-inline">
<div class="form-group col-md-6">
<button #click="addstatus" class="btn btn-primary">Add Rows</button>
</div>
</div>
<div class="display-inline">
<div class="form-group col-md-6">
<button type="submit" class="btn btn-primary">Update Tax</button>
</div>
</div>
<dynamic-rows/>
</form>
</div>
</div>
</div>
{{-- Main layout --}}
#push('script')
<script src="{{ asset('js/app_vue.js') }}" ></script>
<script>
Vue.component('dynamic-rows',{
//accept data inside template
props:['counter'],
//accept data inside template
template:"<label for='exampleInputEmail1'>counter</label>"
});
const app = new Vue({
el: '#settlement_container',
data: {
counter:0
},
component:['dynamic-rows'],
methods:{
addstatus:function(e){
appendDiv=""
e.preventDefault();
alert("inside");
}
}
});
</script>
now i can do this in jquery in 5 minutes , but as i am beginner in vuejs i cant developer the sense of it of how to do it, i have a component and i want to repeat the component every time the button is clicked,
here is the fiddle! fiddle
OK, so a lot going on here and I think it may be easier to break down some of the points in isolation for you to play with and learn.
To add inputs, I think it makes more sense to have the values being in an array. Using Vue, you can iterate through that array to let each array element have its own <input/> while also simply adding another array element to add a new input:
<template>
<div>
<div v-for="(tax, index) in taxes" :key="index">
<input v-model="taxes[index]" />
</div>
<button type="number" #click="add">Add</button>
<p>Count: {{taxes.length}}</p>
</div>
</template>
<script>
export default {
data(): {
return {
taxes: [0]
}
},
methods: {
add() {
this.taxes.push(0);
}
}
});
</script>
Now with regards to the counter, I don't know what you mean validate on the backend. You could add a watcher on the taxes array and process changes there? Watchers are used sparingly, with computed properties being much preferred, but they may make sense if you need to be sending data to the backend instead of into the DOM.
The counter prop you registered in your code is not really going to work for the pattern I showed. Generally, props are for parent components to pass data to child components. The preferred pattern when sending data from child to parent is to use $emit. Read more here.

changing dinamically class and id on vue components

i'm a bit new to vue, and maybe i'm trying to do something that is not doable.
i have this skeleton:
<div class="row"> <!--FIRST ROW-->
<skills-list></skills-list>
</div>
<div class="row"> <!--SECOND ROW-->
<skills-list></skills-list>
</div>
<div class="row"> <!--LAST ROW-->
<skills-list></skills-list>
</div>
now i have three row, each of them contain a vue custom component, this is my app:
Vue.component('skills-list', {
template: `
<div class="col-xs-12 col-sm-12 col-md-4 col-lg-4">
<div class="text-center">
<i :class="skills[0].class"></i>
</div>
<div class="progress-container">
<div class="progress" :id="skills[0].id"></div>
</div>
</div>
`,
data: function(){
return {
skills : [
{'class':'icon-html5-alt skills_icon','id':'#progress-html'},
{'class':'icon-css3-alt skills_icon','id':'#progress-css'},
{'class':'icon-javascript-alt','id':'#progress-js'}
]
}
}
});
new Vue({
el: '#cv_app',
});
my custom component template has two dinamic value, the class and the id, that are listed in the skills array.
i want to fill those value for every template i insert in the html code, i mean: replace in some way :class="skills[0].class with :class="skills[i].class iterating over the skills array.
Hope i explain my self clear, is it possible?