1

I'm trying to update a v-html binding using JS but I seem to be a bit stuck. Could anyone help?

The idea of the code is that I have a list of items per page. And I want to create a pagination. Where the pagination numbers represent the current_page

The problem is that I'm trying to update the page number but I can't seem to get it to work.

I've added this inside a jsfilde

var configuration = {
  searchableFields: ['title', 'tags', 'actors'],
  sortings: {
    name_asc: {
      field: 'name',
      order: 'asc'
    }
  },
  aggregations: {
    tags: {
      title: 'Tags',
      size: 10
    },
    actors: {
      title: 'Actors',
      size: 10
    },
    genres: {
      title: 'Genres',
      size: 10
    }
  }
}

// the rows comes from external resources
// https://github.com/itemsapi/itemsapi-example-data/blob/master/jsfiddle/imdb.js
itemsjs = itemsjs(rows, configuration);
var per_page = 3;
var current_page = 1;

var vm = new Vue({
  el: '#el',
  data: function() {

    // making it more generic
    var filters = {};
    Object.keys(configuration.aggregations).map(function(v) {
      filters[v] = [];
    })

    return {
      query: '',
      // initializing filters with empty arrays
      filters: filters,
    }
  },
  methods: {
    reset: function() {
      var filters = {};
      Object.keys(configuration.aggregations).map(function(v) {
        filters[v] = [];
      })

      this.filters = filters;
      this.query = '';
    }
  },
  computed: {
    searchResult: function() {

      var result = itemsjs.search({
        query: this.query,
        filters: this.filters,
        per_page: per_page,
        page: current_page
      })
      return result
    }
  }
});

var content = "";
var active = "";
var total = document.getElementById("pagination__total").value;
var num_pages = Math.ceil(total / per_page);
console.log(num_pages);
for (var i = 1; i <= num_pages; i++) {
  active = current_page == i ? "is-current" : "";
  content += `<li class="pagination-link is-size-6 ${active}" data-page="${i}">${i}</li>`;
}
document.querySelector(".pagination-list").innerHTML = content;
content = "";


let pagination = document.querySelectorAll(".pagination-link");
for (let i = 0; i < pagination.length; i++) {
  pagination[i].addEventListener("click", ev => {
    current_page = ev.target.getAttribute("data-page");
    console.log(current_page);
    vm.searchResult.page = current_page;
  });
}
<script src="https://cdn.jsdelivr.net/vue/latest/vue.js"></script>
<script src="https://cdn.rawgit.com/itemsapi/itemsjs/master/dist/itemsjs.js"></script>
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdn.rawgit.com/itemsapi/itemsapi-example-data/master/jsfiddle/imdb.js"></script>
<div id="el">
  <nav class="navbar navbar-default navbar-fixed-top">
    <div class="container">
      <div class="navbar-header">
        <a class="navbar-brand" href="#" v-on:click="reset()">ItemsJS movies</a>
      </div>
      <div id="navbar">
        <form class="navbar-form navbar-left">
          <div class="form-group">
            <input type="text" v-model="query" class="form-control" placeholder="Search">
          </div>
        </form>
      </div>
      <!--/.nav-collapse -->
    </div>
  </nav>

  <div class="container" style="margin-top: 50px;">

    <input type="hidden" v-bind:value="searchResult.pagination.total" id="pagination__total">
    <input type="hidden" v-bind:value="searchResult.pagination.page" id="pagination__curent-page">
    <h1>List of items ({{ searchResult.pagination.total }})</h1>

    <p class="text-muted">Search performed in {{ searchResult.timings.search }} ms, facets in {{ searchResult.timings.facets }} ms</p>

    <div class="row">
      <div class="col-md-2 col-xs-2">
        <div v-for="facet in searchResult.data.aggregations">
          <h5 style="margin-bottom: 5px;"><strong style="color: #337ab7;" v-html="facet.title"></strong></h5>

          <ul class="browse-list list-unstyled long-list" style="margin-bottom: 0;">
            <li v-for="bucket in facet.buckets">
              <div class="checkbox block" style="margin-top: 0; margin-bottom: 0;">
                <label>
                <input class="checkbox" type="checkbox" v-model="filters[facet.name]" v-bind:value="bucket.key">
                {{ bucket.key }} ({{ bucket.doc_count }}) 
              </label>
              </div>
            </li>
          </ul>
        </div>
      </div>

      <div class="col-md-10 col-xs-10">
        <div class="breadcrumbs"></div>
        <div class="clearfix"></div>
        <!--<h3>List of items ({{ searchResult.pagination.total }})</h3>-->
        <table class="table table-striped">
          <tbody>
            <tr v-for="item of searchResult.data.items">
              <td><img style="width: 100px;" v-bind:src="item.image"></td>
              <td></td>
              <td>
                <b v-html="item.name"></b>
                <br />
              </td>
              <td></td>
            </tr>
          </tbody>
        </table>
        <div class="clearfix"></div>
      </div>
      <nav class="pagination is-centered" aria-label="pagination">
        <div>
          <i class="pagination-previous is-size-6 fas fa-angle-double-left"></i>
          <ul class="pagination-list"></ul>
          <i class="pagination-next is-size-6 fas fa-angle-double-right"></i>
        </div>
      </nav>

      <div class="clearfix" style="margin-bottom: 100px;"></div>
    </div>
  </div>
</div>

5
  • no, you should not update computed value like that. Commented Mar 16, 2019 at 9:00
  • what would be the alternative way to do it? Commented Mar 16, 2019 at 9:02
  • please post minimal reproducible example, with script execution order. Commented Mar 16, 2019 at 9:09
  • @appleapple I've updated the code and added a link to jsfiddle. Could you have another look, please? Commented Mar 16, 2019 at 9:27
  • I've post an answer, but since your code is too long, I just make a guess, please try it. Commented Mar 16, 2019 at 9:45

1 Answer 1

1

simply put current_page inside data

...
var vm = new Vue({
  data: function() {
    ...
    return {
      query: '',
      current_page,
      filters: filters
    }
  }
  ...
}

then use vm.current_page instead of current_page

pagination[i].addEventListener("click", ev => {
  vm.current_page = ev.target.getAttribute("data-page");
  console.log(vm.current_page);
});

and

searchResult: function() {

  var result = itemsjs.search({
    query: this.query,
    filters: this.filters,
    per_page: per_page,
    page: this.current_page // <-----
  })
  return result
}
Sign up to request clarification or add additional context in comments.

1 Comment

@Selyst no problem :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.