question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Appending pagination after click

See original GitHub issue

Hello,

I contacted email support and Sylvain Utard asked me to ask this here, since he thinks that is makes a lot of sense to integrate it by default in instantsearch.js.

I’m building a pagination widget that appends the results. I based it on the infinite scrolling widget.

Code:

function getTemplate(templateName) {
  return document.getElementById(templateName + '-template').innerHTML;
}


function getParameterByName(name, url) {
    if (!url) url = window.location.href;
    name = name.replace(/[\[\]]/g, "\\$&");
    var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
        results = regex.exec(url);
    if (!results) return null;
    if (!results[2]) return '';
    return decodeURIComponent(results[2].replace(/\+/g, " "));
}


var cursor;
var index;
var page;
var nbPages;
var loading;
var hoganTemplate;
var hoganTemplateItem;
var paginator

var hitsDiv = document.getElementById('hits');

function renderTemplate(hoganTemplate, res) {

  var results = document.createElement('div');
  results.innerHTML = hoganTemplate.render(res);
  return results;
}

function searchNewRecords(scope) {
    addSearchedRecords.call(scope);
}



function addSearchedRecords() {

  if (!loading && page < nbPages - 1) {
    loading = true;
    page += 1;
    var stateObject = {paginator: (page+1)};

    history.pushState(stateObject, '', '?paginator='+stateObject.paginator);

    helper.searchOnce({page: page}, appendSearchResults.bind(this));
  }
  else if(page >= nbPages - 1)
  {
      document.getElementById('bcPagination').className="hidden";
  }
}

function appendSearchResults(err, res, state) {
  if (err) { throw err; }

  page = res.page;
  _.assign(res, {pageNo: page + 1});
  loading = false;

  var container = this.container;
  hoganTemplateItem = this.hoganTemplateItem;
 _.forEach(res.hits, function(value)
 {
  var result = renderTemplate(hoganTemplateItem, value);
  container.appendChild(result);
});
  if (page === nbPages - 1 && (this.args.results.nbHits > nbPages * this.args.results.hitsPerPage)) {
    index = helper.client.initIndex(this.args.state.index);
  }
}


function appendBrowsedResults(err, res) {
  if (err) { throw err; }

  cursor = res.cursor;
  var result = renderTemplate(hoganTemplateItem, res);
  this.container.appendChild(result);

  loading = false;
}

function initialRender(container, args, hoganTemplateItem, hoganTemplateEmpty, parent) {
  var results;

  if (args.results.nbHits) {
    _.assign(args.results, {pageNo: page + 1});
    results = renderTemplate(hoganTemplateItem, args.results);
  } else {
    results = renderTemplate(hoganTemplateEmpty, args.results);
  }

  container.innerHTML = '';
  container.appendChild(results);

}

function bcPagination(options) {
  var container = document.querySelector(options.container);
  var templates = options.templates;
  var hoganTemplateItem = Hogan.compile(templates.item);
  var hoganTemplateEmpty = Hogan.compile(templates.empty);
  var offset = parseInt(options.offset, 10);

  if (!container) {
    throw new Error('BCPagination: cannot select \'' + options.container + '\'');
  }

  return {
    init: function ({helper}) {
      page = undefined;
      nbPages = undefined;
      paginator = getParameterByName('paginator');

      //initialRender(container, args, hoganTemplateItem, hoganTemplateEmpty);
    },

    render: function (args) {
      helper = args.helper;
      page = args.state.page;
      nbPages = args.results.nbPages;
      paginator = page;

      var scope = {
        hoganTemplateItem: hoganTemplateItem,
        hoganTemplateEmpty: hoganTemplateEmpty,
        container: container,
        args: args,
        offset: offset
      };

      initialRender(container, args, hoganTemplateItem, hoganTemplateEmpty);

      var $bcPage = this;

      if (args.results.nbHits) {
          if(nbPages > 1){
              document.getElementById('bcPagination').className="text-center";
          }
          else{
              document.getElementById('bcPagination').className="hidden";
          }

          $(document).on('click', '#bcPagination a', function(e)
          {
                e.preventDefault();
                searchNewRecords(scope);
           });
    }

    }

  };
}

instantsearch.widgets.bcPagination = bcPagination;

search.addWidget(
    instantsearch.widgets.bcPagination({
    container: '#hits',
    hitsPerPage: 10,
    templates: {
      item: getTemplate('hit'),
      empty: getTemplate('no-results')
    }
  })
  );

The default functionality is working, but I also want to save the state in the url so when a page is reloaded or a visitor uses the back button in the browser the same amount of items are loaded (so when a user visited page 5 before there should be 40 extra results loaded automatically).

I’m quite sure I can build the initial loading, but the main issue is in de history.pushState, I can’t figure out how to retrieve the other filters’ data…

How do I use the Instantsearch functions for this? Since I saw there were some functions in the instantsearch.js file that handle this functionality?

Or if there is going to be a default widget that handles this type of pagination, when can I expect this? Since I’m sure your code will be much better than mine and when it’s integrated in the instantsearch.js project it will be more future proof.

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Comments:7 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
Maaarkcommented, Jul 5, 2016

Ok, no problem. This is good enough for now 👍

0reactions
vvocommented, Jul 5, 2016

when I apply a filter I want to reset the hitsperpage to the default value, how do I do that?

Hmm this is not currently doable sadly, we have #1068 that would allow you to do custom actions when you refine on something.

In the meantime I do not see any quickfix to do that.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Handle click on pagination link - javascript - Stack Overflow
It run handlePageClick method after run the app, not after click. Second method I tryed: const linkRef = useRef(null); const handlePageClick = ( ......
Read more >
How to append pages under pagination of HTML table? - MSDN
I have created my user defined paginate function in which I am trying to introduce navigation buttons next & previous.
Read more >
Pagination - Bootstrap
Documentation and examples for showing pagination to indicate a series of related content exists across multiple pages.
Read more >
Pagination buttons with CSS and Javascript - YouTube
A simple walkthrough on how to create a simple pagination button similar to the one used in the google results page for navigation....
Read more >
How To Make Pagination In Website Using HTML CSS And ...
Learn to create Pagination In Website Using HTML CSS And JavaScript | Website design tutorial step by step #htmlandcss #javascript ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found