[RUBY] [Rails] Make pagination compatible with Ajax

1. 1. Introduction

Regarding the pagination of the home screen of the web application (childcare site- * SUKUSUKU *-) currently being created, when I moved to another page, I felt stressed that it was reloaded and moved to the top of the page. So I wanted to make pagination compatible with Ajax to make it easier to use. ezgif-7-71eb2ec20490.gif

** What you can see in this article ** ・ Basic mechanism of Ajax communication ・ Typical JavaScript library ・ Ajax in Rails ・ Make pagination compatible with Ajax

2. What is Ajax in the first place?

According to wikipedia, Ajax is

A programming method that builds an interface while performing asynchronous communication within a web browser. Using asynchronous communication by XMLHttpRequest (JavaScript built-in class for HTTP communication), take the approach of dynamically rewriting a part of the page with dynamic HTML (DHTML) according to the communication result. Ajax stands for Asynchronous JavaScript + XML and was named by US information architect Jesse James Garrett on February 18, 2005.

And that. I will explain in a little more detail.

What is asynchronous communication?

Since it is asynchronous communication with synchronous communication, we will first explain synchronous communication. In synchronous communication, as shown in the figure below, some operation is performed on the user interface and the request is sent to the Web server. Then, the Web server receives the response, processes it in the database, etc., and sends the result to the browser side in the response of HTML, CSS, etc. The browser will reload and you will see the results.

名称未設定ファイル.png

In the synchronous map app, the browser was reloaded when moving or zooming in from the currently displayed position.

r20imasara03_01.gif

Asynchronous communication allows dynamic processing within a web browser using JavaScript. When something is done on the user interface as shown in the figure below, JavaScript is called to the Ajax engine in the browser instead of communicating directly to the server. The Ajax engine sends HTML and CSS as a response to the user interface, and the DOM is displayed in the browser. At this point, the browser and server are not in the same state, so the Ajax engine sends a ** XMLHTTP request (XHR) ** to the web server. The server side responds as XML and JSON as the result of receiving the request.

非同期通信.png

With the map application of asynchronous communication, if you move or enlarge from the currently displayed position, you can perform dynamic processing without reloading on the browser side.

ezgif-4-050dab99fd38.gif

In other words

** Synchronous communication **: After waiting for server communication, the browser is reloaded and dynamic processing is possible.

** Asynchronous communication **: Dynamic processing can be performed without waiting for server communication. The browser will not reload at that time.

about it.

What is XML?

Abbreviation for Extensible Markup Language. One of the markup languages. HTML is the language used to exchange data and write configuration files, as opposed to the language used to display web pages. It is called an "extensible markup language" because you can freely edit tags and so on.

<?xml version="1.0" encoding="UTF-8" ?>
<Grocery>
  <food>
    <name>Apple</name>
    <color>Red</color>
  </food>
</Grocery>

In this way, tags can also be written in Japanese.

What is JSON?

Abbreviation for JavaScript Object Notation. A common data definition language similar to XML. It is a format that is easy for humans to read and write, and easy for machines to parse and generate.

I used it as a reference → Introduction to JSON

What is DOM?

Abbreviation for Document Object Model. A programming interface for HTML and XML documents. The DOM expands HTML and XML as a tree structure. Ajax uses the DOM to rewrite only part of the user interface.

Referenced → Introduction of DOM

3. 3. Advantages and disadvantages of using Ajax

merit

-High-speed dynamic processing can be performed without waiting for a response from the server.

-The amount of data received can be reduced.

-The server is not burdened.

Demerit

-During development, the browser is not reloaded, so no error message is displayed on the screen. It's hard to tell where the error is.

・ Cross-browser countermeasures [^ 1] are required

-Validation must be described on both JS and server side.

It seems that the advantages are mainly on the user side and the disadvantages are on the development side.

4. JavaScript framework

You need to learn JavaScript to use Ajax. There are several frameworks that make it easier to write JavaScript, so here are some typical ones.

jQuery The most popular framework for simplifying Ajax processing. The grammar is simple and easy to remember. It does not depend on the type of browser, and can handle a wide range of areas from animation to effects and asynchronous communication.

Angular A framework developed by Google and the personal and corporate communities. Mainly suitable for large-scale applications. Learning costs are high because there are many unique concepts and functions.

React A framework developed by Facebook and the community. Since it is a library with only the UI part, use it together with other frameworks. Instead, it works fast.

Vue.js Simple, lightweight and fast. With powerful component functions, data and processing can be separated, and communication with the server can be performed at high speed.

5. Ajax in Rails

Rails calls the technique for adding JavaScript to the DOM ** "UJS: Unobtrusive JavaScript" **. If JavaScript is mixed in HTML, it often violates the principle of DRY [^ 2], and it becomes complicated and difficult to maintain. Therefore, Rails uses a method that correctly separates JavaScript and does not expose it. Rails allows you to execute any JavaScript with these "minimization" and "concatenation". To actually embed JavaScript in the link, turn on the remote option on the view as shown below.

<%= link_to "article", @article, remote: true %>

Now you can embed JavaScript.   Reference → Using JavaScript with Rails

6. Make pagination Ajax compatible

environment

This time, considering the learning cost, we decided to use ** jQuery ** as the framework.

Put jQuery in Rails

First, you need to add jQuery to both Webpack and Yarn.

Terminal


$ yarn add jquery

config/webpack/environment.js


const { environment } = require('@rails/webpacker')

const webpack = require('webpack')
environment.plugins.prepend('Provide',
  new webpack.ProvidePlugin({
    $: 'jquery/src/jquery',
    jQuery: 'jquery/src/jquery'
  })
)

module.exports = environment

