am having problem switching from the first section(v-if) to the second second(v-else) section using v-if. as default now section(v-if) is displaying and i created a button(startGame) to change to the second section(v-else) when clicked but i find it not easy to do please help me out
<section class="row controls" v-if="!gameIsrunning">
<div class="small-12 columns">
<button id="start-game" #click="startGame">START NEW GAME</button>
</div>
</section>
<section class="row controls" v-else>
<div class="small-12 columns">
<button id="attack">ATTACK</button>
<button id="special-attack">SPECIAL ATTACK</button>
<button id="heal">HEAL</button>
<button id="give-up">GIVE UP</button>
</div>
</section>
<script>
let app = new Vue({
el: "#app",
data: {
playerHealth: 100,
monsterHealth: 100,
gameIsRunning: false
},
methods: {
startGame: function() {
this.gameIsRunning = true;
}
}
});
</script>
Related
I am using PhotoSwipe to display images within my web page developed using wordpress, using the code from the library to display an image as follows
<button id="btn">open</button>
<div class="pswp" tabindex="-1" role="dialog" aria-hidden="true">
<div class="pswp__bg"></div>
<div class="pswp__scroll-wrap">
<div class="pswp__container">
<div class="pswp__item"></div>
<div class="pswp__item"></div>
<div class="pswp__item"></div>
</div>
<div class="pswp__ui pswp__ui--hidden">
<div class="pswp__top-bar">
<div class="pswp__counter"></div>
<button class="pswp__button pswp__button--close"></button>
<button class="pswp__button pswp__button--share"></button>
<button class="pswp__button pswp__button--fs"></button>
<button class="pswp__button pswp__button--zoom"></button>
<div class="pswp__preloader">
<div class="pswp__preloader__icn">
<div class="pswp__preloader__cut">
<div class="pswp__preloader__donut"></div>
</div>
</div>
</div>
</div>
<div class="pswp__share-modal pswp__share-modal--hidden pswp__single-tap">
<div class="pswp__share-tooltip"></div>
</div>
<button class="pswp__button pswp__button--arrow--left"></button>
<button class="pswp__button pswp__button--arrow--right"></button>
<div class="pswp__caption">
<div class="pswp__caption__center"></div>
</div>
</div>
</div>
</div>
</div>
Then I implement the javascript function to show two images
<script>
var openPhotoSwipe = function(){
var pswpElement = document.querySelectorAll(\'.pswp\')[0];
var items = [{
src: \'https://empresas.blogthinkbig.com/wp-content/uploads/2019/11/Imagen3-245003649.jpg\',
w: 1440,
h:1024
},
{
src: \'https://empresas.blogthinkbig.com/wp-content/uploads/2019/11/Imagen3-245003649.jpg\',
w: 1440,
h:1024
}];
var options = {
history: false,
focus: false,
showAnimationDuration: 0,
hideAnimationDuration: 0
};
var gallery = new PhotoSwipe( pswpElement, PhotoSwipeUI_Default, items, options);
gallery.init();
}
openPhotoSwipe();
document.getElementById(\'btn\').onclick = openPhotoSwipe;
</script>
Everything works fine, but when I go to my page to see the result, I find that the menu is above my PhotoSwipe
I tried to add a z-index, but it didn't work and the image is still hidden by the highlighted elements in the image
.pswp {
z-index: 9999999999999999999;
}
I need an equivalent of jQuery "this.find()" to get child element from this section on click.
So on click="showProd(6) I want to find "this .dropProd" inside a method ":
Image
<div class="sections" #click="showProd(6)">
<h2 class="padding-10">Limited Shelf Life</h2>
<div class="dropProd" :class="{ activate : active_el == 6}">
<div v-for="item in shelf" :key="item.id" class="niceBox">
<p class="prod_title">{{item.title}}</p>
<p class="prod_info">{{item.product_details}}</p>
</div>
</div>
</div>
You can use $refs:
<div class="sections" #click="showProd(6)">
<h2 class="padding-10">Limited Shelf Life</h2>
<!-- note the ref attribute below here -->
<div ref="dropProd" class="dropProd" :class="{ activate : active_el == 6}">
<div v-for="item in shelf" :key="item.id" class="niceBox">
<p class="prod_title">{{item.title}}</p>
<p class="prod_info">{{item.product_details}}</p>
</div>
</div>
</div>
Access it in <script> via this.$refs.dropProd
You could just use this.$refs with an appropriate reference name inside your function like this:
new Vue({
el: '#app',
data: function() {
return {
}
},
methods: {
showProd(){
console.log(this.$refs.referenceMe);
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div class="sections"style="background-color: red" #click="showProd(6)">
<h2 class="padding-10">Limited Shelf Life</h2>
<div class="dropProd" ref="referenceMe">
</div>
</div>
</div>
Below are some snippets of my code. Basically I have a few sections in my code to show some data and all these sections are collapsible. First load all sections expanded. On click on the chevron arrow, div -'ibox-content' will be collapsed.
How do I target only the nearest ibox to collapse? At moment when one arrow is clicked all sections are collapsed.
var vue = new Vue({
el: '#vue-systemActivity',
data: {
loading: false,
collapsed: false,
dateStart: '',
dateEnd: '',
status: 'fail',
msg: '',
meta: '',
data: ''
},
created: function() {
this.fetchData();
},
ready: function() {
this.fetchData();
},
methods: {
fetchData: function() {
var self = this;
if (self.dateStart != '' && self.dateEnd != '') {
this.loading = true;
$.get(baseUrl + '/backend/getSystemActFeed?dateStart=' + self.dateStart + '&dateEnd=' + self.dateEnd, function(json) {
self.data = json.data;
self.status = json.status;
self.meta = json.meta;
self.msg = json.msg;
}).always(function() {
self.loading = false;
});
}
}
}
});
");
<div v-if="data.events">
<div class="ibox float-e-margins" :class="[collapsed ? 'border-bottom' : '']">
<div class="ibox-title">
<h5>Events</h5>
<div class="ibox-tools">
<a v-on:click=" collapsed = !collapsed" class="collapse-link">
<i :class="[collapsed ? 'fa-chevron-up' : 'fa-chevron-down', 'fa']"></i>
</a>
</div>
</div>
<div v-for="event in data.events" class="ibox-content inspinia-timeline" v-bind:class="{'is-collapsed' : collapsed }">
<div class="timeline-item">
<div class="row">
<div class="col-xs-3 date">
<i class="fa fa-calendar"></i> {{event.fDateStarted}}
<br/>
</div>
<div class="col-xs-7 content no-top-border">
<!-- <p class="m-b-xs"><strong>Meeting</strong></p> -->
<b>{{event.title}}</b> started on {{event.fDateStarted}} at {{event.at}}
</div>
</div>
</div>
</div>
</div>
</div>
<div v-if="data.mentorBookings">
<div class="ibox float-e-margins" :class="[collapsed ? 'border-bottom' : '']">
<div class="ibox-title">
<h5>Mentorship</h5>
<div class="ibox-tools">
<a v-on:click=" collapsed = !collapsed" class="collapse-link">
<i :class="[collapsed ? 'fa-chevron-up' : 'fa-chevron-down', 'fa']"></i>
</a>
</div>
</div>
<div v-for="mentorProgram in data.mentorBookings" class="ibox-content inspinia-timeline">
<div class="timeline-item">
<p class="m-b-xs"><strong>{{mentorProgram.programName}}</strong></p>
<div v-for="upcomingBooking in mentorProgram.upcomingBookings">
<div class="row">
<div class="col-xs-3 date">
<i class="fa fa-users"></i> {{upcomingBooking.fBookingTime}}
<br/>
</div>
<div class="col-xs-7 content no-top-border">
#{{upcomingBooking.id}} {{upcomingBooking.mentor.firstname}} {{upcomingBooking.mentor.lastname}} ({{upcomingBooking.mentor.email}}) mentoring {{upcomingBooking.mentee.firstname}} {{upcomingBooking.mentee.lastname}} ({{upcomingBooking.mentee.email}}) on
{{upcomingBooking.fBookingTime}} thru {{upcomingBooking.sessionMethod}}
<!--
<p><span data-diameter="40" class="updating-chart">5,3,9,6,5,9,7,3,5,2,5,3,9,6,5,9,4,7,3,2,9,8,7,4,5,1,2,9,5,4,7,2,7,7,3,5,2</span></p> -->
</div>
</div>
</div>
</div>
</div>
</div>
</div>
Each div should have each own collapsed state for control. You can turn collapsed into an array/object to control them.
simple example: https://codepen.io/jacobgoh101/pen/QQYaZv?editors=1010
<div id="app">
<div v-for="(data,i) in dataArr">
{{data}}<button #click="toggleCollapsed(i)">toggle me</button>
<span v-if="collapsed[i]">this row is collapsed</span>
<br/>
<br/>
</div>
</div>
<script>
var app = new Vue({
el: "#app",
data: {
dataArr: ["data0", "data1", "data2"],
collapsed: [false, false, false]
},
methods: {
toggleCollapsed: function(i) {
this.$set(this.collapsed, i, !this.collapsed[i]);
}
}
});
</script>
I have a project here where I need to add and remove layers of images, using vue.js 2. I am building up a pizza where I need to add toppings. My current solution has a flaw - it removes all other elements/ pizza toppings when I add a new one.
The toppings are generated from an array which I loop through.
Can you please help, I am sure this is easy but me being a rookie in vue.js I have already struggled for hours... Thanks!
<div id="app" class="container-fluid">
<div class="row">
<div class="left-container">
<h2>add your ingredients:</h2>
<div v-for="(item, index) in pizzas" v-bind:key="index">
<button class="btn btn-primary" v-on:click="show == index ? show = -1 : show = index">{{ item.pizza }}</button>
</div>
<div class="submit-buttons">
<button class="btn btn-primary reset-pizza" v-on:click="show = -1">Reset pizza</button>
<button class="btn btn-primary submit-pizza">Share pizza</button>
</div>
</div>
<div class="right-container">
<ul class="pizza-layers">
<li v-for="(item, index) in pizzas" class="pizza-canvas" v-bind:class="item.class" v-if="show == index"></li>
<li class="pizza-canvas pizza-canvas--topping-base"></li>
</ul>
</div>
</div>
</div>
<script>
new Vue({
el: '#app',
data: {
pizzas: [
{ pizza: 'Salami', class: 'pizza-canvas--topping-salami' },
{ pizza: 'Rucolla', class: 'pizza-canvas--topping-rucolla' },
{ pizza: 'Cheese', class: 'pizza-canvas--topping-cheese' }
],
show: {},
},
})
</script>
To allow for multiple toppings, this.show should be an array, instead of an object.
Once you change that, you'd need to modify the click event handler to add/remove the topping based on whether or not the topping is already part of show.
Also, while displaying the topping, you'd need to check its existence using show.includes(index) instead of show == index - since this.show is an array.
In the snippet below, I've applied these changes, and added some background colors to visualize how the toppings are added or removed.
new Vue({
el: '#app',
data: {
pizzas: [{
pizza: 'Salami',
class: 'pizza-canvas--topping-salami'
},
{
pizza: 'Rucolla',
class: 'pizza-canvas--topping-rucolla'
},
{
pizza: 'Cheese',
class: 'pizza-canvas--topping-cheese'
}
],
show: [],
},
methods: {
addTopping(event, item, index) {
if(this.show.includes(index)) {
this.show.splice(this.show.indexOf(index),1);
} else {
this.show.push(index);
}
}
}
})
.pizza-canvas--topping-salami {
background-color: red;
}
.pizza-canvas--topping-rucolla {
background-color: yellow;
}
.pizza-canvas--topping-cheese {
background-color: blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.2/vue.min.js"></script>
<div id="app" class="container-fluid">
<div class="row">
<div class="left-container">
<h2>add your ingredients:</h2>
<div v-for="(item, index) in pizzas" v-bind:key="index">
<button class="btn btn-primary" v-on:click="addTopping(event, item, index)">{{ item.pizza }}</button>
</div>
<div class="submit-buttons">
<button class="btn btn-primary reset-pizza" v-on:click="show = []">Reset pizza</button>
<button class="btn btn-primary submit-pizza">Share pizza</button>
</div>
</div>
<div class="right-container">
<ul class="pizza-layers">
<li v-for="(item, index) in pizzas" class="pizza-canvas" v-bind:class="item.class" v-if="show.includes(index)"></li>
<li class="pizza-canvas pizza-canvas--topping-base"></li>
</ul>
</div>
</div>
</div>
I am trying to create a modal view and have a base class that all modals need and then extending it for more specific functionality.
PlanSource.Modal = Ember.View.extend({
isShowing: false,
hide: function() {
this.set("isShowing", false);
},
close: function() {
this.set("isShowing", false);
},
show: function() {
this.set("isShowing", true);
}
});
PlanSource.AddJobModal = PlanSource.Modal.extend({
templateName: "modals/add_job",
createJob: function() {
var container = $("#new-job-name"),
name = container.val();
if (!name || name == "") return;
var job = PlanSource.Job.createRecord({
"name": name
});
job.save();
container.val("");
this.send("hide");
}
});
I render it with
{{view PlanSource.AddJobModal}}
And have the view template
<a class="button button-green" {{action show target=view}}>+ Add Job</a>
{{#if view.isShowing}}
<div class="modal-wrapper">
<div class="overlay"></div>
<div class="dialog box box-border">
<div class="header">
<p class="title">Enter a job name.</p>
</div>
<div class="body">
<p>Enter a name for your new job.</p>
<input type="text" id="new-job-name" placeholder="Job name">
</div>
<div class="footer">
<div class="buttons">
<a class="button button-blue" {{action createJob target=view}} >Create</a>
<a class="button" {{action close target=view}}>No</a>
</div>
</div>
</div>
</div>
{{/if}}
The problem is that when I click the button on the modal dialog, it gives me an "action createJob" can not be found. Am I extending the objects incorrectly because it works if I put the createJob in the base Modal class.
Fixed
There was an issue somewhere else in my code. The name got copied and so it was redefining it and making the method not exist.