การสร้างหน้าแคตาล็อกสำหรับลูกค้า

A. แผนผังการสร้าง

createCatalog2.png

1. การสร้างหน้าจอ catalog

1.1 ขั้นตอนการสร้างหน้าจอ catalog

1. สร้าง controller store_controller.rb 
2. ดึงข้อมูลสินค้าจากฐานข้อมูล 
  2.1 แก้ไข controllers ชื่อ store_controller.rb
  2.2 แก้ไข models ชื่อ product.rb
3. นำสินค้ามาแสดงผลผ่านหน้าจอ
  3.1 แก้ไข views ชื่อ index.rhtml
4. ปรับปรุงหน้าจอ
  4.1 สร้าง layouts ชื่อ store.rhtml
  4.2 สร้าง Style sheet (CSS) 

1.2 สร้าง controller ตัวที่ 2 ชื่อ store controller

ruby script/generate controller store index

create_store_controller.jpg

เราได้สร้าง controller ขึ้นมาใหม่ (เรียกว่า StoreController) โดยภายในมี method index() เหตุผลในการสร้าง index() เพราะว่าเมื่อมีการเรียก URL มายัง Rails controller และไม่มีการระบุ action ต่อ ก็จะเรียกมาที่ index() อัตโนมัติ ดังนั้น หากเราเรียกไปที่ http://localhost:3000/store จะเห็นว่าไม่สามารถแสดงผลได้เนื่องจาก ไม่มีไฟล์ index.rhtml (ซึ่งต้องอยู่ในส่วนของ View)

ecom_code4.jpg

1.3 ดึงข้อมูลสินค้าจากฐานข้อมูล สร้าง Controller

ดังนั้น เราจะเริ่มการเขียนโปรแกรม เพื่อแสดงรายการสินค้าสำหรับขาย และแสดงให้ลูกค้าดู โดยมีรูปแบบดังนี้

  • ดึงรายการสินค้าที่มีอยู่ใน database (ecommerce_development)

เขียนการแสดงผลในไฟล์ /ecommerce/controllers/store_controller.rb ดังนี้

def index
  @products = Product.find_products_for_sale
end

after_filter :set_charset
  def set_charset
    content_type = @headers["Content-Type"] || 'text/html'
    if /^text\//.match(content_type)
      @headers["Content-Type"] = "#{content_type}; charset=utf-8" 
    end
  end

1.4 ดึงข้อมูลสินค้าจากฐานข้อมูล เขียน Model

ซึ่งยังไม่สามารถ run code ได้ในขณะนี้ เพราะเราต้องมี method find_products_for_sale() อยู่ใน Model product.rb ก่อน ดังนี้

/ecommerce/models/product.rb

def self.find_products_for_sale
      find(:all, :order => "title")
end
note : TIP

  • เมธอด find() จะนำค่า Product ทั้งหมดที่อยู่ในฐานข้อมูล มาไว้ในรููปแบบของ array
  • ในที่นี้เราใช้พารามิเตอร์ :order เพื่อบอกให้มีการเีรียงลำดับด้วย “title”
  • เราได้สร้างเมธอด find_products_for_sale โดยจะเห็นว่าได้ใส่ self เข้าไปที่หน้าชื่อ เพื่อบอกว่าให้มาทำงานที่ class นี้ไม่ใช่ inheritance class โดยเรียกใช้ดังนี้ Product.find_products_for_sale
note : TIPตอนนี้เรายังไม่ได้สร้างเว็บเพจ สำหรับนำข้อมูลออกมาแสดงผล ซึ่งต่อไปเราจะเขียนส่วนของ view template ซึ่งเป็นการแสดงผลทางหน้า web application

  • แก้ไขไฟล์ index.rhtml ที่ (app/view/store/index.rhtml)
  • ให้สังเกตว่า path ของ view นั้นจะสร้างจาก controller (store) และaction (index) ซึ่งจะต่อท้ายด้วย .rhtml แสดงว่าเป็น template
  • มี code ดังนี้
