Output image depending on selection vue.js - javascript

I am relatively new to vue.js and I am having a bit of difficulty. I want to show the images of NBA players depending on the selection using vue.js. For example: If the Dunk contest champion is selected: the image of only Kobe and Jordan should show up. To know if it should output the image of the player, it has to check the data in an object with key-values called properties, which contain conditions and every NBA player.
I created a variable called checksate initially set to false. I want it to turn true when the condition is met. I created an onChange method for that purpose. I am able to show the images and fill up the selection element by taking the data from the key-value objects. However, I cannot make the selection element and the images work together.
Any ideas?
<head>
<style>
a.incognito{
display: none;
}
</style>
</head>
<body>
<h2>NBA players</h2>
<p>A selection of the best NBA players</p>
<div id="app">
<select #change="onChange()" v-model="selected">
<option value="none">Select filter</option>
<option v-for="property in properties" :value="property.filter"> {{property.filter}}</option>
</select>
<div class="portfolio">
<a v-for="player in players" :href="player.href"
:class="{incognito: checkstate}" :playername="player.name">
<img :src="player.src" alt="" >
</a>
</div>
</div>
<script src="https://unpkg.com/vue#3"></script>
<script>
let app = Vue.createApp({
data() {
return {
players: [{ name: "Mike", href: "https://en.wikipedia.org/wiki/Michael_Jordan", src: "/Test/Michael_Jordan_in_2014.jpg" },
{ name: "Kobe", href: "https://en.wikipedia.org/wiki/Kobe_Bryant", src: "/Test/Kobe_Bryant_2014.jpg" },
{ name: "Lebron", href: "https://en.wikipedia.org/wiki/LeBron_James", src: "/Test/LeBron_James_-_51959723161_(cropped).jpg" },
{ name: "Kd", href: "https://en.wikipedia.org/wiki/Kevin_Durant", src: "/Test/Kevin_Durant_(Wizards_v._Warriors,_1-24-2019)_(cropped).jpg" },
],
properties: [{filter: "Guard position",Mike:true,Kobe:true,Kd:false,LeBron:false},
{ filter: "Foward position",Mike:false,Kobe:false,Kd:true,LeBron:true},
{ filter: "Multiple Championships",Mike:true,Kobe:true,Kd:true,LeBron:true},
{ filter: "Multiple MVP's",Mike:true,Kobe:false,Kd:false,LeBron:true},
{ filter: "Over 6'8",Mike:false,Kobe:false,Kd:true,LeBron:true},
{ filter: "Dunk contest champion",Mike:true,Kobe:true,Kd:false,LeBron:false}],
selected: 'none',
checkstate:false,
}
}, methods: {
onChange() {
const attr = this.properties.find((item) => item.filter === this.selected)
checkstate=this.properties[this.playername]
},
},
props:['playername']
,
})
app.mount('#app')
</script>
</body>

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Website</title>
<style>
a.incognito {
display: none;
}
</style>
</head>
<body>
<h2>NBA players</h2>
<p>A selection of the best NBA players</p>
<div id="app">
<select v-model="selected" >
<option value="none">Select filter</option>
<option v-for="property in properties" :value="property"> {{property}}</option>
</select>
<div >
<a v-for="player in players" :href="player.href" :class="{incognito: !player[selected]}" >
<img :src="player.src" alt="">
</a>
</div>
</div>
<script src="https://unpkg.com/vue#3"></script>
<script>
let app = Vue.createApp({
data() {
return {
players: [{ name: "Micheal Jordan", ID: "0", href: "https://en.wikipedia.org/wiki/Michael_Jordan", src: "/Test/Michael_Jordan_in_2014.jpg", GuardPosition: true, ForwardPosition: false, MultipleChampionships: true, MultipleMVP: true, Over6foot8: false, DunkContestChampion: true },
{ name: "Kobe Bryant", ID: "1", href: "https://en.wikipedia.org/wiki/Kobe_Bryant", src: "/Test/Kobe_Bryant_2014.jpg", GuardPosition: true, ForwardPosition: false, MultipleChampionships: true, MultipleMVP: false, Over6foot8: false, DunkContestChampion: true },
{ name: "Lebron James", ID: "2", href: "https://en.wikipedia.org/wiki/LeBron_James", src: "/Test/LeBron_James_-_51959723161_(cropped).jpg", GuardPosition: false, ForwardPosition: true, MultipleChampionships: true, MultipleMVP: true, Over6foot8: true, DunkContestChampion: false },
{ name: "Kevin Durant", ID: "3", href: "https://en.wikipedia.org/wiki/Kevin_Durant", src: "/Test/Kevin_Durant_(Wizards_v._Warriors,_1-24-2019)_(cropped).jpg", GuardPosition: false, ForwardPosition: true, MultipleChampionships: true, MultipleMVP: false, Over6foot8: true, DunkContestChampion: false },
],
properties: ["GuardPosition", "ForwardPosition", "MultipleChampionships", "MultipleMVP", "Over6foot8", "DunkContestChampion"],
selected: 'none',
checkstate: false,
}
}
})
app.mount('#app')
</script>
</body>
</html>

