Start Ajax On Rails part1 (Link)
เราจะพูดถึงการ implement Ajax โดยใช้ library ที่เรียกว่า "Prototype" เพื่อช่วยในการสร้างลิงค์และ form ในรูปแบบของ Ajax
1. สร้าง Rails Application
1.1 สร้าง Controller + Action
script/generate controller chap3 get_time repeat reverse
ประกอบไปด้วย
- 1 controller
- 3 Action (Method)
- get_time, repeat, reverse
1.2 สร้าง HTML Layout และ style sheet (CSS)
1.2.1 HTML Layout
สร้าง HTML Layout : app/views/layouts/application.rhtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>Ajax on Rails</title>
<%= javascript_include_tag :defaults %>
<%= stylesheet_link_tag "application" %>
</head>
<body>
<h1>Ajax on Rails</h1>
<%= yield %>
</body>
</html>
จาก code ด้านบน มีการเรียกใช้
javascript_include_tag :defaults เป็นการเรียกใช้ไฟล์ javascript ที่มีอยู่โดยพื้นฐาน ( prototype.js, effects.js, dragdrop.js, and controls.js)
และ
yield เป็น code ruby ที่นำ content ของ action template มาแทรกใน layout นี้
1.2.2 Css
สร้าง CSS : public/stylesheets/application.css
body {
background-color: #eee;
color: #222;
font-family: trebuchet;
padding: 0;
margin: 25px;
}
h1 {
margin: -25px -25px 20px -25px;
padding: 50px 0 8px 25px;
border-bottom: 3px solid #666;
background-color: #777;
color: #fff;
font: normal 28pt georgia;
text-shadow: black 0px 0px 5px;
}
a { color: #229; }
.box {
border: 1px solid;
width: 100px; height: 100px;
padding: 5px;
font-size: .6em;
letter-spacing: .1em;
text-transform: uppercase;
margin-bottom: 20px;
}
.pink {
border-color: #f00;
background-color: #fcc;
}
.green {
border-color: #090;
background-color: #cfc;
}
.hover {
border-width: 5px;
padding: 1px;
}
ul {
background-color: #ccc;
padding: 5px 0 5px 30px;
}
1.2.3 สร้าง HTML
สร้าง HTML Layout : app/views/chap3/index.rhtml และทดลองรัน
"http://127.0.0.1:3000/chap3" จะได้ผลดังภาพด้านล่าง
2. สร้างลิงค์แบบ Simple และ ลิงค์แบบ Ajax
2.1 สร้าง controller
แก้ไขไฟล์ controller:
app/controllers/chapter3_controller.rb โดยการเพิ่มเนื้อหาใน Action เข้าไปดังนี้
class Chapter3Controller < ApplicationController
def get_time
sleep 1.second
render :text => Time.now.to_s
end
end
2.2 Simple link
แก้ไขไฟล์ index.rhtml:
app/view/chap3/index.rhtml
<%= link_to "Check Time", :action => 'get_time' %>
NOTE: ซึ่งจาก code จะมีการเรียกใช้ฟังก์ชั่น helper
link_to เพื่อไปทำงานยังฟังก์ชั่น
get_time ถ้าเรา view source code จะแสดงผลดังนี้
<a href="/chapter3/get_time">Check Time</a>
2.3 Ajax link
แก้ไขไฟล์ index.rhtml:
app/view/chap3/index.rhtml
<%= link_to_remote "Check Time (Ajax link)",
:update => 'current_time',
:url => { :action => 'get_time' } %>
<div id="current_time"></div>
NOTE: มีการเรียกใช้ฟังก์ชั่น
link_to_remote แทน
link_to และใส่ option
:update เพิ่มเข้าไป (ชี้ไปยัง HTML element ID ชื่อ current_time) เพื่อให้ Output ไปแสดงผลที่นั่น (ใน tag DIV ชื่ิอ current_time)
จะเห็นว่า หน้าเว็บเพจจะไม่ refresh ทั้งหน้า มีการรับส่งข้อมูลกันบางส่วนของหน้าเว็บ ช่วยลดโหลดการทำงานระหว่าง server + client ได้
2.3.1 Callback
นอกจากนี้ ยังมี Callback Option
:before สำหรับการแสดงผลก่อนที่จะแสดง Output เพื่อการแสดงผลทำให้ดูดียิ่งขึ้น เนื่องจาก user จะเห็นว่าเว็บเพจกำลัง process อยู่
<%= link_to_remote "Check Time (Call back)",
:update => 'current_time',
:url => { :action => 'get_time' },
:before => "$('current_time').update('Loading...')" %>
<div id="current_time"></div>
NOTE: สรุป Option ของ
link_to_remote
- before : จะมีการทำงานก่อน การแสดง output
- success : จะมีการทำงานเมื่อ การแสดงผลสำเร็จ (ไม่มี error)
- failure : จะมีการทำงานเมื่อ เมื่อการแสดงผลมีปัญหา (มี error)
- complete : จะมีการทำงานเมื่อ การแสดงผลเสร็จสิ้น
<%= link_to_remote "Check Time (Call back Full Option)",
:update => 'current_time',
:url => { :action => 'get_time' },
:before => "$('indicator').show( )",
:success => "$('current_time').visualEffect('highlight')",
:failure => "alert('There was an error. ')",
:complete => "$('indicator').hide( )" %>
<span id="indicator" style="display: none;">Loading...</span>
<div id="current_time"></div>
จากตัวอย่างด้านบน, :before Ajax จะถูกเรียกใช้งานก่อน โดยการแสดงผลคำว่า "Loading..."
- ถ้าการเรียกใช้สำเร็จ จะอยู่ในขั้นของ :success ก็จะมีการสร้าง visual effect ให้กับข้อความที่ปรากฎ (เป็น highlight แสดงแถบสีขึ้นมา)
- แต่ถ้าไม่สำเร็จจะเป็น :failure ที่จะมีข้อความเตือนขึ้นมา
- สุดท้าย :complete จะทำงานโดยการซ่อนข้อความ "loading..." เอาไว้ เมื่อการทำงานสิ้นสุด
2.3.2 Other Options
เราสามารถใช้ :submit callback โดยทุก field จะถูกส่งข้อมูลแบบ POST ซึ่งจะเห็นว่า เราไม่ได้ใช้ tag
form แต่สามารถใช้ tag
div หรือ tag
tr แทนได้
:submit callback สามารถส่งข้อมูลได้
<div id="fakeForm">
<input type="text" name="foo" value="bar" />
</div>
<%= link_to_remote "Submit fake form",
:submit => "fakeForm",
:url => { :action => 'repeat' },
:complete => "alert(request.responseText)" %>
