Katie Shamus
Katie Shamus

Reputation: 61

Using Vue.js: disabling button on picture slideshow, when no "next" photo is available

This is my first time using Vue. I am trying to create a slideshow from an array of images. I have am able to disable my "previous" button, when the user is at the beginning of the slideshow, but cannot disable my "next" button when at the last image of the slide show.

Here is my code:

Vue.config.devtools = true
var app = new Vue({
  el: '#app',
  data: {
    title: 'Photo of the day!',
    description: '',
    images:   [
    {
      image: 'https://cdn.spacetelescope.org/archives/images/wallpaper2/heic1509a.jpg', date: '1/9/2019', title: 'Beautiful Milky Way'
    },
    {
      image: 'https://img.purch.com/w/660/aHR0cDovL3d3dy5zcGFjZS5jb20vaW1hZ2VzL2kvMDAwLzA2MS8wNzUvb3JpZ2luYWwvY2hhbmRyYS1uZ2M2MzU3LWNvbXBvc2l0ZS5qcGc=', date: '1/10/2019', title: 'Amazing Whirlpool Galaxy'
    },
    {
      image: 'https://icdn3.digitaltrends.com/image/space-engine-featured-510x0.jpg?ver=1', date: '1/11/2019', title: 'Wonderous Large Magellanic Cloud'
    },

  ],
    currentNumber: 0,
    photosAvailable: true,
  }, 
  methods: {
    next: function() {
      app.currentNumber += 1;
      if (app.currentNumber  === app.images.length) {
        console.log('SERGIO')
        app.photosAvailable = false 
        return 
      }
    },
    previous: function() {
      app.photosAvailable = true
      return app.currentNumber -= 1
    }, 
  }
})
<!DOCTYPE html>
<html>
  <head>
    <link href="./styles.css" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css?family=Anaheim" rel="stylesheet">
    <meta charset="UTF-8">
    <title>NASA Photo Of The Day</title>
  </head>
  <body>
    <div id='app'>
      <section class='hero'>
      <h1 class='title'>{{ title }}</h1>
    </section>
    <section class='picture-area'>
      <div class='info'>
        <h2>{{ images[currentNumber].title }}</h2>
        <p v-bind='description'>{{ description }}</p>
        <img class='image-of-day' :src='images[currentNumber].image' />
        <p class='date'>{{ images[currentNumber].date }}</p>
        <button :disabled="!currentNumber" v-on:click="previous" class='backward'>previous</button>
        <button :disabled="!photosAvailable" v-on:click="next" :class="{disabledButton: !photosAvailable}" class='forward'>next</button>
      </div>
    </section>
    </div>
  <script src="https://cdn.jsdelivr.net/npm/vue"></script>
  <script src="https://unpkg.com/[email protected]/dist/axios.min.js"></script>
  <script src='./index.js'></script>
  </body>
</html>

In my Vue devtools, I can see that photosAvailable does turn to false, which should change the button to disabled, but it is not.

Hope someone can catch my error, as it is my first time using Vue.

Upvotes: 1

Views: 728

Answers (2)

Ana Liza Pandac
Ana Liza Pandac

Reputation: 4861

Here's one approach that you can use to make it work including the parts that you should improve on your current code.

  • Replace app with this under your methods since using app will cause an error since it's undefined. Use this if you want to get access to any state or method under your component.

  • Since the status of the next and prev buttons are derived from the value of currentNumber of slide, you can define isPrevPhotoAvailable and isNextPhotoAvailable methods under the computed property of your component. With this, you can remove isPhotosAvailable from your state.

Vue.config.devtools = true
var app = new Vue({
  el: '#app',
  data: {
    title: 'Photo of the day!',
    description: '',
    images:   [
    {
      image: 'https://cdn.spacetelescope.org/archives/images/wallpaper2/heic1509a.jpg', date: '1/9/2019', title: 'Beautiful Milky Way'
    },
    {
      image: 'https://img.purch.com/w/660/aHR0cDovL3d3dy5zcGFjZS5jb20vaW1hZ2VzL2kvMDAwLzA2MS8wNzUvb3JpZ2luYWwvY2hhbmRyYS1uZ2M2MzU3LWNvbXBvc2l0ZS5qcGc=', date: '1/10/2019', title: 'Amazing Whirlpool Galaxy'
    },
    {
      image: 'https://icdn3.digitaltrends.com/image/space-engine-featured-510x0.jpg?ver=1', date: '1/11/2019', title: 'Wonderous Large Magellanic Cloud'
    },

  ],
    currentNumber: 0
  }, 
  computed: {
    isNextPhotoAvailable: function() {
      return this.currentNumber + 1  !== this.images.length;
    },
    isPrevPhotoAvailable: function() {
      return this.currentNumber - 1  !== -1;
    }
  },
  methods: {
    next: function() {
      this.currentNumber += 1;
    },
    previous: function() {
      return this.currentNumber -= 1;
    }, 
  }
})
<!DOCTYPE html>
<html>
  <head>
    <link href="./styles.css" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css?family=Anaheim" rel="stylesheet">
    <meta charset="UTF-8">
    <title>NASA Photo Of The Day</title>
  </head>
  <body>
    <div id='app'>
      <section class='hero'>
      <h1 class='title'>{{ title }}</h1>
    </section>
    <section class='picture-area'>
      <div class='info'>
        <h2>{{ images[currentNumber].title }}</h2>
        <p v-bind='description'>{{ description }}</p>
        <img class='image-of-day' :src='images[currentNumber].image' />
        <p class='date'>{{ images[currentNumber].date }}</p>
        <button :disabled="!isPrevPhotoAvailable" v-on:click="previous" class='backward'>previous</button>
        <button :disabled="!isNextPhotoAvailable" v-on:click="next" :class="{disabledButton: !isNextPhotoAvailable}" class='forward'>next</button>
      </div>
    </section>
    </div>
  <script src="https://cdn.jsdelivr.net/npm/vue"></script>
  <script src="https://unpkg.com/[email protected]/dist/axios.min.js"></script>
  <script src='./index.js'></script>
  </body>
</html>

Upvotes: 1

Ninth Autumn
Ninth Autumn

Reputation: 461

Maybe try putting the logic in computed?

Upvotes: 0

Related Questions