I want to show Filtered products in Vue Js based upon the selection made by user in 3 diffrent parameters from All products - vue.js

This is step 1 which will appear & user will select one category from this
<div class="w-100 text-center step-div py-5">
<h3>step 1 </h3>
<p class="step-p"> for Men, Women or Unisex</p>
<div class="container">
<div id="categorytype" class="responsive">
<div v-for="(type,typeIndex) in types" class="filter-slider-div col-4 p-5" #click= "addfiltertype(typeIndex,type.typeslug)">
<img :src="type.typeImage" class="filter-img mx-auto">
<p>{{type.typename}}</p>
</div>
</div>
</div>
</div>
Out put will be something like Men,Women,Both,Kids etc & On click It is saving slug of this type. which I'll share below,
<h3>step 2 </h3>
<p class="step-p">Select your case size</p>
<div class="container">
<div id="categorydials" class="responsive">
<div v-for="(dial,dialIndex) in dials" class="filter-slider-div col-4 p-5" #click= "addfilterdial(dialIndex,dial.dialname)">
<img :src="dial.dialimage" class="filter-img mx-auto">
<p>{{dial.dialname}}mm</p>
</div>
</div>
</div>
In step 2 User will select Size it can be anything,
<h3>step 3 </h3>
<p class="step-p">Select your case colour</p>
<div class="container">
<div id="categorycolors" class="responsive">
<div v-for="(color,colorIndex) in colors" class="filter-slider-div p-5" #click= "addfiltercolor(colorIndex,color.colorslug)">
<img :src="color.colorimage" class="filter-img mx-auto">
<p>{{color.colorname}}</p>
</div>
</div>
</div>
In Step 3 User will select Colour
Now After this I am updating & saving the slug of these categoies in my js in method
Here is code how my Categories are coming from & saving the category slug in typeslugFilter
I used alert Js to check if it's working & saving correctly or not & It's Saving the exact slug,
var filters = new Vue ({
el: '#categorytype',
data:{
types: [
{
typeId: 1,
typename: 'Men',
typeImage: 'assets/images/filter1.png',
typeslug: 'men',
},
{
typeId: 2,
typename: 'Women',
typeImage: 'assets/images/filter2.png',
typeslug: 'women',
},
{
typeId: 3,
typename: 'Watches',
typeImage: 'assets/images/filter3.png',
typeslug: 'both',
}
] },
methods: {
addfiltertype (typeIndex,typeslug) {
this.typeslugFilter = typeslug;
// alert(this.typeslugFilter+ '+' + typeslug);
}
}
});
Consider similar code for other two categories with variable dialnameFilter & colorslugFilter,
Now I am trieng to fetch filtered products using below code it's not working for me as of now
I am getting my products from json file & they are working fine I am using typeslug & dialname as category type in single product details & using productslider as el: element .
<div id="productslider" class="container py-5">
<p>{{typeslugFilter}}</p>
<div v-for="(variant,variantIndex) in variants" v-if="typeslugFilter === typeslug && dialnameFilter === dialname">
<div class="watch-slider-div">
<img :src="variant.variantImage" class="w-100 py-3">
</div>
</div>
</div>
Please help me out in this If any tech geek an help will be appreciated

Related

How to display a string value in template section in vue.js?