<div id="product-list">
  <h1>รายการสินค้า</h1>

  <table cellpadding="5" cellspacing="0">
  <% for product in @products %>
    <tr valign="top">

      <td>
        <img src="<%= product.image_url %>"/>
      </td>

      <td width="60%">
        <span><%= h(product.title) %></span><br />
        <%= h(product.description) %>
      </td>

      <td>
        <%= sprintf("%0.2f", product.price) %>
         <%= button_to "Add to Cart" , :action => :add_to_cart, :id => product %> 
      </td>
      
      
      
    </tr>
  <% end %>
  </table>
</div>
note : TIP

  • มีการเรียกใช้ h(product.title) , เมธอด h เพื่อระบุว่า ไม่สนใจ tag html (มองเป็น text string ทั่วๆไป)
  • การแสดงผลมีการเขียนด้วยรูปแบบภาษา html
  • แสดงผลโดยใช้การวน loop for

1.5 ปรับปรุงหน้าจอ web site (สร้าง layouts และ Style sheet )

สร้าง layouts ชื่อ store.rhtml

สังเกตว่า web site ส่วนใหญ่จะใช้ layout สำหรับการแสดงผลด้วยกัน ดังนั้นผู้ออกแบบควรมี layout template ซึ่งมันก็คือ มี header, footer, sidebar ของ website โดยส่วนต่างๆ เหล่านี้จะแยกออกจากเนื้อหาที่จะแสดงผล โดยผู้เขียน เขียน layout template เพียงแค่ครั้งเดียวหรือไฟล์เดียว แต่ทุกๆหน้าใน web site สามารถเรียกเอาไปใช้ได้ หากต้องการแก้ไขรูปแบบ web ก็สามารถแก้ไขที่ไฟล์เดียว

ดังนั้นเราต้องสร้างไฟล์ template ดังนี้

  • สร้างในไดเรกทอรีต่อไปนี้ app/view/layouts
  • สร้างไฟล์ template ชื่อเดียวกันกับ controller แต่ลงท้ายด้วย .rhtml
  • ดังนั้น เราต้องเขียนในไฟล์ชื่ิอ store.rhtml
  • สร้าง layouts ที่ /ecommerce/app/views/layouts/store.rhtml

layout01.jpg
layout02.jpg
layout023.jpg

<html>
    <head>
        <title>Pragprog Books Online Store</title>
         <%= stylesheet_link_tag "customer", :media => "all" %>
         <%= javascript_include_tag :defaults %>
    </head>
    <body id="store">
        <div id="banner">
          
            <%= @page_title || "Book Store" %>
        </div>
        <div id="columns">
            <div id="side">
            <div id="cart" >
                <!--%= render(:partial => "cart" , :object => @cart) %-->
            </div>
                <%= link_to("Home", :controller => "store", :action => "index") %>
                <br /><%= link_to("Admin Page", :controller => "admin", :action => "list") %>               
                <br /><a href="http://www..../faq">Questions</a>
                <br /><a href="http://www..../contact">Contact</a>
                <br />
            </div>
            <div id="main">
                <% if flash[:notice] -%>
                    <div id="notice"><%= flash[:notice] %></div>
                <% end %>
                <%= yield :layout %>
            </div>
        </div>
    </body>
</html>
  • จากด้านบน เราจะเขียน code แสดงผลที่ store.rhtml
  • และได้มีการใช้ stylesheet 1 ไฟล์ชื่อ customer.css มาช่วยปรับแต่ง
  • ซึ่ง scaffold.css เรามีแล้ว แต่เราต้องสร้าง customer.css เพิ่ม

สร้าง Stylesheet ชื่อ customer.rhtml

sty.jpg

body { background-color: #fff; color: #333; }

body, p, ol, ul, td {
  font-family: verdana, arial, helvetica, sans-serif;
  font-size:   13px;
  line-height: 18px;
}

/* main page (Customer)*/
#banner { 
  background: #C1DCFD;
  padding-top: 30px;
  padding-bottom: 30px;
  border-bottom: 2px solid;
  font: small-caps 40px/40px "Times New Roman", serif;
  color: #0000CC;
  text-align: center;
}

#banner img {
  float: left;
}

