Everything perfectly works great until I resize the window as I'm trying to build a responsive website. The images inside the slider collapses. I have to reload the page first so they will be in perfect position. What should I do so i don't need to reload the page when resizing the window?
html
<div class="container">
<!-- --- images ---- -->
<div class="slides">
<div class="slide">
<img src="/images/img1.jpg" alt="">
</div>
<div class="slide">
<img src="/images/img2.jpg" alt="">
</div>
<div class="slide">
<img src="/images/img3.jpg" alt="">
</div>
<div class="slide">
<img src="/images/img4.jpg" alt="">
</div>
</div><!-- ---- end of images ---- -->
<!-- ------ controls -------- -->
<div class="slide-controls">
<button id="prev-btn">
<i class="fas fa-chevron-left"></i>
</button>
<button id="next-btn">
<i class="fas fa-chevron-right"></i>
</button>
</div>
<!-- ------ controls -------- -->
</div> <!-- ----- end of container ------- -->
css
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container {
margin: 20px auto 0 auto;
width: 60%;
height: 600px;
position: relative;
border: 2px solid red;
overflow: hidden;
}
.slides {
display: flex;
height: 100%;
}
.slide {
min-width: 100%;
}
.slide img {
width: 100%;
height: 100%;
object-fit: cover;
vertical-align: middle;
}
.slide-controls {
position: absolute;
top: 50%;
left: 0;
transform: translateY(-50%);
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
/* display: none; */
}
#next-btn,
#prev-btn {
cursor: pointer;
background: transparent;
font-size: 40px;
border: none;
padding: 10px;
color: white;
}
#next-btn:focus,
#prev-btn:focus {
outline: none;
}
js
const slideContainer = document.querySelector('.container');
const slide = document.querySelector('.slides');
const prevBtn = document.getElementById('prev-btn');
const nextBtn = document.getElementById('next-btn');
const interval = 3000;
let slides = document.querySelectorAll('.slide');
let index = 1;
let slideId;
const firstClone = slides[0].cloneNode(true);
const lastClone = slides[slides.length - 1].cloneNode(true);
firstClone.id = 'first-clone';
lastClone.id = 'last-clone';
slide.append(firstClone);
slide.prepend(lastClone);
const slideWidth = slides[index].clientWidth;
slide.style.transform = `translateX(${-slideWidth * index}px)`;
const startSlide = () => {
slideId = setInterval( () => {
moveToNextSlide();
}, interval);
}
const getSlides = () => slides = document.querySelectorAll('.slide');
slide.addEventListener('transitionend', () => {
slides = getSlides();
if ( slides[index].id === firstClone.id ) {
slide.style.transition = 'none';
index = 1;
slide.style.transform = `translateX(${-slideWidth * index}px)`;
}
if ( slides[index].id === lastClone.id ) {
slide.style.transition = 'none';
index = slides.length - 2;
slide.style.transform = `translateX(${-slideWidth * index}px)`;
}
});
slideContainer.addEventListener('mouseenter', () => {
clearInterval(slideId);
});
slideContainer.addEventListener('mouseleave', startSlide );
const moveToNextSlide = () => {
slides = getSlides();
if ( index >= slides.length -1 ) return;
index++;
slide.style.transform = `translateX(${-slideWidth * index}px)`;
slide.style.transition = '.7s';
}
const moveToPreviousSlide = () => {
if ( index <= 0 ) return;
index--;
slide.style.transform = `translateX(${-slideWidth * index}px)`;
slide.style.transition = '.7s';
};
nextBtn.addEventListener('click', moveToNextSlide);
prevBtn.addEventListener('click', moveToPreviousSlide );
startSlide();
Here's my code snippet. https://codepen.io/rebeccafm/pen/YzWyrvm
i found the answer to this. I use jquery resize method.
$(window).resize(() => {
slideWidth = slides[index].clientWidth;
slide.style.transform = `translateX(${-slideWidth * index}px)`;
});
Related
//universal variables for cart {
var cart = document.createElement('div');
document.body.appendChild(cart);
cart.id = "cart";
var itemshow = document.createElement('div');
document.getElementById('cart').appendChild(itemshow);
itemshow.id = "itemshow";
var itm1 = document.createElement('div');
document.getElementById('itemshow').appendChild(itm1);
itm1.id = "itm1";
var itd = document.createElement('div');
document.getElementById('itemshow').appendChild(itd);
itd.id = "itd";
var itm_title_1 = document.createElement('div');
document.getElementById('itd').appendChild(itm_title_1);
itm_title_1.id = "itm_title_1";
var quan = document.createElement('div');
document.getElementById('itd').appendChild(quan);
quan.id = "quan";
var sub1 = document.createElement('button');
document.getElementById('quan').appendChild(sub1);
sub1.id = "sub";
sub1.innerHTML = "-";
var qu1 = document.createElement('span');
document.getElementById('quan').appendChild(qu1);
qu1.id = "qu";
var add1 = document.createElement('button');
document.getElementById('quan').appendChild(add1);
add1.id = "add";
add1.innerHTML = "+";
var span1 = document.createElement('span');
document.getElementById('quan').appendChild(span1);
span1.id = "span1";
span1.innerHTML = "10 quantity is allowed per order";
var rtm1 = document.createElement('button');
document.getElementById('itd').appendChild(rtm1);
rtm1.id = "rtm";
rtm1.innerHTML = "Remove Item";
var total_itm_value = document.createElement('div');
document.getElementById('itd').appendChild(total_itm_value);
total_itm_value.id = "total_itm_value";
var iqp1 = document.createElement('div');
document.getElementById('itd').appendChild(iqp1);
iqp1.id = "iqp";
var q1 = document.createElement('div');
document.getElementById('iqp').appendChild(q1);
q1.id = "q";
var iq1 = document.createElement('div');
document.getElementById('iqp').appendChild(iq1);
iq1.id = "iq";
var tp1 = document.createElement('div');
document.getElementById('itd').appendChild(tp1);
tp1.id = "tp";
var price1 = document.createElement('div');
document.getElementById('tp').appendChild(price1);
price1.id = "price";
price1.innerHTML = "price : ";
var p1 = document.createElement('div');
document.getElementById('tp').appendChild(p1);
p1.id = "p";
//function for add to cart for only one item
document.getElementById('btn1').onclick = function() {myFunc()};
document.getElementById('btn2').onclick = function() {myFunc()};
let quantity = 1;
let price = 19;
function myFunc() {
var x = document.getElementById('itm_img_1');
var w = document.getElementById('itm_img_2');
btn1onclick = document.getElementById('btn1');
btn2onclick = document.getElementById('btn2');
if (btn1onclick.onclick) {
document.getElementById('itm1').innerHTML = x.innerHTML
}
else if (btn2onclick.onclick) {
document.getElementById('itm1').innerHTML = w.innerHTML
}
/*document.getElementById('itm1').innerHTML = x.innerHTML;*/
document.getElementById('qu').innerHTML =
quantity;
document.getElementById('iq').innerHTML = quantity;
document.getElementById('p').innerHTML = price;
var z = document.getElementById('itm_title');
document.getElementById('itm_title_1').innerHTML = z.innerHTML;
document.getElementById('rtm').style.display = "inline-block";
var y = document.getElementById('itemshow');
if (y.style.display= "none") {
y.style.display = "flex";
}
var cart = document.getElementById('cart')
cart.style.display = "inline-block";
//function for increment product quantity
document.getElementById('add').onclick = function() {add()};
function add() {
quantity = quantity + 1;
if (quantity <= 10 ) {
var qu = document.getElementById('qu'); qu.innerHTML = quantity;
document.getElementById('sub').disabled = false;
document.getElementById('iq').innerHTML = quantity;
document.getElementById('p').innerHTML = ((Number(quantity)) * (Number(price)));
}
}
//function for decrement product quantity
document.getElementById('sub').onclick = function() {sub()};
function sub() {
quantity = quantity - 1;
if (quantity <= 1) {
document.getElementById('sub').disabled = true;
}
else if (quantity >= 1){
document.getElementById('sub').disabled = false;
}
var qu = document.getElementById('qu'); qu.innerHTML = quantity;
document.getElementById('iq').innerHTML = quantity;
document.getElementById('p').innerHTML = ((Number(quantity)) * (Number(price)));
}
// function for total item value
document.getElementById('total_itm_value').innerHTML = "total";
document.getElementById('q').innerHTML = "quantity :";
// function for remove item from cart
document.getElementById('rtm').onclick = function() {rtm()};
function rtm() {
document.getElementById('itemshow').style.display = "none";
quantity = quantity / quantity;
document.getElementById('qu').innerHTML = quantity;
document.getElementById('cart').style.display = "none";
}
}
////////////////
.all {
display: flex;
}
.item_container {
display: flex;
flex-direction: column;
background-color: #ffcccc;
width: 250px;
border-radius: 6px;
box-shadow: 10px 10px 30px;
align-items: center;
margin: 5%;
}
.itm_img {
padding: 2%;
}
.img {
width: 200px;
border-radius: 5px;
}
.itm_title {
text-align: center;
}
h3 {
font-family: 'Roboto', sans-serif;
margin-bottom: 0%;
}
a:link {
color: #99ddff;
text-decoration: none;
}
a:visited {
color: green;
}
a:hover {
text-decoration: underline;
}
a:active {
color: #99ddff;
}
.price {
font-weight: bold;
font-size: 25px;
font-family: 'Roboto', sans-serif;
text-align: center;
}
.link {
text-align: center;
}
hr {
margin: 4%;
}
.btn {
margin-left: 32%;
margin-top: 5%;
margin-bottom: 6%;
}
.btn1, .btn2 {
background-color: #80ffcc;
border: none;
padding: 5%;
border-radius: 6px;
}
.btn1:hover, .btn2:hover {
background-color: #80e5ff;
transition: 0.5s;
box-shadow: 5px 5px 10px;
}
#itemshow {
display: none;
}
#cart {
display: none;
color: white;
background-color: black;
padding: 2%;
}
#total_itm_value {
font-size: 25px;
}
#iqp, #tp {
display: flex;
}
.itm_title_1 {
display: block;
}
<head>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght#500&display=swap" rel="stylesheet">
</head>
<body>
<div class="all">
<div class="item_container">
<div class="itm_img" id="itm_img_1">
<img src="https://m.media-amazon.com/images/I/61X1b09mK0L._SL1500_.jpg" alt="img" class="img" id="img">
</div>
<div clas="itm_dtl">
<div class="itm_title" id="itm_title">
<h3> Milton stainless steel Water Bottle, 1 pc, 950 ml, Silver</h3>
</div>
<div class="link">
Visit Milton Store
</div>
<hr>
<div class="price">$19</div>
<div class="btn">
<button class="btn1" id="btn1">Add to Cart</button>
</div>
</div>
</div>
<div class="item_container">
<div class="itm_img" id="itm_img_2">
<img src="https://m.media-amazon.com/images/I/616G5-FDTvL._SX425_.jpg" alt="img" class="img">
</div>
<div clas="itm_dtl">
<div class="itm_title">
<h3> Milton stainless steel Water Bottle, 1 pc, 950 ml, Silver</h3>
</div>
<div class="link">
Visit Milton Store
</div>
<hr>
<div class="price">$19</div>
<div class="btn">
<button class="btn2" id = "btn2">Add to Cart</button>
</div>
</div>
</div>
<div class="item_container">
<div class="itm_img" id="itm_img_3">
<img src="https://m.media-amazon.com/images/I/61nb1cWMOiL._SX679_.jpg" alt="img" class="img">
</div>
<div clas="itm_dtl">
<div class="itm_title">
<h3> Milton stainless steel Water Bottle, 1 pc, 950 ml, Silver</h3>
</div>
<div class="link">
Visit Milton Store
</div>
<hr>
<div class="price">$19</div>
<div class="btn">
<button class="btn1">Add to Cart</button>
</div>
</div>
</div>
<div class="item_container">
<div class="itm_img" id=".itm_img_4">
<img src="https://m.media-amazon.com/images/I/61TYUKCL2IL._SX679_.jpg" alt="img" class="img">
</div>
<div clas="itm_dtl">
<div class="itm_title">
<h3> Milton stainless steel Water Bottle, 1 pc, 950 ml, Silver</h3>
</div>
<div class="link">
Visit Milton Store
</div>
<hr>
<div class="price">$19</div>
<div class="btn">
<button class="btn1">Add to Cart</button>
</div>
</div>
</div>
</div>
</body>
**i was declared all variables in js. and calling same function (myFunc()) when add to cart button clicked on on first two buttons of add to cart. only first item is adding on clicking second button of add to cart not adding the second item. and also function (myFunc()) is not adding for other items **
add to cart is adding only first item.
i was declared all variables in js. and calling same function (myFunc()) when add to cart button clicked on on first two buttons of add to cart. only first item is adding on clicking second button of add to cart not adding the second item. and also function (myFunc()) is not adding for other items
After adding and entering a button, I implemented changing the table by pressing the button, but I want to change the column and row of the table immediately as soon as I enter the number. For example, if I enter 4, I want to have a 4X4 table. I don't know. Help me.
<html>
<head>
<meta charset="utf-8" />
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<style>
div { padding: 30px; margin: 30px auto; width: 600px;
border: 1px solid #ccc; box-shadow: 3px 3px 3px #aaa; }
table { border-collapse: collapse; margin-top: 10px; }
td { width: 50px; height: 50px; border: 1px solid gray; font-size: 20pt;
text-align: center; cursor: pointer; }
.yellow { background-color: yellow; }
</style>
</head>
<body>
<div id="app">
<input type="text" v-model.number="size" >
<button type="button" #click="change(size)">Change</button>
<table :style="{backgroundColor: color}">
<tr v-for="(row, index1) in matrix" v-bind:key="index1">
<td v-for="(value, index2) in row" v-bind:key="index2">
{{ value }}
</td>
</tr>
</table>
<h1>{{size}}</h1>
</div>
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
size: 3,
matrix: [],
clicked: [],
color: "",
},
created() {
for (let r = 0; r < this.size; ++r) {
this.matrix[r] = [];
for (let c = 0; c < this.size; ++c)
this.matrix[r][c] = r * this.size + c +1;
}
},
methods:{
change(s){
this.size=s
console.log(this.size)
let arr=[]
for (let r = 0; r < this.size; ++r) {
arr[r] = [];
for (let c = 0; c < this.size; ++c)
arr[r][c] = r * this.size + c +1;
}
this.matrix=arr
}
}
})
</script>
</body>
</html>
you can using a watcher on your size state
the watch statement should be like this:
watch: {
size(newVal){
this.change(newVal)
}
}
and you can see a working example in the below :)
var app = new Vue({
el: '#app',
data: {
size: 3,
matrix: [],
clicked: [],
color: "",
},
created() {
this.change(this.size)
},
methods:{
change(s){
console.log(this.size)
let arr=[]
for (let r = 0; r < this.size; ++r) {
arr[r] = [];
for (let c = 0; c < this.size; ++c)
arr[r][c] = r * this.size + c +1;
}
this.matrix=arr
}
},
watch: {
size(newVal){
this.change(newVal)
}
}
})
div { padding: 30px; margin: 30px auto; width: 600px;
border: 1px solid #ccc; box-shadow: 3px 3px 3px #aaa; }
table { border-collapse: collapse; margin-top: 10px; }
td { width: 50px; height: 50px; border: 1px solid gray; font-size: 20pt;
text-align: center; cursor: pointer; }
.yellow { background-color: yellow; }
<html>
<head>
<meta charset="utf-8" />
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<input type="text" v-model.number="size" >
<table :style="{backgroundColor: color}">
<tr v-for="(row, index1) in matrix" v-bind:key="index1">
<td v-for="(value, index2) in row" v-bind:key="index2">
{{ value }}
</td>
</tr>
</table>
<h1>{{size}}</h1>
</div>
</body>
</html>
Default the loading image is true after complete the upload loading image is false, but after update the loading object no effect in view, always show the loading bar.
Where is my mistake, please help anyone,
Note: also try by this.$nextTick() function, same output;
in console the update we got, but no effect in view
Vue.config.devtools=false;
Vue.config.productionTip = false;
new Vue({
el:"#app",
data: {
isloadingImage: [],
property:{
images:[]
}
},
methods: {
addFiles() {
this.$refs.files.click();
},
handleFilesUpload() {
let uploadedFiles = this.$refs.files.files;
let maxLength = uploadedFiles.length <= 4 ? uploadedFiles.length : 4;
for (let i = 0; i < maxLength; i++) {
uploadedFiles[i].url = URL.createObjectURL(uploadedFiles[i]);
this.property.images.push(uploadedFiles[i]);
}
this.uploadImages();
},
removeFile(key) {
this.property.images.splice(key, 1);
delete this.isloadingImage[key];
},
async uploadImages(){
this.property.images.forEach((value, key) => {
if (!this.isloadingImage[key]) {
this.isloadingImage[key] = true;
let myFormData = new FormData();
myFormData.append('title', value);
axios.post('http://localhost:800/uploadimage',
myFormData).then(response => {
this.isloadingImage[key] = false;
}).catch(error=> {
this.isloadingImage[key] = false;
console.log(this.isloadingImage);
})
}
});
}
}
});
.small-image {
max-height: 200px;
max-width: 200px;
}
.post-image button {
padding: 0 5px;
}
.post-image-preview {
max-height: 105px;
}
.post-image .caption {
max-width: 198px;
height: 27px;
}
.lds-facebook {
display: inline-block;
position: relative;
width: 64px;
height: 50px;
}
.lds-facebook div {
display: inline-block;
position: absolute;
left: 6px;
width: 10px;
background: #bfbebe;
animation: lds-facebook 1.2s cubic-bezier(0, 0.5, 0.5, 1) infinite;
}
.lds-facebook div:nth-child(1) {
left: 6px;
animation-delay: -0.24s;
}
.lds-facebook div:nth-child(2) {
left: 26px;
animation-delay: -0.12s;
}
.lds-facebook div:nth-child(3) {
left: 45px;
animation-delay: 0s;
}
#keyframes lds-facebook {
0% {
top: 6px;
height: 51px;
}
50%, 100% {
top: 19px;
height: 26px;
}
}
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
<div class="field-title"><h5>Pictures</h5></div>
<div class="form-group post-image">
<div class="col-md-12">
<div class="upload-btn-wrapper">
<button class="add-photo" v-on:click="addFiles()"><i
class="fas fa-camera"></i></button>
<input type="file" multiple id="file" ref="files"
v-on:change="handleFilesUpload()">
</div>
<div class="brows-image-text"><p>You can upload up to<br>4 pictures per
listing</p></div>
</div>
<div class="row">
<div v-for="(file, key) in property.images" class="col-md-3">
<div class="lds-facebook" v-if="isloadingImage[key]">
<div></div>
<div></div>
<div></div>
</div>
<div v-else>
<button v-on:click="removeFile( key )" type="button">
<i class="fas fa-times text-danger"></i>
</button>
<img :src="file.url" class="small-image post-image-preview">
</div>
</div>
</div>
</div>
</div>
See rule #2 here https://vuejs.org/2016/02/06/common-gotchas/#Why-isn%E2%80%99t-the-DOM-updating
You update isloadingImage array's values using its keys. In such a case for the change to be reactive, you need to replace your whole array after the fact.
Example:
axios.post('http://localhost:800/uploadimage', myFormData)
.then(response => {
this.isloadingImage[key] = false;
this.isloadingImage = this.isloadingImage.slice(0);
// ^^^ this line
}).catch(error=> {
console.log('error', key, error)
this.isloadingImage[key] = false;
this.isloadingImage = this.isloadingImage.slice(0);
// ^^^ and line
});
Use data as function, not as object like you do.
new Vue({
el:"#app",
data () {
return {
imageIsLoading: ...
I am brand new to VueJS and almost everything is working, except for pagination. As a matter of fact, I have zero warnings. The only thing appearing in the console is "[HMR] Waiting for update signal from WDS... log.js?4244:23" followed by a ">" on the next line.
With that said, the pagination is showing the correct number of pages - given the data coming from the JSON, but I do not know how to connect the pagination to the UL or the app.
At least when there is an error, I can figure something out. Any help is appreciated and thanks in advance.
<template>
<div class="container" id="app">
<span>VueJS-Example</span>
<ul class="list-group list-inline mHeaders">
<li class="list-group-item">Title</li>
<li class="list-group-item">Band</li>
<li class="list-group-item">Date Posted</li>
<li class="list-group-item">Downloads</li>
<li class="list-group-item">YouTube</li>
<li class="list-group-item">MP3</li>
</ul>
<ul :key="item.id" class="list-group list-inline" v-for="item in items">
<li class="list-group-item">
{{item.title}}
</li>
<li class="list-group-item">
{{item.original_band}}
</li>
<li class="list-group-item">
{{item.date_posted}}
</li>
<li class="list-group-item mZip">
<a v-bind:href="''+item.download_midi_tabs+''" target="_blank"></a>
</li>
<li class="list-group-item mYt">
<a v-bind:href="''+item.youtube_link+''" target="_blank"></a>
</li>
<li class="list-group-item mAudio">
<a v-bind:href="''+item.download_guitar_m4v+''" target="_blank"></a>
</li>
</ul>
<pagination :records="288" :per-page="30" #paginate="getPostsViaREST"></pagination>
</div>
</template>
<script>
import axios from 'axios'
import {Pagination} from 'vue-pagination-2'
export default {
name: 'App',
data: function () {
return {
items: [{
title: '',
original_band: '',
date_posted: '',
download_midi_tabs: '',
youtube_link: '',
download_guitar_m4v: ''
}]
}
},
created: function () {
this.getPostsViaREST()
},
methods: {
getPostsViaREST: function () {
axios.get('http://local.sites/getSongs.php')
.then(response => { this.items = response.data })
}
},
components: {
Pagination
}
}
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
a {
color: #999;
}
.current {
color: red;
}
ul {
padding: 0;
list-style-type: none;
}
li {
display: inline;
margin: 5px 5px;
}
ul.list-group:after {
clear: both;
display: block;
content: "";
}
.list-group-item {
float: left;
}
.list-group li{
max-width: 30%;
min-width: 50px;
min-height: 48px;
max-height: 48px;
}
.list-group li:first-child{
width: 200px;
cursor: pointer;
}
.list-group li:nth-child(2){
width: 200px;
}
.list-group li:nth-child(3){
width: 110px;
}
.list-group li:nth-child(4){
width: 48px;
}
.list-group li:nth-child(5){
width: 48px;
}
.list-group li:last-child{
width: 48px;
}
.mZip{
background: url("http://www.kronusproductions.com/songs_angular/assets/images/mZip.png");
display: block !important;
max-width: 48px;
height: 48px;
cursor: pointer;
}
.mYt{
background: url("http://www.kronusproductions.com/songs_angular/assets/images/youtube-icon_48x48.png");
display: block !important;
width: 48px;
height: 48px;
cursor: pointer;
}
.mAudio{
background: url("http://www.kronusproductions.com/songs_angular/assets/images/volume.png");
display: block !important;
width: 48px;
height: 48px;
cursor: pointer;
}
.mZip a{
display: block !important;
width: 48px;
height: 48px;
}
.mYt a{
display: block !important;
width: 48px;
height: 48px;
}
.mAudio a{
display: block !important;
width: 48px;
height: 48px;
}
.mHeaders li{
background-color: cornflowerblue;
font-size: 0.85rem;
color: white;
}
OK - this is somewhat of a hack, but it works.
The following URL is a working example:
Needed help from some old fashion native JavaScript on the index.html file. First, I needed to be able to read a hidden field that contained the number of entries coming from the JSON., followed by setting all the ULs to display none - the setTimeout is to make sure that the JSON file was loaded
<script type="text/javascript">
var mTO = setTimeout(function () {
for (var x = 31; x <= $(".numRows").val() - 1; x++) {
if (typeof (document.getElementById('sp_' + x)) === 'undefined') {
} else {
document.getElementById('sp_' + x).style.display = 'none'
}
}
}, 1000);
mTO;
</script>
This is followed by calling a computed user created method to set this.mVar to the number of elements/entries/properties - whatever name you want to use for it - for Vue to know how many elements, so that we could divide by the number of pages to paginate
computed: {
mFunc: function () {
this.mVar = Object.keys(this.items).length
return Object.keys(this.items).length
}
}
This is another portion of the aforementioned hack - depending on page clicked in the pagination section, this determines what to hide and what to show
setPage: function (page) {
this.page = page
// console.log(page)
for (var y = 0; y <= this.mVar - 1; y++) {
if (typeof (document.getElementById('sp_' + y)) === 'undefined') {
} else {
document.getElementById('sp_' + y).style.display = 'none'
}
}
for (var x = (30 * (this.page - 1)); x <= 30 * (this.page); x++) {
if (typeof (document.getElementById('sp_' + x)) === 'undefined' || (document.getElementById('sp_' + x)) == null) {
break
} else {
document.getElementById('sp_' + x).style.display = 'block'
}
}
}
In case you were wondering what the "30" is for, that is the number of ULs that I wanted to show per page.
The last portion of the hack is within the template section
<pagination :records="mFunc" :per-page="30" #paginate="setPage"></pagination>
<span style="display: none;"><input type="hidden" class="numRows" :value="this.mVar" /></span>
If you would like to use the entire, then you can find it on my github:
Github repo for vuejs-example
I'm learning how to use vue.js to pull movie information and display it.
Inside the main application mc I have a method getMovie which isn't being called when another method updateMovie is called. The updateMovie method is called from the event 'switch' which is emitted by a child component details-card
I can see that the title on my application gets changed and the method updateMovie is working if you click on a director and then a movie under that director. The input field also changes value. Why won't the getMovie work?
var mc = new Vue({
el: "#movie-card",
data: {
title: '',
valid: false,
loading: false,
error: false,
mc: {},
directorArray: [],
actorArray: [],
},
computed: {
checkMulti: function(item) {
if (Object.keys(item).length <= 1) {
return false;
} else {
return true;
}
}
},
methods: {
getMovie: function() {
this.cm = {};
console.log("getMovie called")
if (this.title !== "") {
this.loading = true;
this.error = false;
searchString = 'https://www.omdbapi.com/?t=' + this.title;
var that = this;
axios.get(searchString)
.then(function(res) {
that.cm = res.data;
that.directorArray = res.data.Director.trim().split(/\s*,\s*/);
that.actorArray = res.data.Actors.trim().split(/\s*,\s*/);
that.valid = true;
that.loading = false;
})
.catch(function(error) {
console.log(error.message);
that.loading = false;
that.error = true;
})
}
},
updateMovie: function(movie) {
console.log(movie);
this.title = movie;
this.getMovie;
}
}
})
Vue.component('details-card', {
props: [
'name',
'title'
],
template: `
<div>
<a href=""
#click="handleShowDetails($event)"
>
{{ name }}
</a>
<div v-if="visible" class="detailsCard">
<h3 class="removeTopMargin">{{ name }}</h3>
<img :src="picUrl">
<h4>Known for</h4>
<p v-for="movie in knownForArray">
<a href=""
#click="switchMovie(movie.original_title, $event)"
>{{ movie.original_title }}</a>
</p>
</div>
</div>
`,
data: function() {
return {
picUrl: "",
knownForArray: [],
visible: false
}
},
methods: {
handleShowDetails: function($event) {
this.visible = !this.visible;
this.callPic($event);
},
switchMovie( movie , $event) {
if ($event) $event.preventDefault();
console.log("switching to...", movie);
this.$emit('switch', movie);
},
callPic: function(event) {
if (event) event.preventDefault();
let that = this;
let searchString = "https://api.themoviedb.org/3/search/person?api_key=9b8f2bdd1eaf20c57554e6d25e0823a2&language=en-US&query=" + this.name + "&page=1&include_adult=false";
if (!this.picUrl) { //only load if empty
axios.get(searchString)
.then(function(res) {
let profilePath = res.data.results[0].profile_path;
if (profilePath === null) {
that.picUrl = "http://placehold.it/150x200"
} else {
that.picUrl = 'https://image.tmdb.org/t/p/w150/' + profilePath;
}
that.personPic = profilePath;
that.knownForArray = res.data.results[0].known_for;
}).catch(function(err){
console.log(err);
})
}
},
hideDetails: function () {
this.visible= false;
}
}
})
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
*:focus {
outline: none;
}
ul {
padding-left: 1em;
}
.loading {
margin: auto;
max-width: 450px;
}
.details {
display:block;
margin: 1em auto;
text-align: center;
}
.searchBar {
padding: .5em;
-webkit-box-shadow: 0px 2px 16px 2px rgba(168,168,168,0.45);
-moz-box-shadow: 0px 2px 16px 2px rgba(168,168,168,0.45);
box-shadow: 0px 2px 16px 2px rgba(168,168,168,0.45);
text-align: center;
}
.searchBar input {
padding: .5em;
width: 300px;
font-size: 1em;
border: none;
border-bottom: 1px solid gray;
}
.searchBar button {
padding: .2em;
border: 2px solid gray;
border-radius: 8px;
background: white;
font-size: 1em;
color:#333;
}
img {
display: block;
margin: auto;
width: 150px;
padding-bottom: .33em;
}
.card {
max-width: 500px;
margin: 2em auto;
-webkit-box-shadow: 0px 6px 16px 2px rgba(168,168,168,0.45);
-moz-box-shadow: 0px 6px 16px 2px rgba(168,168,168,0.45);
box-shadow: 0px 6px 16px 2px rgba(168,168,168,0.45);
padding: 2em;
}
.detailsCard {
-webkit-box-shadow: 0px 6px 16px 2px rgba(168,168,168,0.45);
-moz-box-shadow: 0px 6px 16px 2px rgba(168,168,168,0.45);
box-shadow: 0px 6px 16px 2px rgba(168,168,168,0.45);
padding: 1em;
}
/* ======= Typography */
html {font-size: 1em;}
body {
background-color: white;
font-family: roboto;
font-weight: 400;
line-height: 1.45;
color: #333;
}
p {margin-bottom: 1.3em;}
h1, h2, h3, h4 {
margin: 1.414em 0 0.5em;
font-weight: inherit;
line-height: 1.2;
}
h2, h3, h4 {
border-bottom: 1px solid gray;
}
h1 {
margin-top: 0;
font-size: 3.998em;
text-align: center;
}
h2 {font-size: 2.827em;}
h3 {font-size: 1.999em;}
h4 {font-size: 1.414em;}
small, .font_small {font-size: 0.707em;}
.removeTopMargin {
margin-top: .5em;
}
<link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet">
<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<div id="movie-card">
<div class="searchBar">
<input type="text" ref="input" v-model="title" placeholder="Enter a movie title here..." v-on:keyup.enter="getMovie">
<button type="submit" #click="getMovie">Search</button>
</div>
<div class="loading" v-if="loading">
<BR><BR>
<h1>Loading...</h1>
</div>
<div class="loading" v-if="error">
<BR><BR>
<h1>Something went wrong!</h1>
</div>
<div class="card" v-if="valid && !loading">
<h1> {{ cm.Title }}</h1>
<div v-if="!(cm.Poster === 'N/A')" class="poster">
<img v-bind:src="cm.Poster">
</div>
<div class="details">
<p>{{ cm.Year + " – " + cm.Rated + " – " + cm.Runtime }}</p>
</div>
<p>{{ cm.Plot }}</p>
<div class="directors" v-if="cm.Director">
<h3 v-if="(directorArray.length > 1)">Director</h3>
<h3 v-else>Director</h3>
<p>
<p v-for="(director, index) in directorArray">
<details-card :name="director" v-on:switch="updateMovie"></details-card>
</p>
</p>
</div>
<div class="actors" v-if="cm.Actors">
<h3 v-if="actorArray.length > 1">Actors</h3>
<h3 v-else>Actor</h3>
<p>
<p v-for="(actor, index) in actorArray">
<details-card :name="actor"></details-card>
</p>
</p>
</div>
<div class="ratings" v-if="cm.Ratings">
<h3>Ratings</h3>
<ul>
<li v-for="rating in cm.Ratings">{{ rating.Source }}: {{ rating.Value }}</li>
</ul>
</div>
</div>
</div>