I developed one page which is responsible for showing order success message and i am getting response from backend which contains orderId ,i am getting that response and i am able to bind in front end but i am getting my output as a json format in my UI page ,but what i need is to display only orderID value only (like a string).please help me to fix this issue...
i want to display orderID value only
OrderPlace.vue
<template>
<div class="order-place">
<div class="image-container">
<img src="../assets/success.png" alt="not found" />
</div>
<div class="title-container">
<p>Order placed Successfully</p>
</div>
<div class="message-section">
<p>Hurray!!!your order is confirmed and placed successfully contact us in below details
for further communication..</p>
</div>
<div class="order-id">
{{orderNumber}}
</div>
<div class="title-section">
<div class="email-us">
<p>Email-us</p>
</div>
<div class="contact-us">
<p>Contact-us</p>
</div>
<div class="address">
<p>Address</p>
</div>
</div>
<div class="email-sec">
<p>admin#bookstore.com</p>
</div>
<div class="contact-sec">
<p>+918163475881</p>
</div>
<div class="address-sec">
42, 14th Main, 15th Cross, Sector 4 ,opp to BDA complex, near Kumarakom restaurant, HSR Layout, Bangalore 560034
</div>
<div class="button">
<router-link to="/dashboard" class="btn">Continue Shopping</router-link>
</div>
</div>
</template>
<script>
import service from '../service/User';
// import { EventBus } from "./event-bus.js";
export default {
name: 'OrderPlace',
data(){
return{
successTitle:'Order placed Successfully',
adminEmailSection:'Email-us',
adminContactSection:'Contact-us',
adminAddressSection:'Address',
adminEmail:'admin#bookstore.com',
adminMobNum:'+918163475881',
orderNumber: ''
}
},
created() {
service.confirmMail().then(response =>
(this.orderNumber=JSON.stringify(response.data))
)
}
}
</script>
You're stringifying an Object of { message: string; orderId: number } which of course will result in that "string" of an Object being displayed when you use
<div class="order-id">
{{orderNumber}}
</div>
Like Boussadjra said just assign the id to the corresponding data field
service.confirmMail().then(response =>
(this.orderNumber=response.data.orderId)
)
Just assign the orderID to the orderNumber:
service.confirmMail().then(response =>
(this.orderNumber=response.data.orderID)
)

Populate Knockout's observable array from Razor