Related

jquery doesn't work correctly when I call data with Fetch in VueJS?

Owlcarousel-slider works fine when I use below code.
HTML Code:
<div class="banner">
<div class="main-banner owl-carousel" id="homeage-data">
<div class="item" v-for="slider in sliders">
<div v-bind:class="slider.class_type"> <img v-bind:src="slider.image_src" alt="Electrro">
<div class="banner-detail">
<div class="container">
<div class="row">
<div class="col-md-3 col-3" v-if="slider.align_right"></div>
<div class="col-md-9 col-8">
<div class="banner-detail-inner">
<span class="slogan">{{ slider.label }}</span>
<h1 class="banner-title" v-html="slider.banner_title"></h1>
<span class="offer">{{ slider.banner_desc }}</span>
</div>
<a class="btn btn-color big" v-bind:href="slider.button_link" v-if="slider.button_np" target="_blank">{{ slider.button_text }}</a>
<a class="btn btn-color big" v-bind:href="slider.button_link" v-else-if="!slider.button_np">{{ slider.button_text }}</a>
</div>
<div class="col-md-3 col-4" v-if="!slider.align_right"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
JavaScript Code:
<script>
new Vue({
el: '#homeage-data',
data: {
sliders: [
{
"label": "Discover",
"banner_title": "Top Branded for <br>headphone",
"banner_desc": "best selling, and popular.",
"image_src": "images/banner1.jpg",
"button_text": "Shop Now!",
"button_link": "#link",
"class_type" : "banner-1",
"button_np": true,
"align_right": false
},
{
"label": "curved tv",
"banner_title": "Get latest TV models",
"banner_desc": "Get the top brands for TV",
"image_src": "images/banner2.jpg",
"button_text": "Shop Now!",
"button_link": "#link",
"class_type" : "banner-2",
"button_np": false,
"align_right": true
},
{
"label": "Premium",
"banner_title": "drone cameras",
"banner_desc": "The latest camera up to 30% off",
"image_src": "images/banner3.jpg",
"button_text": "Shop Now!",
"button_link": "#link",
"class_type" : "banner-3",
"button_np": true,
"align_right": false
}
]
},
});
</script>
Output Image: (Very Nice!)
But when I call the code remotely with Fetch, the image is broken.
JavaScript Code: (I uploaded the slider array to the api.php file and called it remotely.)
<script>
new Vue({
el: '#homeage-data',
data: {
sliders: [
]
},
created() {
fetch("/api/api.php")
.then((response) => { return response.json() })
.then((response) => {
this.sliders = response.sliders;
});
}
});
</script>
Output Image:
As I understand it, it cannot render JQuery code because it was added later.
No matter what I did, I couldn't find the right way.
I have not tried the code below. It didn't happen :(
<script>
new Vue({
el: '#homeage-data',
data: {
sliders: [
]
},
created() {
fetch("/api/api.php")
.then((response) => { return response.json() })
.then((response) => {
this.sliders = response.sliders;
});
$(".main-banner, #client").owlCarousel({
//navigation : true, Show next and prev buttons
items: 1,
nav: true,
slideSpeed : 300,
paginationSpeed : 400,
loop:true,
autoPlay: false,
dots: true,
singleItem:true,
nav:true
});
}
});
</script>
Demo of using VueOwlCarousel in Vue2, without npm:
Vue.use(VueOwlCarousel);
new Vue({
el: '#app',
data: () => ({
slides: 0,
options: {
autoplay: true,
autoplaySpeed: 800,
autoplayTimeout: 1800,
lazyLoad: true,
autoplayHoverPause: true
}
}),
mounted() {
setTimeout(() => {
this.slides = 7
}, 2000)
},
})
div.owl-carousel {
width: 400px;
height: 180px;
}
.owl-stage-outer {
height: 111px;
}
.loader {
height: 180px;
display: flex;
align-items: center;
width: 400px;
justify-content: center;
}
h2 {
color: #ddd;
}
body {
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
margin: 0;
}
<script src="https://v2.vuejs.org/js/vue.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-owl-carousel#2.0.3/dist/vue-owl-carousel.min.js"></script>
<div id="app">
<vue-owl-carousel :items="1"
v-if="slides"
v-bind="options">
<img v-for="s in slides"
:key="s"
:src="`https://placeimg.com/400/111/any?${s}`">
</vue-owl-carousel>
<div v-else class="loader">
<h2>Loading...</h2>
</div>
</div>
Personal advice: do not mix jQuery with Vue. You only want one source of truth for your DOM manipulations.
That's the underlying cause of your issue.
Note: Owl carousel can't be initialised with empty slides. For this reason, I've placed a v-if="slides" (or, if slides would have been an array, v-if="slides.length").
Also note Owl takes control over the carousel DOM element and, from that moment on, even if you change the slides array, it won't react to the change. If you wanted to update the slides, you'd need the owl instance, change its internal slides (which are built from the original DOM) and then call its internal .refresh() method.