#main {
  margin-left: 17em; 
  padding-top: 4ex; /*ระยะห่างจาก banner ถึงข้อมูล*/
  padding-left: 2em;
  padding-bottom: 15em;
  background: white;
}

/*left bottom menubar */
#columns { 
  background: #0000CC;
  font: small-caps "Times New Roman", serif;
}
#side { /*menu sidebar*/
  background: #0000CC; /*สี bg ของเมนู*/
  float: left;
  padding-top: 1em;
  padding-left: 1em;
  padding-bottom: 1em;
  width: 15em;
}

#side a { /* Text Link On menu sidebar*/
  font: small-caps "Times New Roman", serif;
  color: #FFFFFF;
  font-size: 10px;
}

/* START:notice */
#notice {
  border: 2px solid red;
  padding: 1em;
  margin-bottom: 2em;
  background-color: #f0f0f0;
  font: bold smaller sans-serif;
}
/* END:notice */

h1 {
  font:  150% sans-serif;
  color: #226;
  border-bottom: 3px dotted #77d;
}

/* Styles for admin/list */

#product-list .list-title {
   color:        #244;
   font-weight:  bold;
   font-size:    larger;
}

#product-list .list-image {
  width:        60px;
  height:       70px;
}

#product-list .list-actions {
  font-size:    x-small;
  text-align:   right;
  padding-left: 1em;
}

/*bg color for list product*/
#product-list .list-line-even {
  background:   #e0f8f8;
}

#product-list .list-line-odd {
  background:   #FFFFFF;
}


/* And entry in the store catalog */

#store  .entry {
  border-bottom: 1px dotted #77d;
}

#store  .title {
  font-size: 120%;
  font-family: sans-serif;
}

#store .entry img {
  width: 75px;
  float: left;
}


#store .entry h3 {
 margin-bottom: 2px;
 color: #227;
}

#store .entry p {
 margin-top: 0px; 
 margin-bottom: 0.8em; 
}

#store .entry .price-line {
}

#store .entry .add-to-cart {
  position: relative;
}

#store .entry  .price {
  color: #44a;
  font-weight: bold;
  margin-right: 2em;
}

/* START:inline */
#store .entry form, #store .entry form div {
  display: inline;
}
/* END:inline */

/* Cart in the sidebar */
.cart-title {
  font: 100% bold;
  color: #FFFFFF;
}
.item-price, .total-line {
  text-align: right;   
}

.total-line .total-cell {
  font-weight: bold;
  border-top: 1px solid #FFFFFF;
}
#cart table {
  border-top:    1px dotted #595;
  border-bottom: 1px dotted #595;
  margin-bottom: 10px;
  color: #FFFFFF; /*สีตัวอักษรของสินค้าในตะกร้า*/
}
#cart td,tr{
  font-size:   10px; /*ขนาดตัวอักษรของสินค้าในตะกร้า*/
}
/* END:cart */

/* Styles for order form */

.depot-form fieldset {
  background: #efe;
}

.depot-form legend {
  color: #dfd;
  background: #141;
  font-family: sans-serif;
  padding: 0.2em 1em;
}

.depot-form label {
  width: 5em;
  float: left;
  text-align: right;
  margin-right: 0.5em;
  display: block;
}

.depot-form .submit {
  margin-left: 5.5em;
}

/* The error box */

.fieldWithErrors {
  padding: 2px;
  background-color: red;
  display: table;
}

#errorExplanation {
  width: 400px;
  border: 2px solid red;
  padding: 7px;
  padding-bottom: 12px;
  margin-bottom: 20px;
  background-color: #f0f0f0;
}

#errorExplanation h2 {
  text-align: left;
  font-weight: bold;
  padding: 5px 5px 5px 15px;
  font-size: 12px;
  margin: -7px;
  background-color: #c00;
  color: #fff;
}

#errorExplanation p {
  color: #333;
  margin-bottom: 0;
  padding: 5px;
}

#errorExplanation ul li {
  font-size: 12px;
  list-style: square;
}

  • storePage.png:
    storePage.png

Ref:http://wiki.nectec.or.th/setec/Knowledge/ECommerceWebsiteLab03