Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pushState with Rails ajax

I have an index action page showing a list of items with are paginated with Kaminari and I have added ajax functionality to them and now am trying to get the URL to fit in by using pushState.

My question is how do I get the URL to pass to the pushState method when my pagination links are done via:

<%= paginate @coasters, remote: true %>

and the javascript view is as follows:

$('.grid').html('<%= escape_javascript render(@coasters) %>');
$('.pagination').html('<%= escape_javascript(paginate(@coasters, remote: true).to_s) %>');

I need to somehow get the URL to pass as the 3rd argument of pushstate from what I have read?

UPDATE:

I've changed it to the following:

$(document).ready(function() {

  $(document).on('click', '.pagination a[data-remote=true]', function(e) {
    history.pushState({}, '', $(this).attr('href'));
  });

  $(window).on('popstate', function () {
    $('.grid').html('<%= escape_javascript render(@coasters) %>');
    $('.pagination').html('<%= escape_javascript(paginate(@coasters, remote: true).to_s) %>');
  });

});

$('.grid').html('<%= escape_javascript render(@coasters) %>');
$('.pagination').html('<%= escape_javascript(paginate(@coasters, remote: true).to_s) %>');

So I think my code now bypasses the rails jQuery UJS by capturing the click on the pagination remote true link myself and the URL is sort of working.

It seems like the URL sometimes updates. The back button also fails.

Any ideas where I am going wrong?

UPDATE 2:

I moved a chunk of my javascript to my main pages javascript rather than the javascript view:

  $(document).on('click', '.pagination a[data-remote=true]', function(e) {
    history.pushState(null, '', $(this).attr('href'));
  });

  $(window).on('popstate', function () {
    console.log('popState started');
    $('.grid').html('<%= escape_javascript render(@coasters) %>');
    $('.pagination').html('<%= escape_javascript(paginate(@coasters, remote: true).to_s) %>');
  });

With the popstate stuff removed the above codeupdates the URL perfectly when the links are clicked but when I add the popState stuff back in the postate is called as soon as I do a page refresh to test and my grid area gets replaced with a text output of the following line son my page:

$('.grid').html('<%= escape_javascript render(@coasters) %>');
$('.pagination').html('<%= escape_javascript(paginate(@coasters, remote: true).to_s)

How can I get the popstate to work correctly?

like image 512
rctneil Avatar asked Nov 11 '22 15:11

rctneil


1 Answers

I was in a similar situation and this is how I solved it. I am not sure whether this will work with Kaminari since I have no idea, how kaminari works.

#index.html.erb
<div class="grid">
  <%= render(@coasters) %>
</div>
<div class="pagination">
  <%= paginate @coasters, remote: true %>
</div>

--

#index.js.erb
$('.grid').html('<%= escape_javascript render(@coasters) %>');
$('.pagination').html('<%= escape_javascript(paginate(@coasters, remote: true).to_s) %>');

On pagination, since data-remote is enabled they will render index.js.erb only.

In my JavaScript

  $(document).on('click', '.pagination a[data-remote=true]', function(e) {
    history.pushState({}, '', $(this).attr('href'));
  });

  $(window).on('popstate', function () {
    $.get(document.location.href)
  });

On clicking on the pagination links, data-remote will be handle the ajax request and render index.js.erb

But on clicking the back button of browser the popstate event will be fired and current url in the browser will be link from history. SO we fire another ajax request with that url with $.get(document.location.href). This will have the same effect of clicking on the previous in pagination.

like image 96
RSK Avatar answered Nov 15 '22 11:11

RSK