Drag and Drop
เป็นการใช้หลักการของ Ajax รูปแบบหนึ่ง ซึ่งผู้ใช้สามารถเลือกไปที่วัตถุบน web site แล้วเลื่อนให้วัตถุนั้นๆ สามารถไปยังที่ไหนในหน้า web เพื่อดำเนินการต่อไปได้ ทำให้ web site ดูน่าสนใจมากยิ่งขึ้น
ต้องมีการเรียกใช้ javascript ดังนี้
<%= javascript_include_tag "prototype" %>
<%= javascript_include_tag "dragdrop" %>
การเรียกใช้ javascript ด้านบน ต้องเพิ่มในส่วนของการแสดงผล นั่นก็คือ view นั่นเอง
สิ่งที่ต้องเตรียม
- ฐานข้อมูล ที่มีตารางชื่อ products ดังนี้
CREATE TABLE `products` (
`id` int(11) NOT NULL auto_increment,
`title` varchar(150) NOT NULL default '',
`image_url` varchar(200) NOT NULL default '',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=18 ;
- สร้าง Model ชื่อ product ดังนี้
ruby script/generate model Product
เขียน views : index.rhtml ดังนี้
<%= javascript_include_tag "prototype" %>
<%= javascript_include_tag "dragdrop" %>
<%= stylesheet_link_tag "cartDrag", :media => "all" %>
<div style="margin-bottom:20px;height:120px;">
<% for product in @products %>
<%= image_tag "#{product.image_url}",
:id => "product_#{product.id}",
:alt => product.title,
:class => "products" %>
<%= draggable_element "product_#{product.id}", :revert => true %>
<% end %>
</div>
<div style="height:40px;padding-top:10px;">
<p id="indicator" style="display:none;margin-top:0px;">
<%= image_tag "indicator.gif" %> Updating cart...
</p>
</div>
<h2>Your cart: </h2>
<div id="cart" class="cart" ">
<div id="items">
<%= render :partial => "cart" %>
</div>
<div style="clear:both;"></div>
</div>
<div id="wastebin">
Drop items here to remove them from the cart.
</div>
<%= drop_receiving_element "cart",
:update => "items", :url => { :action => "add" },
:accept => "products", :hoverclass => "cart-active",
:loading => "Element.show('indicator')",
:complete => "Element.hide('indicator')" %>
<%= drop_receiving_element "wastebin",
:update => "items", :url => { :action => "remove" },
:accept => "cart-items", :hoverclass => "wastebin-active",
:before => "Element.hide(element)",
:loading => "Element.show('indicator')",
:complete => "Element.hide('indicator')" %>
อธิบาย code ดังนี้
<%= javascript_include_tag "prototype" %>
<%= javascript_include_tag "dragdrop" %>
<%= stylesheet_link_tag "cartDrag", :media => "all" %>
อธิบาย code
เป็นการ include
javascript ชื่อ prototype.js และ dragdrop.js
style sheet ชื่อ cartDrag.css เพื่อเรียกใช้ต่อไป
<% for product in @products %>
<%= image_tag "#{product.image_url}",
:id => "product_#{product.id}",
:alt => product.title,
:class => "products" %>
<%= draggable_element "product_#{product.id}", :revert => true %>
<% end %>
อธิบาย code
ส่วนแรกของ code ด้านบนเป็นการวนลูปแสดงข้อมูลสินค้า จาก database โดยข้อมูล รูปภาพ สินค้ามาแสดงผล และกำหนดให้แต่ละรูปภาพมี id และ title แตกต่างกันขึ้นอยู่กับข้อมูลใน database
ส่วนที่สองคือ tag
draggable_element เป็นการกำหนดให้ ภาพสินค้าแต่ละภาพสามารถถูกเลื่อนไปมาได้ จาก
product_#{product.id}
<div style="height:40px;padding-top:10px;">
<p id="indicator" style="display:none;margin-top:0px;">
<%= image_tag "indicator.gif" %> Updating cart...
</p>
</div>
อธิบาย code
เป็นการกำหนดพื้นที่การทำงานภายใต้ tag div ซึ่งภายในจะมีการใส่รูปภาพของตัว indicator ซึ่งจะแสดงผลพร้อมกับข้อความว่า " Updating cart..."เมื่อมีการเรียกให้ทำงาน
<h2>Your cart: </h2>
<div id="cart" class="cart" ">
<div id="items">
<%= render :partial => "cart" %>
</div>
<div style="clear:both;"></div>
</div>
อธิบาย code
กำหนดพื้นที่การทำงานในส่วนของตะกร้าสินค้า ด้วย tag div "items"
<div id="wastebin">
Drop items here to remove them from the cart.
</div>
อธิบาย code
กำหนดพื้นที่การทำงานในส่วนของถังขยะ หรือการยกเลิกสินค้า ด้วย tag div "wastebin"
<%= drop_receiving_element "cart",
:update => "items", :url => { :action => "add" },
:accept => "products", :hoverclass => "cart-active",
:loading => "Element.show('indicator')",
:complete => "Element.hide('indicator')" %>
อธิบาย code
บอกว่าถ้าส่วนของพื้นที่การทำงานใน tag div ชื่อ "cart" ได้รับ element หรือ มี element มาที่นี่ จะต้องทำงานดังนี้
- ทำงานที่ฟังก์ชัน add() (ใน controller) โดยผลลัพธ์ที่ได้จะออกมาแสดงผลบนพื้นที่ tag div ชื่อ "items"
- มีการทำงานไปที่ Element.show('indicator') แสดงภาพ indicator ออกมา
- เมื่อทำงานเสร็จ Element.hide('indicator') นำภาพ indicator ซ่อนไว้ไม่ไห้เห็น
<%= drop_receiving_element "wastebin",
:update => "items", :url => { :action => "remove" },
:accept => "cart-items", :hoverclass => "wastebin-active",
:before => "Element.hide(element)",
:loading => "Element.show('indicator')",
:complete => "Element.hide('indicator')" %>
อธิบาย code
บอกว่าถ้าส่วนของพื้นที่การทำงานใน tag div ชื่อ "wastebin"ได้รับ element หรือ มี element มาที่นี่ จะต้องทำงานดังนี้
- ทำงานที่ฟังก์ชัน remove() (ใน controller) โดยผลลัพธ์ที่ได้จะออกมาแสดงผลบนพื้นที่ tag div ชื่อ "items"
- มีการทำงานไปที่ Element.show('indicator') แสดงภาพ indicator ออกมา
- เมื่อทำงานเสร็จ Element.hide('indicator') นำภาพ indicator ซ่อนไว้ไม่ไห้เห็น
เขียน controller
def index
session[:cart] ||= {}
@products = Product.find(:all)
end
def add
product_id = params[:id].split("_")[1]
session[:cart][product_id] =
session[:cart].include?(product_id) ?
session[:cart][product_id]+1 : 1
render :partial => 'cart'
end
def remove
product_id = params[:id].split("_")[1]
if session[:cart][product_id] > 1
session[:cart][product_id] = session[:cart][product_id]-1
else
session[:cart].delete(product_id)
end
render :partial => 'cart'
end
เขียน _cart.rhtml partial
<% session[:cart].each do |product,quantity| %>
<div>
<% quantity.times do |i| %>
<% image_url = Product.find(product).image_url %>
<%= image_tag "#{image_url}",
:class => "cart-items",
:id => "item_#{product}_#{i}",
:style => "position:relative;" %>
<%= draggable_element "item_#{product}_#{i}", :revert => true %>
<% end %>
<span class="title">
<%= Product.find(product).title + " (#{quantity})" %>
</span>
</div>
<% end %>
<%= "Here's your shopping cart." if session[:cart].empty? %>
ผลลัพธ์
- แสดงการเขียน drag and drop อย่างง่ายๆ
- คลิ้กที่รูปภาพ จะเห็นว่ารูปภาพสามารถเลื้อนไปตามเมาส์
- นำรูปภาพไปวางในส่วนที่เรียกว่าตะกร้า โดย double click ในตำแหน่งที่จะวาง
- ยกเลิอกสินค้าที่มีในตะกร้า โดยการคลิ้กที่สินค้าในตะกร้า แล้วนำไปวางในตำแหน่งของถังขยะ
- ผลลัพธ์สุดท้ายของตะกร้าสินค้า
Reference