v-show inside a v-for loop, i need to open only the clicked option

I just started learning Vue.js and I need some help. I have a v-show within a v-for loop set up, there is a show button within the loop, when I click this, at the moment it opens all the hidden divs, I want it to open only the relevant one that's clicked. Maybe there is another way to do this or a better way I have been reading that v-show might not be suited to be used inside a loop.
<style>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
font-family: "Montserrat", sans-serif;
}
.content {
width: 100px;
height: 100px;
background-color: red;
}
.contenttwo {
width: 50px;
height: 50px;
background-color: green;
}
</style>
</head>
<body>
<div id="root">
<div v-for="item in dropdownVoices" :key="item.voice" class="">
<div v-show="active" class="content">
</div>
<div v-show="!active" class="contenttwo">
</div>
<button type="button" name="button" v-on:click="active = !active">Change me</button>
</div>
</div>
<script charset="utf-8">
var app = new Vue({
el: '#root',
data: {
active:true,
dropdownVoices:[
{ voice: 'One' },
{ voice: 'Two' },
{ voice: 'Three' },
{ voice: 'Four' },
{ voice: 'Five' },
{ voice: 'Six' }
],
},
method:{
}
});
Vue.config.devtools = true;
</script>
</body>
</html>
Thanks in advance for the help.
The problem is you are tracking the active changes with only one variable active but you need to track each item, so you have two options add an active property to each item object or track the active item in an array. I'm going to show you the first
// script
data: {
dropdownVoices:[
{ voice: 'One' , active: true},
{ voice: 'Two' , active: true},
{ voice: 'Three' , active: true},
{ voice: 'Four' , active: true},
{ voice: 'Five' , active: true},
{ voice: 'Six', active: true }
],
}
// template
<div v-for="item in dropdownVoices" :key="item.voice" class="">
<div v-show="item.active" class="content"></div>
<div v-show="!item.active" class="contenttwo"></div>
<button type="button" name="button" v-on:click="item.active = !item.active">Change me</button>
</div>
Note: If you only want to change the div styles you can do it with a bind class.
<div :class="item.active ? 'content' : 'contenttwo'"></div>