I'm trying to implement error handling in ASP.NET so that if there is an error the user will get the error message, then be able to go back and have the previous state restored. I'm using ASP.NET Core and Knockout (not my implementation). I want to update "signerFields" with the model from the server (Model.SignersJson). How would I do this?
Signer.js
function SignerViewModel() {
var self = this;
self.signerFields = ko.observableArray([]);
self.guarantorFields = ko.observableArray([]);
self.companyGuarantorFields = ko.observableArray([]);
...
Signer.cshtml
<div data-bind="foreach: signerFields, visible: signerFields().length > 0">
<div class="row">
<div class="col-lg-10">
<div>
#*Header Company signers section*#
<div class="row" data-bind="visible: isCompany() && !anySigner() && !isInvitation()" style="display: none">
<div class="col-lg-4">
<b>FullName</b>
</div>
#*<div class="col-lg-3">
<b>LastName </b>
</div>*#
<div class="col-lg-4">
<b>Role </b>
</div>
<div class="col-lg-3">
<b>Contact_Information</b>
</div>
</div>
</div>
</div>
...
#section scripts
{
<script src="~/Scripts/Signer.js"></script>
var serverSigners = JSON.parse(#Html.Raw(Json.Encode(Model.SignersJson)));
var observableData = ko.mapping.fromJS(serverSigners);
var viewModel = new SignerViewModel();
viewModel.signerFields(observableData); // <-- How?
}
I get no error messages, nothing.
There is a lot of unknowns with this one, but here is a working example using the information we have at hand. One thing I noticed was when creating this sample was that I assumed the data comming from Razor was in an array. and when the array is passed into the mapping component it comes out as an observable array. This meant that the data going into the signerFields was probably not what you were expecting and ended up having an observableArray with one object which itself was an observable array. Adding round brackets to observableData() means that you get the data out of the observable and you can then pass it into the signerFields as an array of objects.
Hope that made sense.
function SignerViewModel() {
var self = this;
self.signerFields = ko.observableArray([]);
self.guarantorFields = ko.observableArray([]);
self.companyGuarantorFields = ko.observableArray([]);
}
var serverSigners = [{'fullname':'Test Name', 'lastName': 'Name', 'role': 'Test Role', 'contactInformation': '123 Seasame Street NY, US', 'isCompany': true, 'anySigner': false, 'isInvitation': false}];
var observableData = ko.mapping.fromJS(serverSigners);
var viewModel = new SignerViewModel();
viewModel.signerFields(observableData());
ko.applyBindings(viewModel)
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.min.js"></script>
<div data-bind="foreach: signerFields, visible: signerFields().length > 0">
<div class="row">
<div class="col-lg-10">
<div>
<div class="row" data-bind="visible: isCompany() && !anySigner() && !isInvitation()">
<div class="col-lg-4">
<b>FullName: </b><span data-bind="text: fullname"></span>
</div>
<div class="col-lg-3">
<b>LastName: </b><span data-bind="text: lastName"></span>
</div>
<div class="col-lg-4">
<b>Role: </b><span data-bind="text: role"></span>
</div>
<div class="col-lg-3">
<b>Contact Information: </b><span data-bind="text: contactInformation"></span>
</div>
</div>
</div>
</div>
</div>
</div>

Carousel not working in Vue js but working in simple php file

I am using owl.carousel in my vue app. But carousel is not showing up on the page. I have include (owl.carousel.min.css) and other relevant files(jquery,bootstrap) inside my index.html. These files can also be seen in network tab of the browser which mean files are loading but no carousel(or images) are seen.When I remove owl.carousel.min.css from index, it displays images used inside carousel on top of one another but no carousel. Any idea what the issue might be..??Thank you.
<div class="banner-slider">
<div class="container">
<div class="row">
<div class="carousel-wrap">
<div id="sync2" class="navigation-thumbs owl-
carousel">
<div class="item">
<img src="./images/bslide4.png">
<div class="details">
<p>Alex</p>
<small>Guitarist</small>
</div>
</div>
<div class="item">
<img src="./images/bslide1.png">
<div class="details">
<p>MIRA</p>
<small>Filmmaking</small>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
And
var sync1 = $(".slider");
var sync2 = $(".navigation-thumbs");
var thumbnailItemClass = '.owl-item';
var slides = sync1.owlCarousel({
video:true,
startPosition: 3,
items:1,
loop:true,
margin:10,
autoplay:true,
autoplayHoverPause:false,
nav: false,
dots: true,
responsive: {
0: {
items: 1,
loop:true
},
600: {
items: 1,
loop:true
},
1000: {
items: 1,
loop:true
}
}
}).on('changed.owl.carousel', syncPosition);

Vue.js how to use radio buttons inside v-for loop

I'm trying to use radio buttons, so that users can choose one of the photos as their profile photo:
<ul v-for="p in myPhotos">
<li>
<div>
<div>
<div>
photo id: {{p.imgId}}
</div>
<input type="radio" v-model="profileImg" value="p.imgId"> Choose as profile image
</div>
<div><img v-bind:src="BASE_URL +'/uploads/' + userId + '/'+ p.imgId" /> </div>
</div>
</li>
</ul>
The values are otained like this:
created () {
axios.get(this.BASE_URL + '/profile/g/myphotos/', this.jwt)
.then( res => {
this.myPhotos = res.data.photos;
this.showUploadedPhoto = true;
this.profileImg = res.data.profileImg
})
.catch( error => {
console.log(error);
})
},
When an photo is chosen, the profileImg variable should be set to that photo's imgId.
The problem is how to let users to choose only one photo as profile image inside this v-for loop?
Update: a photo my myPhotos object that I'm iterate over:
By providing name you can treat it as one element
var app = new Vue({
el:"#app",
data:{
images:[{imgId:1},{imgId:2},{imgId:3}],
profileImg:2
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div>
<div v-for="image in images">
<input type="radio" v-model="profileImg" name="profileImg" :value="image.imgId"> Choose as profile image
</div>
You have selected : {{profileImg}}
</div>
</div>
How about setting name attribute for the input field
<ul v-for="p in myPhotos">
<li>
<div>
<div>
<div>
photo id: {{p.imgId}}
</div>
<input type="radio" name="user_profile_photo" v-model="profileImg" :value="p.imgId"> Choose as profile image
</div>
<div><img v-bind:src="BASE_URL +'/uploads/' + userId + '/'+ p.imgId" /> </div>
</div>
</li>
</ul>

Vue js event not picked up

I have just started experimenting with vue js and I am building a checkout form with it. I am also using Symfony 31 for the project. On the checkout/signup page I have an embedded collection of forms representing order items (each are subscription to a type of product). You can select multiple items by ticking a checkbox. You can also change the quantity. Unfortunately I cannot manage to pass the quantity update to the Vue instance. The entries are registered on render with the quantity 1, and if I change the quantity and then select the item, the price is calculated correctly, but the app registers this as a new entity. The binding with the quantity is not working. I will also need to add a similar field called frequency and I know I will have the same problem. Help?
Here is the js fiddle: https://jsfiddle.net/wavsu8xm/
Javascript:
var bus = new Vue();
var entriesComponent = Vue.component('entries', {
template: '#entries',
props: {
entries: [Array, Object],
selected: Array,
addons: Array,
frequencies: [Array, Object],
},
watch: {
selected: function(val, oldVal) {
bus.$emit('selected-changed', val);
},
}
});
new Vue({
el: '#app',
data: {
entries: [],
selected: [],
addons: [],
frequencies: [],
paymentConfig: {
advance: 25,
firstweek: 25,
ondelivery: 50,
},
weeks: 12,
},
components: {
'entriesComponent': entriesComponent,
},
created: function() {
// store this to use with Vue.set
var temp = this;
bus.$on('selected-changed', function(selected) {
// vm.$set deprecated
Vue.set(temp, 'selected', selected);
});
},
computed: {
totalAdvance: function() {
return (this.paymentConfig.advance * this.total) / 100;
},
totalFirstWeek: {
get: function() {
return (this.paymentConfig.firstweek * this.total) / 100;
},
},
onDeliveryPayment: {
get: function() {
return (this.paymentConfig.ondelivery * this.total) / (this.weeks * 100);
}
},
total: {
get: function() {
var sum = 0;
var weeks = this.weeks;
this.selected.forEach(function(item) {
sum += weeks * item.itemPrice * item.quantity;
});
console.log(sum);
return sum;
}
}
}
});
Template:
<section class="content">
<div class="row" id="app">
<div class="col-md-8">
<div class="box box-primary">
<div class="box-body">
<div class="row">
<div class="col-md-12">
<div class="form-group">
<label class="control-label required">Items</label>
<div class="col-md-12">
<entries :entries="{ 0 : { shareSize : 'Small', quantity : '1', itemPrice : '24', frequency : '' }, 1 : { shareSize : 'Medium', quantity : '1', itemPrice : '35', frequency : '' }, 2 : { shareSize : 'Large', quantity : '1', itemPrice : '46', frequency : '' } }"
:selected="selected"></entries>
<!-- component template -->
<template id="entries">
<div class="col-md-12">
<div class="form-group" v-for="(entry, key) in entries" v-bind:entry="entry">
<div class="form-group col-md-12">
<div class="col-md-12">
<div class="col-md-4">
<input type="checkbox" v-bind:value="entry" v-model="selected">
</div>
<div class="col-md-4">{{entry.shareSize}}</div>
<div class="col-md-4">{{'$ ' + Number(entry.itemPrice).toFixed(2) }}</div>
</div>
<div class="form-group col-md-12">
<div class="col-md-6">
<input type="number" v-model="entry.quantity" :value="entry.quantity" />
</div>
</div>
</div>
</div>
</div>
</template>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-4">
<div class="box box-info">
<div class="box-body" style="padding:15px;">
<div class="container-fluid">
<div class="form-group">
<div class="control-label">
<label>Summary</label>
</div>
<div class="form-control" v-for="item in selected">
<span class="pull-left small-box-footer">{{ item.shareSize }}</span>
<span class="pull-right">{{ item.quantity + ' x $ ' + (item.itemPrice*item.quantity).toFixed(2)}}</span>
</div>
<div class="control-label">
<label>Payment plan</label>
</div>
<div class="col-md-12">
{{ '$ ' + totalAdvance.toFixed(2) }} - advance
</div>
<div class="col-md-12">
{{ '$ ' + totalFirstWeek.toFixed(2) }} - first week
</div>
<div class="col-md-12">
{{ '$ ' + onDeliveryPayment.toFixed(2) }}/ week on each of the {{ weeks }} weeks of the subscription
</div>
<div class="col-md-12 row">
<div class="control-label"><strong><span class="pull-left">Total</span><span class="pull-right">{{ '$ ' + total.toFixed(2) }}</span></strong></div>
</div>
<div class="col-md-12 row">
<div class="title"><strong><span class="pull-left">Total due now</span><span class="pull-right">{{ '$ ' + totalAdvance.toFixed(2) }}</span></strong></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
You are mutating your props directly which will get overwritten when the parent component re-renders, so you need to make a copy of them inside your component, which can be done inside the created method of your component:
created: function() {
// copy props to data
this.entriesCopy = this.entries;
this.selectedCopy = this.selected;
},
data: function() {
return{
entriesCopy: [],
selectedCopy: []
}
}
Now you just need to update your watcher:
watch: {
selectedCopy: function(val, oldVal) {
bus.$emit('selected-changed', val);
}
}
And your template:
//...
div class="form-group" v-for="(entry, key) in entriesCopy" v-bind:entry="entry">
//...
<input type="checkbox" v-bind:value="entry" v-model="selectedCopy">
to reflect the changes.
Here's the updated jsfiddle: https://jsfiddle.net/5pyw74h9/