Requires jQuery in the application.js file.

app/javascript/packs/application.js


require("@rails/ujs").start()
require("turbolinks").start()
require("@rails/activestorage").start()
require("channels")
require("jquery")

You can now use jQuery with Rails.

View (HTML)

First make the view Ajax ready.

HTML:app/views/static_pages/home.html.erb


-Only the pagination part is described-
  .
  .
<div class="question-index">
  <%= paginate @questions, remote: true %>
    <%= render partial: 'questions/question', collection: @questions %>
  <%= paginate @questions, remote: true %>
</div>
  .
  .

Write remote: true in pagenate. The HTML of pagination generated by this home.html.erb is below.

HTML


<ul class="pagination">
  <li class='active'>
    <a data-remote="true">1</a>
  </li>
  <li>
    <a rel="next" data-remote="true" href="/?page=2">2</a>
  </li>
  <li>
    <a rel="next" data-remote="true" href="/?page=2">Next&rsaquo;</a>
  </li>
  <li>
    <a data-remote="true" href="/?page=2">last&raquo;</a>
  </li>
</ul>
```

 All pagination links now have `` data-remote = "true" ``.
 This allows Rails to be informed that JavaScript is allowed to manipulate forms.

 <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/687088/0cb6e3b0-2b9f-c5cc-3fd1-ef28f16e879d.png " width="30%">
 ↑ The generated pagination.

#### controller

 Then enable the controller to respond to Ajax requests.


#### **`app/controllers/static_pages_controller.rb`**
```ruby

class StaticPagesController < ApplicationController

  def home
    @questions = Question.page(params[:page]).per(10).all
    respond_to do |format|
      format.html
      format.js
    end
  end

end
```

 The `` respond_to`` method executes any one of the code in the block.
 Normally, `` format.html`` is called as a response, but this time the pagination link is `` data-remote = "true" `` and the `` remote`` option is turned on, so ` `format.js`` will be called.

#### View (HTML)
 Finally, use jQuery to make it Ajax compatible.
 Before that, move the code in home.html.erb to partial so that it can be called by jQuery.


#### **`HTML:app/views/static_pages/home.html.erb (review)`**
```

<div id="home_pagenate">
  <%= render partial: 'index_page' %>
</div>
```

 Paste the original home.html.erb code into the partial.


#### **`HTML:app/views/static_pages/_index_page.html.erb`**
```

-Only the pagination part is described-
  .
  .
<div class="question-index">
  <%= paginate @questions, remote: true %>
    <%= render partial: 'questions/question', collection: @questions %>
  <%= paginate @questions, remote: true %>
</div>
  .
  .
```

 Create a JS file and write the jQuery code.


#### **`javascript:home.js.erb`**
```

 $('#home_pagenate').html("<%= escape_javascript(render 'index_page') %>");
```
 Now, when pagination with `` data-remote = "true" `` is executed, the controller will call the JS file and render the original page in the JS file. This completes Ajax support.

#### Completed form

 ![ezgif-6-bfbd4116adbc.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/687088/7e84ee1e-7dfc-e6bf-3665-e6a201675750.gif)

 There seems to be an easier way, but it worked fine for the time being! !!

# 7. Summary
 I've been studying Ruby for a while, but I'm not familiar with JavaScript, so I summarized it. The learning cost is reasonably high, and maintenance seems to be difficult for beginners, so I would like to identify the necessary parts.

 [^ 1]: Guaranteed to work on all browsers.
 [^ 2]: Don't Repeat Yourself "Avoid Repeating"


Recommended Posts

[Rails] Make pagination compatible with Ajax
Create pagination function with Rails Kaminari
[Rails 6] Interactive graph drawing with Ajax + chart.js
Make a login function with Rails anyway
Make a site template easily with Rails
Let's make an error screen with Rails
Implement Rails pagination
Make SpringBoot1.5 + Gradle4.4 + Java8 + Docker environment compatible with Java11
Let's make a search function with Rails (ransack)
Implement the Like feature in Ajax with Rails.
How to make batch processing with Rails + Heroku configuration
Compatible with Android 10 (API 29)
Make Calendar gadgets made with JavaFX compatible with Java SE 9
About rails kaminari pagination
Rails deploy with Docker
How to make an almost static page with rails
[Rails 6] RuntimeError with $ rails s
Handle devise with Rails
[Rails] Learning with Rails tutorial
[Rails] Test with RSpec
Make Nginx of CentOS8 SSL compatible with Let's Encrypt
[Rails] Development with MySQL
Pagination implementation with gem'kaminari'
Supports multilingualization with Rails!
Double polymorphic with Rails
Create Rails5 and postgresql environment with Docker and make pgadmin available
Rails implementation of ajax removal
Introduced graph function with rails
[Rails] Express polymorphic with graphql-ruby
[Rails] Upload videos with Rails (ActiveStorage)
Try using view_component with rails
Make your own Rails validate
[Vue Rails] "Hello Vue!" Displayed with Vue + Rails
Japaneseize using i18n with Rails
API creation with Rails + GraphQL
Preparation for developing with Rails
Microservices with DevOps Make Changes
Implement jCaptcha reload with ajax
Run Rails whenever with docker
[Docker] Rails 5.2 environment construction with docker
Use multiple databases with Rails 6.0
[Rails] Specify format with link_to
Login function implementation with rails
Ajax bookmark function using Rails
[Rails] Make a breadcrumb trail
[Rails] How to make seed
[Docker] Use whenever with Docker + Rails
[Rails 6] Pagination function implementation (kaminari)
I tried to make a group function (bulletin board) with Rails
Summary of what we did to make JavaScript compatible with IE11