Highcharts - How would I use HTML input boxes to input the data for a Pie Chart?

Sorry, this is my first stackoverflow question so let me know if I've formatted this wrong.
I attempted to use document.getElementById("id").value in order to get the input value from the input box but I couldn't quite figure out how to make it work. I saw other answers making use of JSON or JQuery but I don't have much experience in those yet so if I could make this work without those(if possible) I'll take that option.
Any bits of code that are commented out are just me trying to get it to work.
(Sidenote: I know my HTML code might be a bit scuffed, that isn't a priority right now)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Pricer.ie</title>
<link rel="stylesheet" href="homepage.css"/>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script type="text/javascript" src="/js/themes/gray.js"></script>
<meta name="viewport" content="initial-scale=1.0, width=device-width"/>
</head>
<body>
<nav class="navbar">
<ul>
<li class="logo">
<img src="logopricer.png" alt="logo" id="logo" >
</li>
<li>
Login
</li>
</ul>
</nav>
<main>
<figure class="highcharts-figure">
<div id="container" style="width:100%; height:400px;"></div>
<script>
document.addEventListener('DOMContentLoaded', function () {
var myChart = Highcharts.chart({
chart: {
renderTo: 'container',
type: 'pie',
events: {
load: function(event) {
var chart = this,
points = chart.series[0].points,
len = points.length,
total = 0,
i = 0;
for (; i < len; i++) {
total += points[i].y;
}
chart.setTitle({
text: '<span style="font-size: 13px">Current Price</small><br>' + '<b>' + '€' + total.toFixed(2) + '</b>',
align: 'center',
verticalAlign: 'middle',
y: -10,
});
}
}
},
title: {
text: 'Product Details'
},
tooltip: {
pointFormat: '<b>{point.percentage:.1f}</b>' + '<b>%</b>'
},
plotOptions: {
pie: {
allowPointSelect: true,
cursor: 'pointer',
dataLabels: {
enabled: true,
format: '{point.name}: €{point.y:.2f}'
}
}
},
series: [{
name: 'Total', [{
name: 'Profit Margin',
// y: document.getElementById('pcost').value
y : 0.29
}, {
name: 'Taxes',
// y: document.getElementById('taxes').value // external thing! database cuz tax changes depending on product
y : 4.25
}, {
name: 'Ebay Fees',
// y: document.getElementById('listfee').value
y : 3.93
}, {
name: 'Unit + Shipping Costs',
// y : document.getElementById('icost').value + document.getElementById('scost').value
y : 17.03
}],
size: '60%',
innerSize: '70%',
showInLegend:true,
dataLabels: {
enabled: true
}
}]
},
)
}
)
</script>
</figure>
<article>
<form>
<label for="icost">Item Cost:</label>
<input type="number" id="icost" name="icost" step="0.01"><br><br>
<label for="scost">Shipping Cost:</label>
<input type="number" id="scost" name="scost" step="0.01"><br><br> <!-- names and ids are incorrect just like this for now -->
<label for="pcost">Pickpack Cost:</label>
<input type="number" id="pcost" name="scost" step="0.01"><br><br>
<label for="taxes">Taxes:</label>
<input type="number" id="taxes" name="taxes" step="0.01"><br><br> <!-- shouldnt exist as taxes is from database but sure look-->
<label for="listfee">Listing Fee:</label>
<input type="number" id="listfee" name="listfee"><br><br>
<button onclick="Function()">Save Changes</button>
</form>
</article>
</main>
<footer>
</footer>
</body>
<html>
I would link to a JSFiddle but not sure how I would do that as my JS is currently embedded within my HTML lol. Thanks in advance to anyone that decides to give me a hand with this. Any advice with this is useful!
You need to get data and put them in a format required by Highcharts. Simple example below:
document.getElementById('btn').addEventListener('click', function() {
var data = [
parseInt(document.getElementById('data1').value),
parseInt(document.getElementById('data2').value)
];
Highcharts.chart('container', {
series: [{
type: 'pie',
data
}]
});
});
Live demo: http://jsfiddle.net/BlackLabel/dyp5208b/
API Reference: https://api.highcharts.com/highcharts/series.pie.data

How to use multiple component to filter data

What I want to happen, is when you click on the radio button on the left, then it filter the content on the right to show only has the same location.
I don't know how to emit an event when someone click on the radio buttons.
I'm using the x-template in this vue code.
const locations = {
options: [
{
title: 'A',
value: 'a'
},
{
title: 'B',
value: 'b'
},
{
title: 'C',
value: 'c'
}]
};
const team = {
options: [
{
name: 'Team A',
location: 'a'
},
{
name: 'Team B',
location: 'b'
},
{
name: 'Team C',
location: 'c'
}]
};
Vue.component('location-filter', {
template: '#location-filter',
props: {
location: {
type: Array,
required: true
}
}
});
new Vue({
el: '#location-finder',
data: {
location: locations.options,
teams: team.options
}
});
.page {
padding:5px;
border:1px solid #cccccc;
display:flex;
flex-flow:row;
}
.sidebar {
flex-grow:0.6;
border: 1px solid red;
padding:10px;
}
.body {
padding:10px;
border:1px solid blue;
flex-grow:1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div class="page" id="location-finder">
<div class="sidebar">
<location-filter :location="location"></location-filter>
</div>
<div class="body">
<div v-for="team in teams">
<div>{{ team.name }}</div>
</div>
</div>
</div>
<script type="text/x-template" id="location-filter">
<div>
<div v-for="place in location">
<label>
<input type="radio" name="place" value="place.value">{{ place.title }}
</label>
</div>
</div>
</script>
Hopefully, it's good enough my explanation and the code to give you an picture of what i'm trying to achieve.
You can emit a custom event from inside of a component, such as when the user clicks on the radio label, like this:
<label #click="$emit('location', place.value)">
I named the event location. Now you can listen for an event named location in the parent's template (locationFinder) like this:
<location-filter :location="location" #location="changeLocation">
Now, locationFinder will try to call a method in its instance called changeLocation every time that location event is emitted. Here's what that method looks like:
changeLocation(location) {
this.selected = location;
}
You can see it sets a data property called selected to the selected location. So now you'll need your teams loop to check that selected location, and only show a team if its location matches the selected one. The best way to do this is to create a computed property which will always contain a filtered version of the teams list. If there is no selected team, it returns all teams:
filtered() {
if (this.selected) {
return this.teams.filter(team => team.location == this.selected);
} else {
return this.teams;
}
}
Finally, update the template to loop over this filtered teams list instead of the unfiltered one:
<div v-for="team in filtered">
I included an updated snippet.
const locations = {
options: [
{
title: 'A',
value: 'a'
},
{
title: 'B',
value: 'b'
},
{
title: 'C',
value: 'c'
}]
};
const team = {
options: [
{
name: 'Team A',
location: 'a'
},
{
name: 'Team B',
location: 'b'
},
{
name: 'Team C',
location: 'c'
}]
};
Vue.component('location-filter', {
template: '#location-filter',
props: {
location: {
type: Array,
required: true
}
}
});
new Vue({
el: '#location-finder',
data: {
location: locations.options,
teams: team.options,
selected: null
},
computed: {
filtered() {
if (this.selected) {
return this.teams.filter(team => team.location == this.selected);
} else {
return this.teams;
}
}
},
methods: {
changeLocation(location) {
this.selected = location;
}
}
});
.page {
padding:5px;
border:1px solid #cccccc;
display:flex;
flex-flow:row;
}
.sidebar {
flex-grow:0.6;
border: 1px solid red;
padding:10px;
}
.body {
padding:10px;
border:1px solid blue;
flex-grow:1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div class="page" id="location-finder">
<div class="sidebar">
<location-filter :location="location" #location="changeLocation"></location-filter>
</div>
<div class="body">
<div v-for="team in filtered">
<div>{{ team.name }}</div>
</div>
</div>
</div>
<script type="text/x-template" id="location-filter">
<div>
<div v-for="place in location">
<label #click="$emit('location', place.value)">
<input type="radio" name="place" value="place.value">{{ place.title }}
</label>
</div>
</div>
</script>

Bind Click Event to Kendo ToolBar

I am trying to bind click event to buttons I have in kendo Tool bar. I am creating button using template.
I am using Kendo Jquery with angular.
Any help will be highly appreciated.
So far I have tried this using Kendo Jquery Documentation:
<!DOCTYPE html>
<html>
<head>
<base href="https://demos.telerik.com/kendo-ui/toolbar/index">
<style>
html {
font-size: 14px;
font-family: Arial, Helvetica, sans-serif;
}
</style>
<title></title>
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2019.3.1023/styles/kendo.default-v2.min.css" />
<script src="https://kendo.cdn.telerik.com/2019.3.1023/js/jquery.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2019.3.1023/js/kendo.all.min.js"></script>
</head>
<body>
<div id="example">
<div class="demo-section k-content wide">
<div id="toolbar"></div>
</div>
<script>
$(document).ready(function () {
$("#toolbar").kendoToolBar({
items: [
{
template: "<a href='' class='k-icon-text-button k-button k-button-icontext k-toolbar-first-visible'><span class='k-icon k-i-save'></span>Save</a>"
},
{
template: "<a href='' class='k-icon-text-button k-button k-button-icontext k-toolbar-first-visible'><span class='k-icon k-i-arrows-swap'></span>Top/Bottom</a>"
},
{
template: "<a href='' class='k-icon-text-button k-button k-button-icontext k-toolbar-first-visible'><span class='k-icon k-i-pencil'></span>Edit</a>"
},
{
template: "<a href='' class='k-icon-text-button k-button k-button-icontext k-toolbar-first-visible'><span class='k-icon k-i-calendar'></span>Schedule</a>",
click: onButtonClick()
},
{
type: "splitButton",
text: "Download",
menuButtons: [{
text: "PDF",
icon: "k-i-pdf"
},
{
text: "EXCEL",
icon: "k-i-excel"
}
]
},
{
type: "button",
text: "Action",
overflow: "always"
},
{
type: "button",
text: "Another Action",
overflow: "always"
},
{
type: "button",
text: "Something else here",
overflow: "always"
}
]
});
$("#dropdown").kendoDropDownList({
optionLabel: "Paragraph",
dataTextField: "text",
dataValueField: "value",
dataSource: [{
text: "Heading 1",
value: 1
},
{
text: "Heading 2",
value: 2
},
{
text: "Heading 3",
value: 3
},
{
text: "Title",
value: 4
},
{
text: "Subtitle",
value: 5
}
]
});
});
function onButtonClick() {
alert('clicked')
}
</script>
</div>
</body>
</html>
Dojo for the same: https://dojo.telerik.com/#amitdwivedi/uDOFeWev
According to the Telerik Docs for the toolbar Click function, the click event handler is only applicable for toolbar items of type button or splitButton. But, items with a template do not have a type.
So, you need to either use basic buttons instead of templates (then you can use the Telerik click handler), or put the click handler in the template itself like this:
$(document).ready(function() {
$("#toolbar").kendoToolBar({
items: [
{
template: "<a href='' onclick='onButtonClick()' class='k-icon-text-button k-button k-button-icontext k-toolbar-first-visible'><span class='k-icon k-i-save'></span>Save</a>"
// ^^^^^^^^^^^^^^^^^^^^^^^^^
}
]
});
});
function onButtonClick(){
alert('clicked')
}
Example Dojo: https://dojo.telerik.com/UniqiHuF/4

Categories

Resources