こんにちは! フリーエンジニアの長瀬です。
みなさんはajax(エイジャックス)を使っていますか?
ajax(エイジャックス)ってなんだか難しそうだなと思っていませんか?
この記事では順を追って初心者にわかりやすいように説明するので、安心してください。
ajaxを使えば、動的にページ内容を変更できます。
なのでうまく使いこなせばユーザーとの連携がより強いウェブサイトを作成することができます。
この記事では、ajaxの使い方について
・ ajaxとは
・ ajaxを使ってタイトルを変更する方法
という基本的な内容から、
・ajaxを使った入力フォームを実装する方法
といった実践的な内容について解説していきます。
ajaxとは
ajaxはAsynchronous Javascript and XMLの略で、ウェブ開発において使用されるいくつかの技術の総称です。
ajaxにおいて使用される技術を使えば、ページを更新することなくページの内容だけを入れ替えられるので、使い方によってはより快適なウェブページを作成できます。
動的にページを部分的に更新できるので、デスクトップアプリケーションなどにより近い表現になります。
また、ajaxの中核を支えているのはJavacriptの技術です。
XMLHttpRequestと呼ばれる技術を使うことによって、HttpRequestを動的にコントローラーに送ることができ、任意のアクションを動的かつ非同期に実行できます。
また、動的にDOM(Document Object Model)を操作することで,部分的なページの変更(HTML、CSSの変更)を実現しています。
つまり、ajaxの実体はJavascriptにあるわけです。
ただ、ajaxを使用する上ではいくつかのデメリットもあります。
なので、実際の開発ではajaxを使用する部分としない部分を考える必要がでてきます。
具体的には以下の通りです。
・ページを更新しないということはURLが変わらないので、変化後の情報に直接アクセスできない。(変化後のページ内容を直接ブックマークできない)
・変更後に表示された文章は検索エンジンには引っかからないので、SEOの問題がある。
・すべてのブラウザが対応しているわけではない。
・セキュリティーやプライバーシの問題のすべてが解決しているわけではない。
などです。
しかし、これらのデメリットを考えた上でもajaxにはそれを打ち消すくらいの魅力があります。
最近ではSPA(Single Page Application)が流行していて、その中核をなしているのがajaxを使った非同期でのページの更新です。
SPAとはシングルページアプリケーションの略で、名前のとおりajaxを多用することでページ遷移に頼らないウェブアプリケーションの形式のことです。
SPAを実現するためのフレームワークはBackbone、Angular、Ember、Riot、Vue、React、Knockoutなどがあり、数多く開発されています。
Railsでも5.1からはjQuery依存が解消されたりと、これらのフレームワークをRailsで使用する場面がこれから増えてきます。
なので、この記事でしっかりとajaxの基本的な流れと概念を理解しておきましょう。
ajaxを使って動的にタイトルを変更する方法
それでは、まずはajax(エイジャックス)の導入として、テキストボックスに入力した値を用いてタイトルを動的に変更してみましょう。
実行環境のRailsのバージョンは5.0.5です。
今回使用するコントローラーを作成するためコマンドプロンプトに以下のコードを入力してください。
[Practiceコントローラーとindexアクションを作成する]
rails g controller Practice index
[実行結果]
create app/controllers/practice_controller.rb route get 'practice/index' invoke erb create app/views/practice create app/views/practice/index.html.erb invoke test_unit create test/controllers/practice_controller_test.rb invoke helper create app/helpers/practice_helper.rb invoke test_unit invoke assets invoke coffee create app/assets/javascripts/practice.coffee invoke scss create app/assets/stylesheets/practice.scss
これで、コントローラーを作成することができました。
では、まずはViewを整えていきましょう。
作成したapp/views/practice/index.html.erbを以下のように修正してください。
[app/views/practice/index.html.erbの内容]
<h1>Ajaxを使ってみよう</h1> <%= form_tag(url_for(:action => 'index'), :remote => true) do %> <%= text_field_tag :title %> <%= submit_tag "タイトルを変更する" %> <% end %>
これで、Viewを作成できました。
ここで大切なのは、:remote => trueの部分です。こう記述することによってturbolinkを有効にできます。
Railsではturbolinkを使えば、ajaxが自動的に使えるようになります。
これがRailsでajax実装のコストが低いと言われる理由です。
次はPracticeコントローラーの内容を修正します。
作成したapp/controllers/practice_controller.rbのindexアクションを以下のように修正してください。
[app/controllers/practice_controller.rbのindexアクションの内容]
def index @title = params[:title] respond_to do |format| format.html format.js end end
indexでポストされたデータをparams[:title]で受け取った後、respond_toメソッドを使って結果をどのフォーマットで返すかを指定しています。
turbolinkが有効でないときはformat.htmlになり、有効な時はformat.jsが選ばれます。
format.jsが選ばれると、次に実行されるファイルはindex.js.erbです。このファイルにJavascript(jQueryやCoffeescript等)を記述することによって動的にDOMを操作できます。(HTML、CSSの変更)
またindexにポストしているので、app/config/routes.rbに以下のようにリソースを振り分けてください。
[app/config/routes.rbの内容]
get 'practice/index' post 'practice/index'
post ‘practice/index’以外はrails g controllerの際に作成されています。
それでは、次はformat.jsで指定したindex.js.erbをapp/views/practice/に作成して内容を以下のようにしてください。
[app/views/practice/index.js.erb]
$('h1').html("<%= @title %>");
h1の要素を指定して、内容をテキストフィールドで入力された値に変更しています。
それではajaxの準備が整ったので実際に非同期かつ動的にタイトルを変更してみましょう。
確認するためにコマンドプロンプトにrails sと入力して、サーバーを起動してください。
以下のURLにアクセスして、app/views/practice/index.html.erbを開いてください。
http://localhost:3000/practice/index(補足http://localhost:3000の箇所は各自の開発環境により読み替えてください。)
では、実際に値を打ち込んでタイトルを変更してみましょう。
このように動的にDOMを操作して、HTMLを変更できました。
また、URLが本当に変わっていないか確かめてみてください。
Railsにおけるajaxの流れを確認すると以下の通りです。
1.turbolinkまたはjQueryなどを使って、JavascriptでXMLHttpRequestを送り任意のアクションを実行する(今回はindexアクション)
2.アクションが実行される(この間にデータベースとのやりとりができる)。また、どの形式でデータを返却するかを指定することができる。(Javacript、JSON、XMLなど)
3.選択されたデータ形式で(今回はJavascript)ファイルを自動的に検索して、ファイル内容を実行する(今回はindex.js.erb)ここで、HTML&CSSが変更されて、ajaxが完結する。
index.js.erbなどややたくさんのファイルを作成する必要がありますが、ひとつひとつの役割を頭に入れてをおいてください。
順番を追って理解すれば、そう難しいものではないので、ajaxを使うときはこの流れをしっかりとイメージできるようにしましょう。
ajaxを使った入力フォームを実装する方法
続いてはより実践的な内容です。
ajaxを使った動的な入力フォームを作成してみましょう。
今回実装することは
・ボタンを押すとポスト用のフォームが現れる。
・値を入力し、送信すると動的にデータが更新される。
・ポスト用のフォームは消える。
です。
では、まずデータを保存するためにModelを作成しておきましょう。
コマンドプロンプトに以下のコードを入力してください。
[モデルを作成し、マイグレーションファイルを実行する]
rails g model Apple name:string rake db:migrate
[実行結果]
invoke active_record create db/migrate/20170807063503_create_apples.rb create app/models/apple.rb invoke test_unit create test/models/apple_test.rb create test/fixtures/apples.yml == 20170807063503 CreateApples: migrating ===================================== -- create_table(:apples) -> 0.0052s == 20170807063503 CreateApples: migrated (0.0053s) ============================
nameのカラムを持ったAppleモデルを作成することに成功しました。
次はコントローラーです。コンマンドプロンプトに以下のコードを入力してください。
rails g controller apples
[実行結果]
create app/controllers/apples_controller.rb invoke erb create app/views/apples invoke test_unit create test/controllers/apples_controller_test.rb invoke helper create app/helpers/apples_helper.rb invoke test_unit invoke assets invoke coffee create app/assets/javascripts/apples.coffee invoke scss create app/assets/stylesheets/apples.scss
これでコントローラーが作成されました。
次はリソースを振り分けるので、app/config/routesに以下のコードを追加してください。
resources :apples
これでRESTfulなリソースの振り分けができます。
RESTfulなリソースの振り分けがわからない人は以下の記事を参考にしてみてください。
まずはコントローラーからコードを書いていきましょう。
app/controller/apples_controller.rbに以下のコードを追加してください。
[app/controller/apples_controller.rbに追加する内容]
class ApplesController < ApplicationController def index @apples = Apple.all end def new @apples = Apple.new respond_to do |format| format.html format.js end end def create @apples = Apple.all @apple = Apple.new(apple_params) respond_to do |format| if @apple.save format.html format.js else format.js {render :new} end end end def apple_params params.require(:apple).permit(:name) end end
respond_toの挙動は前節で説明したとおりです。
では、次にViewの作成をしていきましょう。app/views/apples/index.html.erbを作成して以下のコードを入力してください。
[app/views/apples/index.html.erbの内容]
<h1>Appleモデル一覧</h1> <table class="table" id="apples"> <%= render @apples %> </table> <%= link_to "データを追加する", new_apple_path, remote: true %> <div id="apple-form"></div>
<%= render @apples =>の部分でパーシャルを入れているので、該当するパーシャルを作成する必要があります。
app/views/apples/_apple.html.erbを作成して以下のコードを入力してください。
(@applesのように、書くと自動的に_apple.html.erbを検索します。)
[app/views/apples/_apple.html.erbの内容]
<tr> <td> <%= apple.name %> </td> </tr>
これでコントローラーで設定した変数から値を出力できます。
[indexアクションの内容]
def index @apples = Apple.all end
また、前節で説明したようにlink_toにremote:trueを加えることによって自動的にajaxでの処理にすることができます。
これで、"データを追加する”のボタンを押すと、applesのnewアクションが実行されます。
[newアクションの内容]
def new @apples = Apple.new respond_to do |format| format.html format.js end end
ajaxで実行しているので、format.jsに該当するnew.js.erbを返します。
なので、app/views/apples/new.js.erbを作成して、以下のコードを入力してください。
[app/views/apples/new.js.erbに追加する内容]
$('#apple-form').html("<%= j (render 'form') %>"); $('#apple-form').fadeIn(800);
これで<div id="apple-form"></div>の箇所に入力フォームが動的に表示されるようになります。
また、renderでformを指定しているので、_form.html.erbを作成して入力フォーム用のコードを入力する必要があります。
[app/views/apples/_form.html.erbの内容]
<%= simple_form_for @apples, remote: true do |f| %> <%= f.input :name %> <%= f.button :submit ,"追加" %> <% end %>
こちらはsimpel_formというformを簡素化してくれるgemを使用しています。
ですので、Gemfileに
gem 'simple_form'
を入力した後、bundle installをしてgemを有効にしてください。
また、sime_formの初期設定のためにコマンドプロンプトに以下のコードを入力してください。
rails generate simple_form:install
これで、simple_formが使用可能になります。
ここまでで
・ボタンを押すとポスト用のフォームが現れる。
まで完了しました。
残りは
・値を入力し、送信すると動的にデータが更新される。
・ポスト用のフォームは消える。
です。
この後はフォームに値を入力してポストした後の動作を実装していきます。
値がポストされるとコントローラーで設定したcreateアクションが呼び出されます。
[createアクションの内容]
def create @apples = Apple.all @apple = Apple.new(apple_params) respond_to do |format| if @apple.save format.html format.js else format.js {render :new} end end end
値を受け取って、saveに成功すればformat.jsに該当するcreate.js.erbが実行されます。
ですので、app/views/apples/create.js.erbを作成して以下のコードを作成してください。
[app/views/apples/create.js.erbの内容]
$('#apples').html("<%= j (render 'index') %>"); $('#apple-form').fadeOut(600);
render ‘index’の部分でindexのパーシャルを出力し、またfadeOutでフォームを見えないようにしています。
では、パーシャルの内容を入力していきましょう。app/views/apples/_index.html.erbを作成して以下のコードを入力してください。
[app/views/apples/_index.html.erbの内容]
<%= render @apples %>
これで、自動的に_apple.html.erbにアクセスして値を更新します。
これで、ajaxの設定が完了しました。長い設定でしたが、作成したviewは
・_apple.html.erb
・_form.html.erb
・_index.html.erb
・create.js.erb
・index.htlm.erb
・new.js.erb
の6つです。
すべて作成されているか確認してください。
確認できたら、結果を確認するためにコマンドプロンプトにrails sと入力して、サーバーを起動してください。
以下のURLにアクセスして、index.html.erbを開いてください。
http://localhost:3000/apples[実行結果]
このように表示されます。
では、実際にデータを追加してみてください。
このように、ajaxで動的に入力フォームを作成することができました。
まとめ
いかがでしたでしょうか?
この記事では、ajaxの使い方を解説しました
ajaxはJavascriptによって実現している技術だということがお分かりいただけたかと思います。
ajaxを使いこなせるようになれば、スピード感あふれる快適なウェブサイトを開発できます。
本格的な実装には少したくさんの処理を必要としますが、基本を理解していれば対応できます。
これを機会にajaxでの実装を勉強してみてください。
もしajaxの使い方について忘れてしまったらこの記事を確認してくださいね!