OSDN Git Service

管理画面の日付検索をjavascrptのカレンダーで 2-2-stable 2.2.0
authorymatsumoto <ymatsumoto@appirits.com>
Thu, 18 Apr 2013 01:04:15 +0000 (10:04 +0900)
committerymatsumoto <ymatsumoto@appirits.com>
Thu, 18 Apr 2013 07:28:53 +0000 (16:28 +0900)
選択できるような機能追加

69 files changed:
ChangeLog
app/controllers/admin/products_controller.rb
app/helpers/admin/base_helper.rb
app/views/admin/campaigns/_form.html.erb
app/views/admin/customers/_search.html.erb
app/views/admin/mail_magazines/_form.html.erb
app/views/admin/new_informations/_form.html.erb
app/views/admin/orders/_search.html.erb
app/views/admin/products/_form.html.erb
app/views/admin/products/_search.html.erb
app/views/admin/return_items/_form.html.erb
app/views/admin/return_items/_history_search.html.erb
app/views/admin/return_items/_search.html.erb
app/views/admin/stock_histories/_search.html.erb
app/views/admin/stock_in/_search.html.erb
app/views/admin/stock_modify/_search.html.erb
app/views/admin/totals/index.html.erb
app/views/layouts/admin/base.html.erb
public/images/calendar/error.gif [new file with mode: 0644]
public/images/calendar/icon_calendar.gif [new file with mode: 0644]
public/images/calendar/metal/base_dark.gif [new file with mode: 0644]
public/images/calendar/metal/base_date.gif [new file with mode: 0644]
public/images/calendar/metal/base_light.gif [new file with mode: 0644]
public/images/calendar/metal/button_left_off.gif [new file with mode: 0644]
public/images/calendar/metal/button_left_on.gif [new file with mode: 0644]
public/images/calendar/metal/button_right_off.gif [new file with mode: 0644]
public/images/calendar/metal/button_right_on.gif [new file with mode: 0644]
public/images/calendar/metal/concept.jpg [new file with mode: 0644]
public/images/calendar/metal/concept2.gif [new file with mode: 0644]
public/images/calendar/paper/base.gif [new file with mode: 0644]
public/images/calendar/paper/base_body.gif [new file with mode: 0644]
public/images/calendar/paper/base_date.gif [new file with mode: 0644]
public/images/calendar/paper/base_footer.gif [new file with mode: 0644]
public/images/calendar/paper/base_header.gif [new file with mode: 0644]
public/images/calendar/paper/base_line.gif [new file with mode: 0644]
public/images/calendar/paper/button_left_off.gif [new file with mode: 0644]
public/images/calendar/paper/button_left_on.gif [new file with mode: 0644]
public/images/calendar/paper/button_right_off.gif [new file with mode: 0644]
public/images/calendar/paper/button_right_on.gif [new file with mode: 0644]
public/images/calendar/paper/check.gif [new file with mode: 0644]
public/images/calendar/paper/concept.gif [new file with mode: 0644]
public/images/calendar/paper/concept2.gif [new file with mode: 0644]
public/images/calendar/paper/disabled.gif [new file with mode: 0644]
public/images/calendar/paper/line.gif [new file with mode: 0644]
public/images/calendar/simple/concept.gif [new file with mode: 0644]
public/images/calendar/simple/concept2.gif [new file with mode: 0644]
public/javascripts/calendar/lang_cs.js [new file with mode: 0644]
public/javascripts/calendar/lang_de.js [new file with mode: 0644]
public/javascripts/calendar/lang_en-GB.js [new file with mode: 0644]
public/javascripts/calendar/lang_es.js [new file with mode: 0644]
public/javascripts/calendar/lang_fr.js [new file with mode: 0644]
public/javascripts/calendar/lang_hu.js [new file with mode: 0644]
public/javascripts/calendar/lang_it.js [new file with mode: 0644]
public/javascripts/calendar/lang_ja.js [new file with mode: 0644]
public/javascripts/calendar/lang_pl.js [new file with mode: 0644]
public/javascripts/calendar/lang_pt-BR.js [new file with mode: 0644]
public/javascripts/calendar/lang_ro.js [new file with mode: 0644]
public/javascripts/calendar/lang_ru.js [new file with mode: 0644]
public/javascripts/calendar/lang_sk.js [new file with mode: 0644]
public/javascripts/calendar/lang_zh-cn.js [new file with mode: 0644]
public/javascripts/calendar/lang_zh-tw.js [new file with mode: 0644]
public/javascripts/calendar/protocalendar.js [new file with mode: 0644]
public/javascripts/calendar/protocalendar_min.js [new file with mode: 0644]
public/stylesheets/calendar/ext-simple.css [new file with mode: 0644]
public/stylesheets/calendar/jquery-calendar.css [new file with mode: 0644]
public/stylesheets/calendar/metal.css [new file with mode: 0644]
public/stylesheets/calendar/paper.css [new file with mode: 0644]
public/stylesheets/calendar/simple.css [new file with mode: 0644]
spec/helpers/admin/base_helper_spec.rb [new file with mode: 0644]

index 783c08e..f4c7cd9 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,11 @@
+2013-04-18  Matsumoto Yasuhito  <ymatsumoto _at_ appirits.com>
+
+       * 2.2.0 Release
+       * [管理画面] 日付検索をjavascriptのカレンダーでも選択できるようにしました
+       * [備考] 納品書・ビッキングリストのPDF作成機能も含まれます 
+
 2013-04-03  Matsumoto Yasuhito  <ymatsumoto _at_ appirits.com>
+
        * 2.1.7 Release
        * [管理画面] コントローラーのテストが通る用に作り直しました
 
index 29e112c..3f5d4da 100644 (file)
@@ -37,8 +37,8 @@ class Admin::ProductsController < Admin::BaseController
       @product = Product.new @old_product.attributes.reject{ |key, value| key.to_s == "id" }
     else
       @product = Product.new(params[:product])
-      @product.sale_end_at = Date.today + 3 * 365 #30年後
-      @product.public_end_at = Date.today + 3 * 365 #30年後
+      @product.sale_end_at = 3.years.since
+      @product.public_end_at = 3.years.since
     end
   end
 
index 10f3312..8642c41 100644 (file)
@@ -3,5 +3,32 @@ module Admin::BaseHelper
     date && date.strftime("%Y-%m-%d")
   end
 
+  def calendar_date_select(object,method,option= {},js_option= {})
+    
+    tag = date_select object,method,option
 
+    tag = <<-EOS
+      #{date_select object,method,option}
+      #{image_tag("../images/calendar/icon_calendar.gif",:id => method)}
+      <script type="text/javascript">
+      SelectCalendar.createOnLoaded({
+      yearSelect: '#{object}_#{method}_1i',
+      monthSelect: '#{object}_#{method}_2i',
+      daySelect: '#{object}_#{method}_3i'},
+     {triggers: ['#{method}'],
+      lang: 'ja',
+      showEffect: 'SlideDown', 
+      hideEffect: 'SlideUp',
+      startYear: #{option[:start_year]},
+      endYear: #{option[:end_year]}
+    EOS
+
+    js_option.each do |(key,value)|
+      tag << ',' + key.to_s + ": #{value}"
+    end
+
+    tag << '});</script>'
+
+    return tag
+  end
 end
index dcfe236..ce20ddd 100644 (file)
@@ -37,11 +37,21 @@ Event.observe(window, 'load', function() {
     </tr>
     <tr>
       <th>開始日時 <span class="pnt">※</span></th>
-      <td><%= confirm_tag :datetime_select, :campaign, :opened_at, :use_month_numbers => true %></td>
+      <td>
+        <%= confirm_tag :calendar_date_select,
+                      :campaign,:opened_at,
+                      {:start_year => 5.years.ago.year,
+                      :end_year => Date.today.year} %>
+      </td>
     </tr>
     <tr>
       <th>終了日時 <span class="pnt">※</span></th>
-      <td><%= confirm_tag :datetime_select, :campaign, :closed_at, :use_month_numbers => true %></td>
+      <td>
+        <%= confirm_tag :calendar_date_select,
+                      :campaign,:closed_at,
+                      {:start_year => 5.years.ago.year,
+                      :end_year => Date.today.year} %>
+      </td>
     </tr>
     <tr>
       <th>申込制限数</th>
index d74283a..9004b84 100644 (file)
   <tr>\r
     <th>誕生日</th>\r
     <td colspan="3" style="width:600px">\r
-      <%= f.birthday_select :birthday_from, :use_month_numbers => true, :include_blank=>true %>&nbsp〜&nbsp\r
-      <%= f.birthday_select :birthday_to, :use_month_numbers => true, :include_blank=>true %>\r
+      <%= calendar_date_select(:condition,"birthday_from",\r
+                          {:start_year => 100.years.ago.year,\r
+                          :end_year => Date.today.year,\r
+                          :use_month_numbers => true,\r
+                          :include_blank =>true})%>\r
+      &nbsp〜&nbsp\r
+      <%= calendar_date_select(:condition,"birthday_to",\r
+                          {:start_year => 100.years.ago.year,\r
+                          :end_year => Date.today.year,\r
+                          :use_month_numbers => true})%>\r
     </td>\r
   </tr>\r
   <tr>\r
   <tr>\r
     <th>登録・更新日</th>\r
     <td colspan="3" style="width:600px">\r
-      <%= f.date_select :updated_at_from, :use_month_numbers => true, :include_blank=>true %>&nbsp〜&nbsp\r
-      <%= f.date_select :updated_at_to, :use_month_numbers => true, :include_blank=>true %>\r
+      <%= calendar_date_select(:condition,"updated_at_from",\r
+                          {:start_year => 5.years.ago.year,\r
+                          :end_year => Date.today.year,\r
+                          :use_month_numbers => true,\r
+                          :include_blank =>true})%>\r
+      &nbsp〜&nbsp\r
+      <%= calendar_date_select(:condition,"updated_at_to",\r
+                          {:start_year => 5.years.ago.year,\r
+                          :end_year => Date.today.year,\r
+                          :use_month_numbers => true})%>\r
     </td>\r
   </tr>\r
   <tr>\r
     <th>最終購入日</th>\r
     <td colspan="3" style="width:600px">\r
-      <%= f.date_select :last_order_from, :use_month_numbers => true, :include_blank=>true %>&nbsp〜&nbsp\r
-      <%= f.date_select :last_order_to, :use_month_numbers => true, :include_blank=>true %>\r
+      <%= calendar_date_select(:condition,"last_order_from",\r
+                          {:start_year => 5.years.ago.year,\r
+                          :end_year => Date.today.year,\r
+                          :use_month_numbers => true,\r
+                          :include_blank =>true})%>\r
+      &nbsp〜&nbsp\r
+      <%= calendar_date_select(:condition,"last_order_to",\r
+                          {:start_year => 5.years.ago.year,\r
+                          :end_year => Date.today.year,\r
+                          :use_month_numbers => true})%>\r
     </td>\r
   </tr>\r
   <tr>\r
index c78664b..aed826b 100644 (file)
     <tr>
       <th>誕生日</th>
       <td colspan="3" style="width:600px">
-        <%= f.birthday_select :birthday_from, :use_month_numbers => true, :include_blank=>true %>&nbsp~&nbsp
-        <%= f.birthday_select :birthday_to, :use_month_numbers => true, :include_blank=>true %>
+        <%= calendar_date_select(:condition,"birthday_from",
+                          {:start_year => 100.years.ago.year,
+                          :end_year => Date.today.year,
+                          :use_month_numbers => true,
+                          :include_blank =>true})%>
+        &nbsp;~&nbsp;
+        <%= calendar_date_select(:condition,"birthday_to",
+                          {:start_year => 100.years.ago.year,
+                          :end_year => Date.today.year,
+                          :use_month_numbers => true})%>
       </td>
     </tr>
     <tr>
       <th>登録日</th>
       <td colspan="3" style="width:600px">
-        <%= f.date_select :updated_at_from, :use_month_numbers => true, :include_blank=>true %>&nbsp~&nbsp
-        <%= f.date_select :updated_at_to, :use_month_numbers => true, :include_blank=>true %>
+        <%= calendar_date_select(:condition,"updated_at_from",
+                          {:start_year => 5.years.ago.year,
+                          :end_year => Date.today.year,
+                          :use_month_numbers => true,
+                          :include_blank =>true})%>
+        &nbsp;~&nbsp;
+        <%= calendar_date_select(:condition,"updated_at_to",
+                          {:start_year => 5.years.ago.year,
+                          :end_year => Date.today.year,
+                          :use_month_numbers => true})%>
       </td>
     </tr>
     <tr>
       <th>最終購入日</th>
       <td colspan="3" style="width:600px">
-        <%= f.date_select :last_order_from, :use_month_numbers => true, :include_blank=>true %>&nbsp;~&nbsp;
-        <%= f.date_select :last_order_to, :use_month_numbers => true, :include_blank=>true %>
+        <%= calendar_date_select(:condition,"last_order_from",
+                          {:start_year => 5.years.ago.year,
+                          :end_year => Date.today.year,
+                          :use_month_numbers => true,
+                          :include_blank =>true})%>
+        &nbsp;~&nbsp;
+        <%= calendar_date_select(:condition,"last_order_to",
+                          {:start_year => 5.years.ago.year,
+                          :end_year => Date.today.year,
+                          :use_month_numbers => true})%>
       </td>
     </tr>
     <tr>
index f3063cc..f639b2c 100644 (file)
@@ -3,7 +3,13 @@
 <table class="data" cellspacing="1" cellpadding="0">
   <tr>
     <th>日付 <span class="pnt">※</span></th>
-    <td><%= confirm_tag :datetime_select, :new_information, :date, :use_month_numbers => true %></td>
+    <td>
+      <%= confirm_tag :calendar_date_select,
+                      :new_information,"date",
+                      {:start_year => 5.years.ago.year,
+                      :end_year => Date.today.year,
+                      :use_month_numbers => true} %>
+    </td>
   </tr>
   <tr>
     <th>タイトル <span class="pnt">※</span></th>
index 96c05a2..32d6660 100644 (file)
@@ -5,9 +5,17 @@
     <tr>
      <th>受注日</th>
        <td class="td1" colspan="3">
-        <%= f.date_select "created_at_from",
-            :use_month_numbers => true, :include_blank=>true %>
-         ~ <%= f.date_select "created_at_to", :use_month_numbers => true, :include_blank=>true %>
+       <%= calendar_date_select(:search,"created_at_from",
+                          {:start_year => 5.years.ago.year,
+                          :end_year => Date.today.year,
+                          :use_month_numbers => true,
+                          :default => false,
+                          :include_blank =>true}) %>
+         ~ 
+         <%= calendar_date_select(:search,"created_at_to",
+                          {:start_year => 5.years.ago.year,
+                          :end_year => Date.today.year,
+                          :use_month_numbers => true})%> 
      </td>
     </tr>
     <tr>
     <tr>
      <th>生年月日</th>
      <td class="td1" colspan="3">
-    <%= f.birthday_select "search_birth_from", :use_month_numbers => true, :include_blank=>true %>~ <%= f.birthday_select "search_birth_to", :use_month_numbers => true, :include_blank=>true %></td>
+      <%= calendar_date_select(:search,"search_birth_from",
+                          {:start_year => 100.years.ago.year,
+                          :end_year => Date.today.year,
+                          :use_month_numbers => true,
+                          :include_blank =>true})%>
+      〜
+      <%= calendar_date_select(:search,"search_birth_to",
+                          {:start_year => 100.years.ago.year,
+                          :end_year => Date.today.year,
+                          :use_month_numbers => true})%>
+     </td>
     </tr>
     <tr>
      <th>性別</th>
     <tr>
      <th>登録・更新日</th>
      <td class="td1" colspan="3">
-      <%= f.date_select "search_updated_at_from", :use_month_numbers => true, :include_blank=>true %>~ <%= f.date_select "search_updated_at_to", :use_month_numbers => true, :include_blank=>true %>
+      <%= calendar_date_select(:search,"search_updated_at_from",
+                          {:start_year => 5.years.ago.year,
+                          :end_year => Date.today.year,          
+                          :use_month_numbers => true,
+                          :include_blank =>true})%>
+     
+      〜
+      <%= calendar_date_select(:search,"search_updated_at_to",
+                          {:start_year => 5.years.ago.year,
+                          :end_year => Date.today.year,
+                          :use_month_numbers => true})%>
      </td>
     </tr>
     <tr>
     <tr>
      <th>発送日</th>
      <td class="td1" colspan="3">
-      <%= f.date_select "shipped_at_from", :use_month_numbers => true, :include_blank=>true %>~ <%= f.date_select "shipped_at_to", :use_month_numbers => true, :include_blank=>true %>
+      <%= calendar_date_select(:search,"shipped_at_from",
+                          {:start_year => 5.years.ago.year,
+                          :end_year => Date.today.year,
+                          :use_month_numbers => true,
+                          :include_blank =>true})%>
+      〜
+      <%= calendar_date_select(:search,"shipped_at_to",
+                          {:start_year => 5.years.ago.year,
+                          :end_year => Date.today.year,
+                          :use_month_numbers => true})%>
      </td>
     </tr>
     <tr>
index 259d084..6a899c6 100644 (file)
   <tr>
     <th>入荷予定日</th>
     <td>
-      <%= confirm_tag :date_select, :product, :arrival_expected_date, :use_month_numbers => true %>
+      <%= confirm_tag :calendar_date_select, 
+                      :product, 
+                      :arrival_expected_date,
+                     {:start_year => 5.years.ago.year,
+                      :end_year => 5.years.since.year,
+                      :use_month_numbers => true} %>
     </td>
   </tr>
   <tr>
     <th>販売期間</th>
     <td>
-      <%= confirm_tag :date_select, :product, :sale_start_at , :use_month_numbers => true%> ~
-      <%= confirm_tag :date_select, :product, :sale_end_at , :use_month_numbers => true %>
+      <%= confirm_tag :calendar_date_select,
+                      :product,
+                      :sale_start_at,
+                     {:start_year => 5.years.ago.year,
+                      :end_year => 5.years.since.year,
+                      :use_month_numbers => true} %>
+      ~
+      <%= confirm_tag :calendar_date_select,
+                      :product,
+                      :sale_end_at,
+                     {:start_year => 5.years.ago.year,
+                      :end_year => 5.years.since.year,
+                      :use_month_numbers => true} %>
     </td>
   </tr>
   <tr>
     <th>公開期間</th>
     <td>
-      <%= confirm_tag :date_select, :product, :public_start_at , :use_month_numbers => true%> ~
-      <%= confirm_tag :date_select, :product, :public_end_at , :use_month_numbers => true %>
+      <%= confirm_tag :calendar_date_select,
+                      :product,
+                      :public_start_at,
+                     {:start_year => 5.years.ago.year,
+                      :end_year => 5.years.since.year,
+                      :use_month_numbers => true} %>
+      ~
+      <%= confirm_tag :calendar_date_select,
+                      :product,
+                      :public_end_at,
+                     {:start_year => 5.years.ago.year,
+                      :end_year => 5.years.since.year,
+                      :use_month_numbers => true} %>
     </td>
   </tr>
   <tr>
index 9da2198..c467184 100644 (file)
       <tr>
         <th>登録日</th>
         <td>
-          <%= f.date_select :created_at_from ,:use_month_numbers => true, :include_blank=>true %>~
-          <%= f.date_select :created_at_to, :use_month_numbers => true, :include_blank=>true %>
-        </td>
+          <%=calendar_date_select(:search,"created_at_from",
+                          {:start_year => 5.years.ago.year,
+                          :end_year => Date.today.year,
+                          :use_month_numbers => true,
+                          :include_blank =>true}) %>
+          ~
+          <%=calendar_date_select(:search,"created_at_to",
+                          {:start_year => 5.years.ago.year,
+                          :end_year => Date.today.year,
+                          :use_month_numbers => true}) %>
+       </td>
       </tr>
       <tr>
         <th>更新日</th>
         <td>
-          <%= f.date_select :updated_at_from ,:use_month_numbers => true, :include_blank=>true %>~
-          <%= f.date_select :updated_at_to, :use_month_numbers => true, :include_blank=>true %>
+          <%=calendar_date_select(:search,"updated_at_from",
+                          {:start_year => 5.years.ago.year,
+                          :end_year => Date.today.year,
+                          :use_month_numbers => true,
+                          :include_blank =>true}) %>
+          ~
+          <%=calendar_date_select(:search,"updated_at_to",
+                          {:start_year => 5.years.ago.year,
+                          :end_year => Date.today.year,
+                          :use_month_numbers => true}) %>
         </td>
       </tr>
       <tr>
         <th>販売開始日</th>
         <td>
-          <%= f.date_select :sale_start_at_start ,:use_month_numbers => true, :include_blank => true %>~
-          <%= f.date_select :sale_start_at_end, :use_month_numbers => true, :include_blank => true  %>
+          <%=calendar_date_select(:search,"sale_start_at_start",
+                          {:start_year => 5.years.ago.year,
+                          :end_year => Date.today.year,
+                          :use_month_numbers => true,
+                          :include_blank =>true}) %>
+          ~
+          <%=calendar_date_select(:search,"sale_start_at_end",
+                          {:start_year => 5.years.ago.year,
+                          :end_year => Date.today.year,
+                          :use_month_numbers => true}) %>
         </td>
       </tr>
       <tr>
index 6190047..ee2a902 100644 (file)
@@ -9,7 +9,11 @@
   <tr>
     <th>返品日時</th>
     <td>
-      <%= f.date_select :returned_at ,:use_month_numbers => true, :include_blank=>true %>
+      <%= calendar_date_select(:return_item,"returned_at",
+                          {:start_year => 5.years.ago.year,
+                          :end_year => Date.today.year,
+                          :use_month_numbers => true,
+                          :include_blank =>true})%>
     </td>
   </tr>
   <tr>
index a75a997..aa455c3 100644 (file)
   <tr>
     <th>返品登録日</th>
     <td>
-      <%= f.date_select :returned_at_from, :use_month_numbers => true, :include_blank => true %>〜
-      <%= f.date_select :returned_at_to, :use_month_numbers => true, :include_blank => true %>
+      <%= calendar_date_select(:condition,"returned_at_from",
+                          {:start_year => 5.years.ago.year,
+                          :end_year => Date.today.year,
+                          :use_month_numbers => true,
+                          :include_blank =>true})%>
+      〜
+      <%= calendar_date_select(:condition,"returned_at_to",
+                          {:start_year => 5.years.ago.year,
+                          :end_year => Date.today.year,
+                          :use_month_numbers => true})%>
     </td>
   </tr>
   <tr>
index 5caa341..fe03709 100644 (file)
   <tr>
     <th>登録日・更新日</th>
     <td>
-      <%= f.date_select :updated_at_from ,:use_month_numbers => true, :include_blank=>true %>~
-      <%= f.date_select :updated_at_to, :use_month_numbers => true, :include_blank=>true %>
+      <%= calendar_date_select(:condition,"updated_at_from",
+                          {:start_year => 5.years.ago.year,
+                          :end_year => Date.today.year,
+                          :use_month_numbers => true,
+                          :include_blank =>true})%>
+      〜
+      <%= calendar_date_select(:condition,"updated_at_to",
+                          {:start_year => 5.years.ago.year,
+                          :end_year => Date.today.year,
+                          :use_month_numbers => true})%>
     </td>
   </tr>
   <tr>
index 43828a7..2d96f10 100644 (file)
       <tr>
         <th>在庫移動日</th>
         <td>
-          <%= f.date_select :moved_at_from ,:use_month_numbers => true, :include_blank=>true %>~
-          <%= f.date_select :moved_at_to, :use_month_numbers => true, :include_blank=>true %>
+          <%= calendar_date_select(:condition,"moved_at_from",
+                          {:start_year => 5.years.ago.year,
+                          :end_year => Date.today.year,
+                          :use_month_numbers => true,
+                          :include_blank =>true})%>
+          〜
+          <%= calendar_date_select(:condition,"moved_at_to",
+                          {:start_year => 5.years.ago.year,
+                          :end_year => Date.today.year,
+                          :use_month_numbers => true})%>
         </td>
       </tr>
       <tr>
index 25c1d8a..93ff62d 100644 (file)
       <tr>
         <th>登録日・更新日</th>
         <td>
-          <%= f.date_select :updated_at_from ,:use_month_numbers => true, :include_blank=>true %>~
-          <%= f.date_select :updated_at_to, :use_month_numbers => true, :include_blank=>true %>
+          <%= calendar_date_select(:condition,:updated_at_from,
+                          {:start_year => 5.years.ago.year,
+                          :end_year => Date.today.year,
+                          :use_month_numbers => true,
+                          :include_blank =>true})%>
+          〜
+          <%= calendar_date_select(:condition,:updated_at_to,
+                          {:start_year => 5.years.ago.year,
+                          :end_year => Date.today.year,
+                          :use_month_numbers => true})%>
         </td>
       </tr>
       <tr>
index 25c1d8a..93ff62d 100644 (file)
       <tr>
         <th>登録日・更新日</th>
         <td>
-          <%= f.date_select :updated_at_from ,:use_month_numbers => true, :include_blank=>true %>~
-          <%= f.date_select :updated_at_to, :use_month_numbers => true, :include_blank=>true %>
+          <%= calendar_date_select(:condition,:updated_at_from,
+                          {:start_year => 5.years.ago.year,
+                          :end_year => Date.today.year,
+                          :use_month_numbers => true,
+                          :include_blank =>true})%>
+          〜
+          <%= calendar_date_select(:condition,:updated_at_to,
+                          {:start_year => 5.years.ago.year,
+                          :end_year => Date.today.year,
+                          :use_month_numbers => true})%>
         </td>
       </tr>
       <tr>
index 9c0d174..37f2a83 100644 (file)
       <tr>
         <th>販売開始期間</th>
           <td>
-            <%= date_select 'search', 'sale_start_from', :use_month_numbers => true, :include_blank => true %>~
-            <%= date_select 'search', 'sale_start_to', :use_month_numbers => true, :include_blank => true %>
+            <%= calendar_date_select(:search,:sale_start_from,
+                     {:start_year => 5.years.ago.year,
+                      :end_year => 5.years.since.year,
+                      :use_month_numbers => true,
+                      :include_blank =>true}) %>
+            〜
+            <%= calendar_date_select(:search,:sale_start_to,
+                     {:start_year => 5.years.ago.year,
+                      :end_year => 5.years.since.year,
+                      :use_month_numbers => true,
+                      :include_blank =>true}) %>
           </td>
       </tr>
     </table>
     <tr>
       <th style="width:10%">期間集計</th>
         <td style="width:90%">
-          <%= date_select 'search', 'date_from', :use_month_numbers => true %>~
-          <%= date_select 'search', 'date_to', :use_month_numbers => true %>&nbsp;
+          <%= calendar_date_select(:search,:date_from,
+                     {:start_year => 5.years.ago.year,
+                      :end_year => 5.years.since.year,
+                      :use_month_numbers => true}) %>
+          ~
+          <%= calendar_date_select(:search,:date_to,
+                     {:start_year => 5.years.ago.year,
+                      :end_year => 5.years.since.year,
+                      :use_month_numbers => true}) %>
           <%= submit_tag '期間で集計する', :name=>'search[by_date]', :class => "btn_s" %>
         </td>
     </tr>
index 2d4a8e5..24de4ce 100644 (file)
@@ -9,7 +9,10 @@
     <%= javascript_include_tag js_url(:action => "treemenu") %>
     <%= javascript_include_tag "rollover" %>
     <%= javascript_include_tag js_url(:action => "application") %>
+    <%= javascript_include_tag 'calendar/protocalendar' %>
+    <%= javascript_include_tag 'calendar/lang_ja' %>
     <%= stylesheet_link_tag "admin" %>
+    <%= stylesheet_link_tag 'calendar/simple' %>
     <%= yield :head %>
   </head>
   <body>
diff --git a/public/images/calendar/error.gif b/public/images/calendar/error.gif
new file mode 100644 (file)
index 0000000..c93047d
Binary files /dev/null and b/public/images/calendar/error.gif differ
diff --git a/public/images/calendar/icon_calendar.gif b/public/images/calendar/icon_calendar.gif
new file mode 100644 (file)
index 0000000..cf3375e
Binary files /dev/null and b/public/images/calendar/icon_calendar.gif differ
diff --git a/public/images/calendar/metal/base_dark.gif b/public/images/calendar/metal/base_dark.gif
new file mode 100644 (file)
index 0000000..215ad18
Binary files /dev/null and b/public/images/calendar/metal/base_dark.gif differ
diff --git a/public/images/calendar/metal/base_date.gif b/public/images/calendar/metal/base_date.gif
new file mode 100644 (file)
index 0000000..b394a07
Binary files /dev/null and b/public/images/calendar/metal/base_date.gif differ
diff --git a/public/images/calendar/metal/base_light.gif b/public/images/calendar/metal/base_light.gif
new file mode 100644 (file)
index 0000000..243b321
Binary files /dev/null and b/public/images/calendar/metal/base_light.gif differ
diff --git a/public/images/calendar/metal/button_left_off.gif b/public/images/calendar/metal/button_left_off.gif
new file mode 100644 (file)
index 0000000..0fd0e55
Binary files /dev/null and b/public/images/calendar/metal/button_left_off.gif differ
diff --git a/public/images/calendar/metal/button_left_on.gif b/public/images/calendar/metal/button_left_on.gif
new file mode 100644 (file)
index 0000000..88a9357
Binary files /dev/null and b/public/images/calendar/metal/button_left_on.gif differ
diff --git a/public/images/calendar/metal/button_right_off.gif b/public/images/calendar/metal/button_right_off.gif
new file mode 100644 (file)
index 0000000..1f6c810
Binary files /dev/null and b/public/images/calendar/metal/button_right_off.gif differ
diff --git a/public/images/calendar/metal/button_right_on.gif b/public/images/calendar/metal/button_right_on.gif
new file mode 100644 (file)
index 0000000..906dcd6
Binary files /dev/null and b/public/images/calendar/metal/button_right_on.gif differ
diff --git a/public/images/calendar/metal/concept.jpg b/public/images/calendar/metal/concept.jpg
new file mode 100644 (file)
index 0000000..d46c1b3
Binary files /dev/null and b/public/images/calendar/metal/concept.jpg differ
diff --git a/public/images/calendar/metal/concept2.gif b/public/images/calendar/metal/concept2.gif
new file mode 100644 (file)
index 0000000..c9aa110
Binary files /dev/null and b/public/images/calendar/metal/concept2.gif differ
diff --git a/public/images/calendar/paper/base.gif b/public/images/calendar/paper/base.gif
new file mode 100644 (file)
index 0000000..a5be3af
Binary files /dev/null and b/public/images/calendar/paper/base.gif differ
diff --git a/public/images/calendar/paper/base_body.gif b/public/images/calendar/paper/base_body.gif
new file mode 100644 (file)
index 0000000..9633419
Binary files /dev/null and b/public/images/calendar/paper/base_body.gif differ
diff --git a/public/images/calendar/paper/base_date.gif b/public/images/calendar/paper/base_date.gif
new file mode 100644 (file)
index 0000000..76a1cf3
Binary files /dev/null and b/public/images/calendar/paper/base_date.gif differ
diff --git a/public/images/calendar/paper/base_footer.gif b/public/images/calendar/paper/base_footer.gif
new file mode 100644 (file)
index 0000000..3d42800
Binary files /dev/null and b/public/images/calendar/paper/base_footer.gif differ
diff --git a/public/images/calendar/paper/base_header.gif b/public/images/calendar/paper/base_header.gif
new file mode 100644 (file)
index 0000000..c37c831
Binary files /dev/null and b/public/images/calendar/paper/base_header.gif differ
diff --git a/public/images/calendar/paper/base_line.gif b/public/images/calendar/paper/base_line.gif
new file mode 100644 (file)
index 0000000..676611c
Binary files /dev/null and b/public/images/calendar/paper/base_line.gif differ
diff --git a/public/images/calendar/paper/button_left_off.gif b/public/images/calendar/paper/button_left_off.gif
new file mode 100644 (file)
index 0000000..6775f86
Binary files /dev/null and b/public/images/calendar/paper/button_left_off.gif differ
diff --git a/public/images/calendar/paper/button_left_on.gif b/public/images/calendar/paper/button_left_on.gif
new file mode 100644 (file)
index 0000000..94259a5
Binary files /dev/null and b/public/images/calendar/paper/button_left_on.gif differ
diff --git a/public/images/calendar/paper/button_right_off.gif b/public/images/calendar/paper/button_right_off.gif
new file mode 100644 (file)
index 0000000..76e908f
Binary files /dev/null and b/public/images/calendar/paper/button_right_off.gif differ
diff --git a/public/images/calendar/paper/button_right_on.gif b/public/images/calendar/paper/button_right_on.gif
new file mode 100644 (file)
index 0000000..646515d
Binary files /dev/null and b/public/images/calendar/paper/button_right_on.gif differ
diff --git a/public/images/calendar/paper/check.gif b/public/images/calendar/paper/check.gif
new file mode 100644 (file)
index 0000000..c52ab8e
Binary files /dev/null and b/public/images/calendar/paper/check.gif differ
diff --git a/public/images/calendar/paper/concept.gif b/public/images/calendar/paper/concept.gif
new file mode 100644 (file)
index 0000000..82f83c5
Binary files /dev/null and b/public/images/calendar/paper/concept.gif differ
diff --git a/public/images/calendar/paper/concept2.gif b/public/images/calendar/paper/concept2.gif
new file mode 100644 (file)
index 0000000..0586e3a
Binary files /dev/null and b/public/images/calendar/paper/concept2.gif differ
diff --git a/public/images/calendar/paper/disabled.gif b/public/images/calendar/paper/disabled.gif
new file mode 100644 (file)
index 0000000..db0d464
Binary files /dev/null and b/public/images/calendar/paper/disabled.gif differ
diff --git a/public/images/calendar/paper/line.gif b/public/images/calendar/paper/line.gif
new file mode 100644 (file)
index 0000000..22412a5
Binary files /dev/null and b/public/images/calendar/paper/line.gif differ
diff --git a/public/images/calendar/simple/concept.gif b/public/images/calendar/simple/concept.gif
new file mode 100644 (file)
index 0000000..ff4e4db
Binary files /dev/null and b/public/images/calendar/simple/concept.gif differ
diff --git a/public/images/calendar/simple/concept2.gif b/public/images/calendar/simple/concept2.gif
new file mode 100644 (file)
index 0000000..9e9a563
Binary files /dev/null and b/public/images/calendar/simple/concept2.gif differ
diff --git a/public/javascripts/calendar/lang_cs.js b/public/javascripts/calendar/lang_cs.js
new file mode 100644 (file)
index 0000000..f0e2fa9
--- /dev/null
@@ -0,0 +1,15 @@
+(function() {\r
+   ProtoCalendar.LangFile['cs'] = {\r
+     HOUR_MINUTE_ERROR: 'The time is not valid.',\r
+     NO_DATE_ERROR: 'No day has been selected.',\r
+     OK_LABEL: 'OK',\r
+     DEFAULT_FORMAT: 'mm/dd/yyyy',\r
+     LABEL_FORMAT: 'dddi mmm dd yyyy',\r
+     MONTH_ABBRS: ['Leden','Únor','Bøezen','Duben','Kvìten','Èerven','Èervenec','Srpen','Záøí','Øíjen','Listopad','Prosinec'],\r
+     WEEKDAY_ABBRS: ['Ne','Po','Út','St','Èt','Pá','So'],\r
+     WEEKDAY_NAMES: ['Ne','Po','Út','St','Èt','Pá','So'],\r
+     YEAR_LABEL: ' ',\r
+     MONTH_LABEL: ' ',\r
+     YEAR_AND_MONTH: false\r
+   };\r
+ })();\r
diff --git a/public/javascripts/calendar/lang_de.js b/public/javascripts/calendar/lang_de.js
new file mode 100644 (file)
index 0000000..ad0c448
--- /dev/null
@@ -0,0 +1,15 @@
+(function() {\r
+   ProtoCalendar.LangFile['de'] = {\r
+     HOUR_MINUTE_ERROR: 'The time is not valid.',\r
+     NO_DATE_ERROR: 'No day has been selected.',\r
+     OK_LABEL: 'OK',\r
+     DEFAULT_FORMAT: 'mm/dd/yyyy',\r
+     LABEL_FORMAT: 'dddi mmm dd yyyy',\r
+     MONTH_ABBRS: ['Januar','Februar','März','April','Mai','Juni','Juli','August','September','Oktober','November','Dezember'],\r
+     WEEKDAY_ABBRS: ['So','Mo','Di','Mi','Do','Fr','Sa'],\r
+     WEEKDAY_NAMES: ['So','Mo','Di','Mi','Do','Fr','Sa'],\r
+     YEAR_LABEL: ' ',\r
+     MONTH_LABEL: ' ',\r
+     YEAR_AND_MONTH: false\r
+   };\r
+ })();\r
diff --git a/public/javascripts/calendar/lang_en-GB.js b/public/javascripts/calendar/lang_en-GB.js
new file mode 100644 (file)
index 0000000..3a4d74c
--- /dev/null
@@ -0,0 +1,3 @@
+(function() {\r
+   ProtoCalendar.LangFile['en-GB'] = Object.extend(ProtoCalendar.LangFile['en'], { });\r
+ })();\r
diff --git a/public/javascripts/calendar/lang_es.js b/public/javascripts/calendar/lang_es.js
new file mode 100644 (file)
index 0000000..fbb296a
--- /dev/null
@@ -0,0 +1,15 @@
+(function() {\r
+   ProtoCalendar.LangFile['es'] = {\r
+     HOUR_MINUTE_ERROR: 'The time is not valid.',\r
+     NO_DATE_ERROR: 'No day has been selected.',\r
+     OK_LABEL: 'OK',\r
+     DEFAULT_FORMAT: 'mm/dd/yyyy',\r
+     LABEL_FORMAT: 'dddi mmm dd yyyy',\r
+     MONTH_ABBRS: ['Enero','Febrero','Marzo','Abril','Mayo','Junio','Julio','Agosto','Septiembre','Octubre','Noviembre','Diciembre'],\r
+     WEEKDAY_ABBRS: ['Do','Lu','Ma','Mi','Ju','Vi','S&aacute;'],\r
+     WEEKDAY_NAMES: ['Do','Lu','Ma','Mi','Ju','Vi','S&aacute;'],\r
+     YEAR_LABEL: ' ',\r
+     MONTH_LABEL: ' ',\r
+     YEAR_AND_MONTH: false\r
+   };\r
+ })();\r
diff --git a/public/javascripts/calendar/lang_fr.js b/public/javascripts/calendar/lang_fr.js
new file mode 100644 (file)
index 0000000..56f7029
--- /dev/null
@@ -0,0 +1,15 @@
+(function() {\r
+   ProtoCalendar.LangFile['fr'] = {\r
+     HOUR_MINUTE_ERROR: 'The time is not valid.',\r
+     NO_DATE_ERROR: 'No day has been selected.',\r
+     OK_LABEL: 'OK',\r
+     DEFAULT_FORMAT: 'mm/dd/yyyy',\r
+     LABEL_FORMAT: 'dddi mmm dd yyyy',\r
+     MONTH_ABBRS: ['Janvier','Février','Mars','Avril','Mai','Juin','Juillet','Août','Septembre','Octobre','Novembre','Décembre'],\r
+     WEEKDAY_ABBRS: ['Di','Lu','Ma','Me','Je','Ve','Sa'],\r
+     WEEKDAY_NAMES: ['Di','Lu','Ma','Me','Je','Ve','Sa'],\r
+     YEAR_LABEL: ' ',\r
+     MONTH_LABEL: ' ',\r
+     YEAR_AND_MONTH: false\r
+   };\r
+ })();\r
diff --git a/public/javascripts/calendar/lang_hu.js b/public/javascripts/calendar/lang_hu.js
new file mode 100644 (file)
index 0000000..d714225
--- /dev/null
@@ -0,0 +1,15 @@
+(function() {\r
+   ProtoCalendar.LangFile['hu'] = {\r
+     HOUR_MINUTE_ERROR: 'The time is not valid.',\r
+     NO_DATE_ERROR: 'No day has been selected.',\r
+     OK_LABEL: 'OK',\r
+     DEFAULT_FORMAT: 'mm/dd/yyyy',\r
+     LABEL_FORMAT: 'dddi mmm dd yyyy',\r
+     MONTH_ABBRS: ['Január', 'Február', 'Március', 'Április', 'Május', 'Június','Július', 'Augusztus', 'Szeptember', 'Október', 'November', 'December'],\r
+     WEEKDAY_ABBRS: ['V', 'H', 'K', 'Sze', 'Cs', 'P', 'Szo'],\r
+     WEEKDAY_NAMES: ['V', 'H', 'K', 'Sze', 'Cs', 'P', 'Szo'],\r
+     YEAR_LABEL: ' ',\r
+     MONTH_LABEL: ' ',\r
+     YEAR_AND_MONTH: false\r
+   };\r
+ })();\r
diff --git a/public/javascripts/calendar/lang_it.js b/public/javascripts/calendar/lang_it.js
new file mode 100644 (file)
index 0000000..3a9685f
--- /dev/null
@@ -0,0 +1,15 @@
+(function() {\r
+   ProtoCalendar.LangFile['it'] = {\r
+     HOUR_MINUTE_ERROR: 'The time is not valid.',\r
+     NO_DATE_ERROR: 'No day has been selected.',\r
+     OK_LABEL: 'OK',\r
+     DEFAULT_FORMAT: 'mm/dd/yyyy',\r
+     LABEL_FORMAT: 'dddi mmm dd yyyy',\r
+     MONTH_ABBRS: ['Gennaio','Febbraio','Marzo','Aprile','Maggio','Giugno','Luglio','Agosto','Settembre','Ottobre','Novembre','Dicembre'],\r
+     WEEKDAY_ABBRS: ['Do','Lu','Ma','Me','Gio','Ve','Sa'],\r
+     WEEKDAY_NAMES: ['Do','Lu','Ma','Me','Gio','Ve','Sa'],\r
+     YEAR_LABEL: ' ',\r
+     MONTH_LABEL: ' ',\r
+     YEAR_AND_MONTH: false\r
+   };\r
+ })();\r
diff --git a/public/javascripts/calendar/lang_ja.js b/public/javascripts/calendar/lang_ja.js
new file mode 100644 (file)
index 0000000..bb4da98
--- /dev/null
@@ -0,0 +1,132 @@
+(function() {\r
+   ProtoCalendar.LangFile['ja'] = {\r
+     HOUR_MINUTE_ERROR: '時間が無効です。',\r
+     NO_DATE_ERROR: '日を選択して下さい。',\r
+     OK_LABEL: 'OK',\r
+     DEFAULT_FORMAT: 'yyyy/mm/dd',\r
+     LABEL_FORMAT: 'yyyy年mm月dd日 ddddi',\r
+     MONTH_ABBRS: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],\r
+     WEEKDAY_ABBRS: ['日','月','火','水','木','金','土'],\r
+     WEEKDAY_NAMES: ['日曜日','月曜日','火曜日','水曜日','木曜日','金曜日','土曜日'],\r
+     YEAR_LABEL: '年',\r
+     MONTH_LABEL: '月',\r
+     YEAR_AND_MONTH: true,\r
+     today: '今日',\r
+     tomorrow: '明日',\r
+     yesterday: '昨日',\r
+\r
+     parseDate: function(inputValue) {\r
+       if (inputValue == '一昨日') {\r
+         var d = new Date();\r
+         d.setDate(d.getDate() - 2);\r
+         return d;\r
+       } else if (inputValue == '明後日') {\r
+         var d = new Date();\r
+         d.setDate(d.getDate() + 2);\r
+         return d;\r
+       }\r
+     },\r
+\r
+     getHolidays:   function(calendar) {\r
+       var year = calendar.getYear();\r
+       var month = calendar.getMonth();\r
+       var lastDay = calendar.getNumDayOfMonth();\r
+\r
+       var temp;\r
+       if (year < 2000) {\r
+         temp = 2213;\r
+       } else {\r
+         temp = 2089;\r
+       }\r
+       var springDay = Math.floor((31 * year + temp)/128) - Math.floor(year/4) + Math.floor(year/100);\r
+\r
+       if (year < 2000) {\r
+         temp = 2525;\r
+       } else {\r
+         temp = 2395;\r
+       }\r
+       var autumnDay =  Math.floor((31 * year + temp)/128) - Math.floor(year/4) + Math.floor(year/100);\r
+\r
+       var holidays = [];\r
+       var mondayIndex = 0;\r
+       for(var day = 1; day <= lastDay; day++) {\r
+         var dayOfWeek = new Date(year, month, day).getDay();\r
+         holidays[day] = 0;\r
+\r
+         if (dayOfWeek == ProtoCalendar.MONDAY) {\r
+           ++mondayIndex;\r
+         }\r
+        \r
+         /*祝日は削除するためにコメントアウト Edit by ymatsumoto\r
+         if (day == 1 && month == ProtoCalendar.JAN && 1949 <= year) {\r
+           holidays[day] = '元旦';\r
+         } else if (day == 15 && month == ProtoCalendar.JAN && 1949 <= year && year < 2000) {\r
+           holidays[day] = '成人の日';\r
+         } else if (dayOfWeek == ProtoCalendar.MONDAY && mondayIndex == 2 && month == 0 && 2000 <= year) {\r
+           holidays[day] = '成人の日';\r
+         } else if (day == 11 && month == ProtoCalendar.FEB && 1967 <= year) {\r
+           holidays[day] = '建国記念の日';\r
+         } else if (day == springDay && month == ProtoCalendar.MAR) {\r
+           holidays[day] = '春分の日';\r
+         } else if (day == 29 && month == ProtoCalendar.APR && 1989 <= year && year < 2007) {\r
+           holidays[day] = 'みどりの日';\r
+         } else if (day == 29 && month == ProtoCalendar.APR && 1949 <= year && year < 1989) {\r
+           holidays[day] = '天皇誕生日';\r
+         } else if (day == 4 && month == ProtoCalendar.MAY && 2007 <= year) {\r
+           holidays[day] = 'みどりの日';\r
+         } else if (day == 29 && month == ProtoCalendar.APR && 2007 <= year){\r
+           holidays[day] = '昭和の日';\r
+         } else if (day == 3 && month == ProtoCalendar.MAY && 1949 <= year) {\r
+           holidays[day] = '憲法記念日';\r
+         } else if (day == 4 && month == ProtoCalendar.MAY && 1986 <= year && year < 2007) {\r
+           holidays[day] = '国民の休日';\r
+         } else if (day == 5 && month == ProtoCalendar.MAY && 1949 <= year) {\r
+           holidays[day] = 'こどもの日';\r
+         } else if (day == 20 && month == ProtoCalendar.JULY && 1996 <= year && year < 2003) {\r
+           holidays[day] = '海の日';\r
+         } else if (mondayIndex == 3 && month == ProtoCalendar.JULY && dayOfWeek == ProtoCalendar.MONDAY && 2003 <= year) {\r
+           holidays[day] = '海の日';\r
+         } else if (day == 15 && month == ProtoCalendar.SEPT && 1966 <= year && year < 2003) {\r
+           holidays[day] = '敬老の日';\r
+         } else if (mondayIndex == 3 && month == ProtoCalendar.SEPT && dayOfWeek == ProtoCalendar.MONDAY && 2003 <= year) {\r
+           holidays[day] = '敬老の日';\r
+         } else if (autumnDay == day && month == ProtoCalendar.SEPT) {\r
+           holidays[day] = '秋分の日';\r
+         } else if (day == 10 && month == ProtoCalendar.OCT && 1966 <= year && year < 2001) {\r
+           holidays[day] = '体育の日';\r
+         } else if (mondayIndex == 2 && month == ProtoCalendar.OCT && dayOfWeek == ProtoCalendar.MONDAY && 2000 <= year) {\r
+           holidays[day] = '体育の日';\r
+         } else if (day == 3 && month == ProtoCalendar.NOV && 1948 <= year) {\r
+           holidays[day] = '文化の日';\r
+         } else if (day == 23 && month == ProtoCalendar.NOV && 1948 <= year) {\r
+           holidays[day] = '勤労感謝の日';\r
+         } else if (day == 23 && month == ProtoCalendar.DEC && 1989 <= year) {\r
+           holidays[day] = '天皇誕生日';\r
+         }\r
+       }\r
+       var hasHoliday = year > 1973 || year == 1973 && month > ProtoCalendar.APR;\r
+       var hasKokuminHoliday = year >= 1988;\r
+       var oldRule = hasHoliday && year < 2006;\r
+       var curRule = hasHoliday && year >= 2006;\r
+       for(var day = 1; day <= lastDay; day++) {\r
+         var dayOfWeek = new Date(year, month, day).getDay();\r
+         if (hasHoliday) {\r
+           if (dayOfWeek == ProtoCalendar.SUNDAY && holidays[day]) {\r
+             var next = day + 1;\r
+             if (oldRule) {\r
+                if (holidays[next]) continue;\r
+             } else if (curRule) {\r
+               for (; holidays[next]; next += 1) { }\r
+             }\r
+             holidays[next] = '振替休日';\r
+           \r
+           } else if (hasKokuminHoliday && holidays[day - 1] && holidays[day + 1] && !holidays[day]) {\r
+             holidays[day] = '国民の休日';\r
+           }\r
+          }*/\r
+       }\r
+       calendar.holidays = holidays;\r
+     }\r
+   };\r
+\r
+ })();\r
diff --git a/public/javascripts/calendar/lang_pl.js b/public/javascripts/calendar/lang_pl.js
new file mode 100644 (file)
index 0000000..2b7fbd9
--- /dev/null
@@ -0,0 +1,15 @@
+(function() {\r
+   ProtoCalendar.LangFile['pl'] = {\r
+     HOUR_MINUTE_ERROR: 'The time is not valid.',\r
+     NO_DATE_ERROR: 'No day has been selected.',\r
+     OK_LABEL: 'OK',\r
+     DEFAULT_FORMAT: 'mm/dd/yyyy',\r
+     LABEL_FORMAT: 'dddi mmm dd yyyy',\r
+     MONTH_ABBRS: ['Styczeń','Luty','Marzec','Kwiecień','Maj','Czerwiec','Lipiec','Sierpień','Wrzesień','Październik','Listopad','Grudzień'],\r
+     WEEKDAY_ABBRS: ['Pn','Wt','Śr','Czw','Pt','So','Nie'],\r
+     WEEKDAY_NAMES: ['Pn','Wt','Śr','Czw','Pt','So','Nie'],\r
+     YEAR_LABEL: ' ',\r
+     MONTH_LABEL: ' ',\r
+     YEAR_AND_MONTH: false\r
+   };\r
+ })();\r
diff --git a/public/javascripts/calendar/lang_pt-BR.js b/public/javascripts/calendar/lang_pt-BR.js
new file mode 100644 (file)
index 0000000..a6aeca5
--- /dev/null
@@ -0,0 +1,15 @@
+(function() {\r
+   ProtoCalendar.LangFile['pt-BR'] = {\r
+     HOUR_MINUTE_ERROR: 'The time is not valid.',\r
+     NO_DATE_ERROR: 'No day has been selected.',\r
+     OK_LABEL: 'OK',\r
+     DEFAULT_FORMAT: 'mm/dd/yyyy',\r
+     LABEL_FORMAT: 'dddi mmm dd yyyy',\r
+     MONTH_ABBRS: ['Janeiro','Fevereiro','Mar&ccedil;o','Abril','Maio','Junho','Julho','Agosto','Setembro','Outubro','Novembro','Dezembro'],\r
+     WEEKDAY_ABBRS: ['Dom','Seg','Ter','Qua','Qui','Sex','Sab'],\r
+     WEEKDAY_NAMES: ['Dom','Seg','Ter','Qua','Qui','Sex','Sab'],\r
+     YEAR_LABEL: ' ',\r
+     MONTH_LABEL: ' ',\r
+     YEAR_AND_MONTH: false\r
+   };\r
+ })();\r
diff --git a/public/javascripts/calendar/lang_ro.js b/public/javascripts/calendar/lang_ro.js
new file mode 100644 (file)
index 0000000..6b74357
--- /dev/null
@@ -0,0 +1,15 @@
+(function() {\r
+   ProtoCalendar.LangFile['ro'] = {\r
+     HOUR_MINUTE_ERROR: 'The time is not valid.',\r
+     NO_DATE_ERROR: 'No day has been selected.',\r
+     OK_LABEL: 'OK',\r
+     DEFAULT_FORMAT: 'mm/dd/yyyy',\r
+     LABEL_FORMAT: 'dddi mmm dd yyyy',\r
+     MONTH_ABBRS: ['Januarie', 'Februarie', 'Martie', 'Aprilie', 'Mai', 'Junie','Julie', 'August', 'Septembrie', 'Octombrie', 'Noiembrie', 'Decembrie'],\r
+     WEEKDAY_ABBRS: ['D', 'L', 'Ma', 'Mi', 'J', 'V', 'S'],\r
+     WEEKDAY_NAMES: ['D', 'L', 'Ma', 'Mi', 'J', 'V', 'S'],\r
+     YEAR_LABEL: ' ',\r
+     MONTH_LABEL: ' ',\r
+     YEAR_AND_MONTH: false\r
+   };\r
+ })();\r
diff --git a/public/javascripts/calendar/lang_ru.js b/public/javascripts/calendar/lang_ru.js
new file mode 100644 (file)
index 0000000..3120c9b
--- /dev/null
@@ -0,0 +1,15 @@
+(function() {\r
+   ProtoCalendar.LangFile['ru'] = {\r
+     HOUR_MINUTE_ERROR: 'The time is not valid.',\r
+     NO_DATE_ERROR: 'No day has been selected.',\r
+     OK_LABEL: 'OK',\r
+     DEFAULT_FORMAT: 'mm/dd/yyyy',\r
+     LABEL_FORMAT: 'dddi mmm dd yyyy',\r
+     MONTH_ABBRS: ['Январь','Февраль','Март','Апрель','Май','Июнь','Июль','Август','Сентябрь','Октябрь','Ноябрь','Декабрь'],\r
+     WEEKDAY_ABBRS: ['Вс','Пн','Вт','Ср','Чт','Пт','Сб'],\r
+     WEEKDAY_NAMES: ['Вс','Пн','Вт','Ср','Чт','Пт','Сб'],\r
+     YEAR_LABEL: ' ',\r
+     MONTH_LABEL: ' ',\r
+     YEAR_AND_MONTH: false\r
+   };\r
+ })();\r
diff --git a/public/javascripts/calendar/lang_sk.js b/public/javascripts/calendar/lang_sk.js
new file mode 100644 (file)
index 0000000..7075331
--- /dev/null
@@ -0,0 +1,15 @@
+(function() {\r
+   ProtoCalendar.LangFile['sk'] = {\r
+     HOUR_MINUTE_ERROR: 'The time is not valid.',\r
+     NO_DATE_ERROR: 'No day has been selected.',\r
+     OK_LABEL: 'OK',\r
+     DEFAULT_FORMAT: 'mm/dd/yyyy',\r
+     LABEL_FORMAT: 'dddi mmm dd yyyy',\r
+     MONTH_ABBRS: ['Január','Február','Marec','Apríl','Máj','Jún','Júl','August','September','Október','November','December'],\r
+     WEEKDAY_ABBRS: ['Ne','Po','Ut','St','Št','Pia','So'],\r
+     WEEKDAY_NAMES: ['Ne','Po','Ut','St','Št','Pia','So'],\r
+     YEAR_LABEL: ' ',\r
+     MONTH_LABEL: ' ',\r
+     YEAR_AND_MONTH: false\r
+   };\r
+ })();\r
diff --git a/public/javascripts/calendar/lang_zh-cn.js b/public/javascripts/calendar/lang_zh-cn.js
new file mode 100644 (file)
index 0000000..01d4784
--- /dev/null
@@ -0,0 +1,18 @@
+(function() {\r
+   ProtoCalendar.LangFile['zh-cn'] = {\r
+     HOUR_MINUTE_ERROR: '请输入正确的时间。',\r
+     NO_DATE_ERROR: '请选择日期。',\r
+     OK_LABEL: 'OK',\r
+     DEFAULT_FORMAT: 'yyyy/mm/dd',\r
+     LABEL_FORMAT: 'yyyy年mm月dd日 ddddi',\r
+     MONTH_ABBRS: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],\r
+     WEEKDAY_ABBRS: ['日','一','二','三','四','五','六'],\r
+     WEEKDAY_NAMES: ['星期日','星期一','星期二','星期三','星期四','星期五','星期六'],\r
+     YEAR_LABEL: '年',\r
+     MONTH_LABEL: '月',\r
+     YEAR_AND_MONTH: true,\r
+     today: '今天',\r
+     tomorrow: '明天',\r
+     yesterday: '昨天'\r
+   };\r
+ })();\r
diff --git a/public/javascripts/calendar/lang_zh-tw.js b/public/javascripts/calendar/lang_zh-tw.js
new file mode 100644 (file)
index 0000000..495c27e
--- /dev/null
@@ -0,0 +1,18 @@
+(function() {\r
+   ProtoCalendar.LangFile['zh-tw'] = {\r
+     HOUR_MINUTE_ERROR: '請輸入正確的時間。',\r
+     NO_DATE_ERROR: '請選擇日期。',\r
+     OK_LABEL: '完成',\r
+     DEFAULT_FORMAT: 'yyyy/mm/dd',\r
+     LABEL_FORMAT: 'yyyy年mm月dd日 ddddi',\r
+     MONTH_ABBRS: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],\r
+     WEEKDAY_ABBRS: ['日','一','二','三','四','五','六'],\r
+     WEEKDAY_NAMES: ['星期日','星期一','星期二','星期三','星期四','星期五','星期六'],\r
+     YEAR_LABEL: '年',\r
+     MONTH_LABEL: '月',\r
+     YEAR_AND_MONTH: true,\r
+     today: '今天',\r
+     tomorrow: '明天',\r
+     yesterday: '昨天'\r
+   };\r
+ })();\r
diff --git a/public/javascripts/calendar/protocalendar.js b/public/javascripts/calendar/protocalendar.js
new file mode 100644 (file)
index 0000000..a13d7c9
--- /dev/null
@@ -0,0 +1,1434 @@
+/*  protocalendar.js
+ *  (c) 2009 Spookies
+ * 
+ *  License : MIT-style license.
+ *  Web site: http://labs.spookies.jp/product/protocalendar
+ *
+ *  protocalendar.js - depends on prototype.js 1.6 or later
+ *  http://www.prototypejs.org/
+ *
+/*--------------------------------------------------------------------------*/
+
+var ProtoCalendar = Class.create();
+ProtoCalendar.Version = "1.1.8.2";
+
+ProtoCalendar.LangFile = new Object();
+ProtoCalendar.LangFile['en'] = {
+  HOUR_MINUTE_ERROR: 'The time is not valid.',
+  NO_DATE_ERROR: 'No day has been selected.',
+  OK_LABEL: 'OK',
+  DEFAULT_FORMAT: 'mm/dd/yyyy',
+  LABEL_FORMAT: 'ddd mm/dd/yyyy',
+  MONTH_ABBRS: ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'],
+  MONTH_NAMES: ['January','February','March','April','May','June','July','August','September','October','November','December'],
+  YEAR_LABEL: ' ',
+  MONTH_LABEL: ' ',
+  WEEKDAY_ABBRS: ['Sun','Mon','Tue','Wed','Thr','Fri','Sat'],
+  WEEKDAY_NAMES: ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'],
+  YEAR_AND_MONTH: false
+};
+
+ProtoCalendar.LangFile.defaultLang = 'en';
+ProtoCalendar.LangFile.defaultLangFile = function() { return ProtoCalendar.LangFile[defaultLang]; };
+
+ProtoCalendar.newDate = function() {
+  var d = new Date();
+  d.setDate(1);
+  return d;
+}
+
+//Only check vertically
+ProtoCalendar.withinViewport = function(element) {
+  var dimensions = ProtoCalendar.callWithVisibility(element, function() { return element.getDimensions(); });
+  var width = dimensions.width;
+  var height = dimensions.height;
+  var offsets = ProtoCalendar.callWithVisibility(element, function() { return element.viewportOffset(); });
+  var offsetX = offsets.left;
+  var offsetY = offsets.top;
+  return (offsetY >=0) && (offsetY + height <= document.viewport.getHeight());
+}
+
+ProtoCalendar.callWithVisibility = function(element, func) {
+  element = $(element);
+  var display = $(element).getStyle('display');
+  if (display != 'none' && display != null) {// Safari bug 
+    return func();
+  }
+  var els = element.style;
+  var originalVisibility = els.visibility;
+  var originalPosition = els.position;
+  var originalDisplay = els.display;
+  els.visibility = 'hidden';
+  els.position = 'absolute';
+  els.display = 'block';
+  var result = func();
+  els.display = originalDisplay;
+  els.position = originalPosition;
+  els.visibility = originalVisibility;
+  return result;
+}
+
+Object.extend(ProtoCalendar, {
+                JAN: 0,
+                FEB: 1,
+                MAR: 2,
+                APR: 3,
+                MAY: 4,
+                JUNE: 5,
+                JULY: 6,
+                AUG: 7,
+                SEPT: 8,
+                OCT: 9,
+                NOV: 10,
+                DEC: 11,
+
+                SUNDAY: 0,
+                MONDAY: 1,
+                TUESDAY: 2,
+                WEDNESDAY: 3,
+                THURSDAY: 4,
+                FRIDAY: 5,
+                SATURDAY: 6,
+
+                getNumDayOfMonth: function(year, month){
+                  return 32 - new Date(year, month, 32).getDate();
+                },
+
+                getDayOfWeek: function(year, month, day) {
+                  return new Date(year, month, day).getDay();
+                }
+              });
+
+ProtoCalendar.prototype = {
+  initialize: function(options) {
+    var date = ProtoCalendar.newDate();
+    this.options = Object.extend({
+                                   month: date.getMonth(),
+                                   year: date.getFullYear(),
+                                   lang: ProtoCalendar.LangFile.defaultLang
+                                 }, options || { });
+    var getHolidays = ProtoCalendar.LangFile[this.options.lang]['getHolidays'];
+    if (getHolidays) {
+      this.initializeHolidays = getHolidays.bind(top, this);
+    } else {
+      this.initializeHolidays = function() { this.holidays = []; };
+    }
+    this.date = new Date(this.options.year, this.options.month, 1);
+  },
+
+  getMonth: function() {
+    return this.date.getMonth();
+  },
+
+  getYear: function() {
+    return this.date.getFullYear();
+  },
+
+  invalidate: function() {
+    this.holidays = undefined;
+  },
+
+  setMonth: function(month) {
+    if (month != this.getMonth()) {
+      this.invalidate();
+    }
+    return this.date.setMonth(month);
+  },
+
+  setYear: function(year) {
+    if (year != this.getYear()) {
+      this.invalidate();
+    }
+    return this.date.setFullYear(year);
+  },
+
+  getDate: function() {
+    return this.date;
+  },
+
+  setDate: function(date) {
+    this.invalidate();
+    this.date = date;
+  },
+
+  setYearByOffset: function(offset) {
+    if (offset != 0) {
+      this.invalidate();
+    }
+    this.date.setFullYear(this.date.getFullYear() + offset);
+  },
+
+  setMonthByOffset: function(offset) {
+    if (offset != 0) {
+      this.invalidate();
+    }
+    this.date.setMonth(this.date.getMonth() + offset);
+  },
+
+  getNumDayOfMonth: function() {
+    return ProtoCalendar.getNumDayOfMonth(this.getYear(), this.getMonth());
+  },
+
+  getDayOfWeek: function(day) {
+    return ProtoCalendar.getDayOfWeek(this.getYear(), this.getMonth(), day);
+  },
+
+  clone: function() {
+    return new ProtoCalendar({year: this.getYear(), month: this.getMonth()});
+  },
+
+  getHoliday: function(day) {
+    if(!this.holidays) { this.initializeHolidays();}
+    var holiday = this.holidays[day];
+    return holiday? holiday : false;
+  },
+
+  initializeHolidays: function() {
+  }
+};
+
+var AbstractProtoCalendarRender = Class.create();
+Object.extend(AbstractProtoCalendarRender, {
+                id: 1,
+                WEEK_DAYS_SUNDAY: [ 0, 1, 2, 3, 4, 5, 6 ],
+                WEEK_DAYS_MONDAY: [ 1, 2, 3, 4, 5, 6, 0 ],
+                WEEK_DAYS_INDEX_SUNDAY: [ 0, 1, 2, 3, 4, 5, 6 ],
+                WEEK_DAYS_INDEX_MONDAY: [ 6, 0, 1, 2, 3, 4, 5 ],
+
+                getId: function() {
+                  var id = AbstractProtoCalendarRender.id;
+                  AbstractProtoCalendarRender.id += 1;
+                  return id;
+                }
+               });
+
+AbstractProtoCalendarRender.prototype = {
+  initialize: function(options) {
+    this.id = AbstractProtoCalendarRender.getId();
+    this.options = Object.extend({
+                                   weekFirstDay : ProtoCalendar.MONDAY,
+                                   containerClass: 'cal-container',
+                                   tableClass: 'cal-table',
+                                   headerTopClass: 'cal-header-top',
+                                   headerClass: 'cal-header',
+                                   headerBottomClass: 'cal-header-bottom',
+                                   bodyTopClass: 'cal-body-top',
+                                   bodyClass: 'cal-body',
+                                   bodyBottomClass: 'cal-body-bottom',
+                                   bodyId: this.getIdPrefix() + '-body',
+                                   footerTopClass: 'cal-footer-top',
+                                   footerClass: 'cal-footer',
+                                   footerBottomClass: 'cal-footer-bottom',
+                                   footerId: this.getIdPrefix() + '-footer',
+                                   yearSelectClass: 'cal-select-year',
+                                   yearSelectId: this.getIdPrefix() + '-select-year',
+                                   monthSelectClass: 'cal-select-month',
+                                   monthSelectId: this.getIdPrefix() + '-select-month',
+                                   borderClass: 'cal-border',
+                                   hourMinuteInputClass: 'cal-input-hour-minute',
+                                   hourMinuteInputId: this.getIdPrefix() + '-input-hour-minute',
+                                   hourInputClass: 'cal-input-hour',
+                                   hourInputId: this.getIdPrefix() + '-input-hour',
+                                   minuteInputClass: 'cal-input-minute',
+                                   minuteInputId: this.getIdPrefix() + '-input-minute',
+                                   secondInputClass: 'cal-input-second',
+                                   secondInputId: this.getIdPrefix() + '-input-second',
+                                   okButtonClass: 'cal-ok-button',
+                                   okButtonId: this.getIdPrefix() + '-ok-button',
+                                   errorDivClass: 'cal-error-list',
+                                   errorDivId: this.getIdPrefix() + '-error-list',
+                                   labelRowClass: 'cal-label-row',
+                                   labelCellClass: 'cal-label-cell',
+                                   nextButtonClass: 'cal-next-btn',
+                                   prevButtonClass: 'cal-prev-btn',
+                                   dayCellClass: 'cal-day-cell',
+                                   dayClass: 'cal-day',
+                                   weekdayClass: 'cal-weekday',
+                                   sundayClass: 'cal-sunday',
+                                   saturdayClass: 'cal-saturday',
+                                   holidayClass: 'cal-holiday',
+                                   otherdayClass: 'cal-otherday',
+                                   disabledDayClass: 'cal-disabled',
+                                   selectedDayClass: 'cal-selected',
+                                   nextBtnId: this.getIdPrefix() + '-next-btn',
+                                   prevBtnId: this.getIdPrefix() + '-prev-btn',
+                                   lang: ProtoCalendar.LangFile.defaultLang,
+                                   showEffect: 'Appear',
+                                   hideEffect: 'Fade',
+                                   ifInvisible: 'Flip', /* None | Scroll | Flip */
+                                   scrollMargin: 20
+                                 }, options || {});
+    this.langFile = ProtoCalendar.LangFile[this.options.lang];
+    this.weekFirstDay = this.options.weekFirstDay;
+    this.initWeekData();
+    this.container = this.createContainer();
+    this.alignTo = $(this.options.alignTo);
+    this.alignOrient = 'Below';
+    if (navigator.appVersion.match(/\bMSIE\b/)) {
+      this.iframe = this.createIframe();
+    }
+    this.resizeHandler = this.setPosition.bind(this);
+  },
+
+  createContainer: function() {
+    var container = $(document.createElement('div'));
+    container.addClassName(this.options.containerClass);
+    container.setStyle({position:'absolute',
+                        top: "0px",
+                        left: "0px",
+                        zindex:1,
+                        display: 'none'});
+    container.hide();
+    document.body.appendChild(container);
+    return container;
+  },
+
+  createIframe: function() {
+    var iframe = document.createElement("iframe");
+    iframe.setAttribute("src", "javascript:false;");
+    iframe.setAttribute("frameBorder", "0");
+    iframe.setAttribute("scrolling", "no");
+    Element.setStyle(iframe, { position:'absolute',
+                               top: "0px",
+                               left: "0px",
+                               zindex:10,
+                               display: 'none',
+                               overflow: 'hidden',
+                               filter: 'progid:DXImageTransform.Microsoft.Alpha(opacity=0)'
+                             });
+    document.body.appendChild(iframe);
+    return $(iframe);
+  },
+
+  getWeekdayLabel: function(weekday) {
+    return this.langFile.WEEKDAY_ABBRS[weekday];
+  },
+
+  getWeekdays: function() {
+    return this.weekdays;
+  },
+
+  initWeekData: function() {
+    if (this.weekFirstDay == ProtoCalendar.SUNDAY) {
+      this.weekLastDay = ProtoCalendar.SATURDAY;
+      this.weekdays = AbstractProtoCalendarRender.WEEK_DAYS_SUNDAY;
+      this.weekdaysIndex = AbstractProtoCalendarRender.WEEK_DAYS_INDEX_SUNDAY;
+    } else {
+      this.weekFirstDay == ProtoCalendar.MONDAY
+      this.weekLastDay = ProtoCalendar.SUNDAY;
+      this.weekdays = AbstractProtoCalendarRender.WEEK_DAYS_MONDAY;
+      this.weekdaysIndex = AbstractProtoCalendarRender.WEEK_DAYS_INDEX_MONDAY;
+    }
+  },
+
+  getCalendarBeginDay: function(calendar) {
+    var offset = this.getDayIndexOfWeek(calendar, 1);
+    var date = new Date(calendar.getYear(), calendar.getMonth(), 1 - offset);
+    return date;
+  },
+
+  getCalendarEndDay: function(calendar) {
+    var lastDayOfMonth = calendar.getNumDayOfMonth();
+    var offset = 6 - this.getDayIndexOfWeek(calendar, lastDayOfMonth);
+    var date = new Date(calendar.getYear(), calendar.getMonth(), lastDayOfMonth + offset + 1);
+    return date;
+  },
+
+  getDayIndexOfWeek: function(calendar, day) {
+    return this.weekdaysIndex[ calendar.getDayOfWeek(day) ];
+  },
+
+  getIdPrefix: function() {
+    return 'cal' + this.id;
+  },
+
+  getDayDivId: function(date) {
+    return this.getIdPrefix() + '-year' + date.getFullYear() + '-month' + date.getMonth() + '-day' + date.getDate();
+  },
+
+  setPosition: function() {
+    if (!this.alignTo) return true;
+    this.setAlignment(this.alignTo, this.container, this.alignOrient);
+    var withinView = ProtoCalendar.withinViewport(this.container);
+    if (!withinView && this.options.ifInvisible == 'Flip') {
+      this.alignOrient = (this.alignOrient == 'Above' ? 'Below' : 'Above');
+      this.setAlignment(this.alignTo, this.container, this.alignOrient);
+    }
+    if (this.iframe) {
+      var dimensions = Element.getDimensions(this.container);
+      this.iframe.setAttribute("width", dimensions.width);
+      this.iframe.setAttribute("height", dimensions.height);
+      this.setAlignment(this.alignTo, this.iframe, this.alignOrient);
+    }
+    if (this.options.ifInvisible == 'Scroll') this.scrollIfInvisible();
+    return true;
+  },
+
+  setAlignment: function(alignTo, element, pos) {
+    var offsets = Position.cumulativeOffset(alignTo);
+    element.setStyle({left: offsets[0] + "px"});
+    if (pos == 'Above') {
+      var elementHeight = ProtoCalendar.callWithVisibility(element, function() { return element.offsetHeight; });
+      element.setStyle({top: (offsets[1] - elementHeight) + "px"});
+    } else if (pos == 'Below') {
+      element.setStyle({top: (offsets[1] + alignTo.offsetHeight) + "px"});
+    } else {
+      //Unknown option
+    }
+  },
+
+  show: function(option) {
+    Event.observe(window, 'resize', this.resizeHandler);
+    this.setPosition();
+    if (typeof Effect != 'undefined') {
+      var effect =  this.options['showEffect'] || 'Appear';
+      if (!this._effect || this._effect.state == 'finished') {
+        this._effect = new Effect[effect](this.container, {duration: 0.5});
+      }
+    } else {
+      this.container.show();
+    }
+    if (this.iframe) this.iframe.show();
+  },
+
+  scrollIfInvisible: function() {
+    var container = this.container;
+    var dimensions = ProtoCalendar.callWithVisibility(container, function() { return container.getDimensions(); });
+    var width = dimensions.width;
+    var height = dimensions.height;
+    var offsets = ProtoCalendar.callWithVisibility(container, function() { return container.viewportOffset(); });
+    var offsetX = offsets.left;
+    var offsetY = offsets.top;
+    var diff = offsetY + height - document.viewport.getHeight();
+    if (diff > 0) {
+      window.scrollBy(0, diff + this.options.scrollMargin);
+    }
+  },    
+
+  hide: function(option) {
+    Event.stopObserving(window, 'resize', this.resizeHandler);
+    if (!this.container.visible()) {
+      return ;
+    }
+    if (typeof Effect != 'undefined') {
+      var effect =  this.options['hideEffect'] || 'Fade';
+      if (!this._effect || this._effect.state == 'finished') {
+        this._effect = new Effect[effect](this.container, {duration: 0.3});
+      }
+    } else {
+      this.container.hide();
+    }
+    if (this.iframe) this.iframe.hide();
+  },
+
+  hideImmediately: function(option) {
+    if (!this.container.visible()) {
+      return ;
+    }
+    this.container.hide();
+    if (this.iframe) this.iframe.hide();
+  },
+
+  toggle: function(element) {
+    this.container.visible() ? this.hide() : this.show();
+  },
+
+  render: function(calendar) { },
+
+  rerender: function(calendar) { },
+
+  getContainer: function() {
+    return this.container;
+  },
+
+  getPrevButton: function() {
+    return $(this.options.prevBtnId);
+  },
+
+  getNextButton: function() {
+    return $(this.options.nextBtnId);
+  },
+
+  getYearSelect: function() {
+    return $(this.options.yearSelectId);
+  },
+
+  getMonthSelect: function() {
+    return $(this.options.monthSelectId);
+  },
+
+  getHourInput: function() {
+    return $(this.options.hourInputId);
+  },
+
+  getMinuteInput: function() {
+    return $(this.options.minuteInputId);
+  },
+
+  getSecondInput: function() {
+    return $(this.options.secondInputId);
+  },
+
+  getOkButton: function() {
+    return $(this.options.okButtonId);
+  },
+
+  getBody: function() {
+    return $(this.options.bodyId);
+  },
+
+  getDayDivs: function() {
+    //Good Performance for IE
+    var divEls = [];
+    var dayDivs = this.dayDivs;
+    for (var i = 0; i < dayDivs.length; i++) {
+      divEls.push(document.getElementById(dayDivs[i]));
+    }
+    return divEls;
+    //return this.container.getElementsBySelector("a." + this.options.dayClass);
+  },
+
+  getDateFromEl: function(el) {
+    var element = $(el);
+    return new Date(element.readAttribute('year'), element.readAttribute('month'), element.readAttribute('day'));
+  },
+
+  //Set hour minute (second) to date from the input, if invalid return undefined.
+  //The input date parameter will not be tainted even if it fails, because the return result is a copy.
+  injectHourMinute: function(date) {
+    if (!date || isNaN(date.getTime())) return undefined;
+    var rd = new Date(date.getFullYear(), date.getMonth(), date.getDate());
+    rd.setHours(parseInt(this.getHourInput().value, 10));
+    rd.setMinutes(this.getMinuteInput().value);
+    if (this.options.enableSecond) rd.setSeconds(this.getSecondInput().value);
+    return isNaN(rd.getTime()) ? undefined : rd;
+  },
+
+  selectDate: function(date) {
+    var dayEl = $(this.getDayDivId(date));
+    if (dayEl) dayEl.addClassName(this.options.selectedDayClass);
+  },
+
+  selectTime: function(date) {
+    if (!date) return;
+    this.getHourInput().value = date.getHours();
+    this.getMinuteInput().value = date.getMinutes();
+    if (this.options.enableSecond) this.getSecondInput().value = date.getSeconds();
+  },
+
+  deselectDate: function(date) {
+    if (date) {
+      var dateEl = $(this.getDayDivId(date));
+      if (dateEl) dateEl.removeClassName(this.options.selectedDayClass);
+    }
+  },
+
+  evaluateWithOptions: function(html) {
+    var template = new Template(html);
+    return template.evaluate(this.options);
+  },
+
+  defaultOnError: function(msg) {
+    this.ensureErrorDiv();
+    this.errorDiv.show();
+    this.errorDiv.innerHTML += '<li>' + this.langFile[msg] + '</li>';
+  },
+
+  hideError: function() {
+    this.ensureErrorDiv();
+    this.errorDiv.innerHTML = '';
+    this.errorDiv.hide();
+  },
+
+  ensureErrorDiv: function() {
+    if (!this.errorDiv) {
+      var errorDivHtml = '<div class="#{errorDivClass}" id="#{errorDivId}"><ul></ul></div>';
+      new Insertion.Before($(this.options.footerId), this.evaluateWithOptions(errorDivHtml));
+      this.errorDiv = $(this.options.errorDivId);
+    }
+    },
+
+  isSelectable: function(date) {
+      return (this.options.minDate - date) <= 0 && (date - this.options.maxDate) <= 0;
+    }
+  
+};
+
+var ProtoCalendarRender = Class.create();
+Object.extend(ProtoCalendarRender.prototype, AbstractProtoCalendarRender.prototype);
+
+Object.extend(
+  ProtoCalendarRender.prototype,
+  {
+    render: function(calendar) {
+      var html = '';
+      html += this.renderHeader(calendar);
+      html += '<div class="#{bodyTopClass}"></div><div class="#{bodyClass}" id="#{bodyId}">';
+      html += '</div><div class="#{bodyBottomClass}"></div>';
+      if (this.options.enableHourMinute) html += this.renderHourMinute();
+      html += this.renderFooter(calendar);
+      this.container.innerHTML = this.evaluateWithOptions(html);
+      this.rerender(calendar);
+    },
+
+    rerender: function(calendar) {
+      this.getBody().innerHTML = this.evaluateWithOptions(this.renderBody(calendar));
+      SelectCalendar.selectOption(this.getMonthSelect(), calendar.getMonth());
+      SelectCalendar.selectOption(this.getYearSelect(), calendar.getYear());
+      if (this.container.visible()) this.setPosition();
+    },
+
+    renderHeader: function(calendar) {
+      var html = '';
+      // required 'href'
+      html += '<div class="#{headerTopClass}"></div><div class="#{headerClass}">' +
+        '<a href="#" id="#{prevBtnId}" class="#{prevButtonClass}">&lt;&lt;</a>' +
+        this.createSelect(calendar.getYear(), calendar.getMonth()) +
+        '<a href="#" id="#{nextBtnId}" class="#{nextButtonClass}">&gt;&gt;</a>' +
+        '</div><div class="#{headerBottomClass}"></div>';
+      return html;
+    },
+
+    renderFooter: function(calendar) {
+      return '<div class="#{footerTopClass}"></div><div class="#{footerClass}" id="#{footerId}"></div><div class="#{footerBottomClass}"></div>';
+    },
+
+    renderHourMinute: function() {
+      if (!this.hourMinuteHtml) {
+        var html = '<div class="#{borderClass}"></div><div id="#{hourMinuteInputId}" class="#{hourMinuteInputClass}">';
+        html += '<input type="text" name="hour" size="2" maxlength="2" class="#{hourInputClass}" id="#{hourInputId}" />' +
+          ':<input type="text" name="minute" size="2" maxlength="2" class="#{minuteInputClass}" id="#{minuteInputId}" />';
+        if (this.options.enableSecond) {
+          html += ':<input type="text" name="second" size="2" maxlength="2" class="#{secondInputClass}" id="#{secondInputId}"/>';
+        }
+        html += '<input type="button" value="' + this.langFile['OK_LABEL'] + '" class="#{okButtonClass}" name="ok_button" id="#{okButtonId}"/>';
+        html += '</div>';
+        this.hourMinuteHtml =  html;
+      }
+      return this.hourMinuteHtml;
+    },
+
+    createSelect: function(year, month) {
+      var yearPart = this.createYearSelect(year) + this.langFile.YEAR_LABEL;
+      var monthPart = this.createMonthSelect(month) + this.langFile.MONTH_LABEL;
+      if (this.langFile.YEAR_AND_MONTH) {
+        return  yearPart + monthPart;
+      } else {
+        return monthPart + yearPart;
+      }
+    },
+
+    createYearSelect: function(year) {
+      var html = '';
+      html += '<select id="#{yearSelectId}" class="#{yearSelectClass}">';
+      for (var y = this.options.startYear, endy = this.options.endYear; y <= endy; y += 1) {
+        html += '<option value="' + y + '"' + (y == year ? ' selected' : '') + '>' + y + '</option>';
+      }
+      html += '</select>';
+      return html;
+    },
+
+    createMonthSelect: function(month) {
+      if (!this.monthSelectHtml) {
+        var html = '';
+        html += '<select id="#{monthSelectId}" class="#{monthSelectClass}">';
+        for (var m = ProtoCalendar.JAN; m <= ProtoCalendar.DEC; m += 1) {
+          html += '<option value="' + m + '"' + (m == month ? ' selected' : '') + '>' + this.langFile['MONTH_ABBRS'][m] + '</option>';
+        }
+        html += '</select>';
+        this.monthSelectHtml = html;
+      }
+      return this.monthSelectHtml;
+    },
+
+    renderBody: function(calendar) {
+      this.dayDivs = [];
+      var html = '<table class="#{tableClass}" cellspacing="0">';
+      html += '<tr class="#{labelRowClass}">';
+      var othis = this;
+      if (!this.headHtml) {
+        this.headHtml = '';
+        $A(this.getWeekdays()).each(function(weekday) {
+                                      var exClassName = '';
+                                      if (weekday == ProtoCalendar.SUNDAY) { exClassName = ' #{sundayClass}'; }
+                                      if (weekday == ProtoCalendar.SATURDAY) { exClassName = ' #{saturdayClass}'; }
+                                      othis.headHtml += '<th class="#{labelCellClass}' + exClassName + '">' +
+                                        othis.getWeekdayLabel(weekday) +
+                                        '</th>';
+                                    });
+      }
+      html += this.headHtml;
+      var curDay = this.getCalendarBeginDay(calendar);
+      var calEndDay = this.getCalendarEndDay(calendar);
+      html += '<tbody>';
+      var dayNum = Math.round((calEndDay - curDay) / 1000 / 60 / 60 / 24);
+      for(var i = 0; i < dayNum; i += 1, curDay.setDate(curDay.getDate() + 1)) {
+        var divClassName;
+        var holiday = calendar.getHoliday(curDay.getDate());
+        if(curDay.getMonth() != calendar.getMonth()) {
+          divClassName = this.options.otherdayClass;
+        } else if (holiday) {
+          divClassName = this.options.holidayClass;
+        } else if (curDay.getDay() == ProtoCalendar.SUNDAY) {
+          divClassName = this.options.sundayClass;
+        } else if (curDay.getDay() == ProtoCalendar.SATURDAY) {
+          divClassName = this.options.saturdayClass;
+        } else {
+          divClassName = this.options.weekdayClass;
+        }
+
+        if (curDay.getDay() == this.weekFirstDay) { html += '<tr>'; }
+        var dayId = this.getDayDivId(curDay);
+        var dayHtml = '';
+        if (this.isSelectable(curDay)) {
+          dayHtml = '<a class="#{dayClass}" href="#" id="' + dayId +
+            (holiday ? '" title="' + holiday : '') +
+            '" year="' + curDay.getFullYear() +
+            '" month="' + curDay.getMonth() +
+            '" day="' + curDay.getDate() +
+            '">' + curDay.getDate() + '</a>';
+          this.dayDivs.push(dayId);
+        } else {
+          divClassName += ' ' + this.options.disabledDayClass;
+          dayHtml = curDay.getDate();
+        }
+        html += '<td class="' + divClassName + ' #{dayCellClass}">' + dayHtml + '</td>';
+        if (curDay.getDay() == this.weekLastDay) { html += '</tr>'; }
+      }
+      html += '</tbody></table>';
+      return html;
+    }
+
+  });
+
+var ProtoCalendarController = Class.create();
+ProtoCalendarController.prototype = {
+  initialize: function(calendarRender, options) {
+    this.options = Object.extend({
+                                   onHourMinuteError: this.defaultOnHourMinuteError.bind(this),
+                                   onNoDateError: this.defaultOnNoDateError.bind(this)
+                                 }, options);
+    this.calendarRender = calendarRender;
+    this.initializeDate();
+    this.calendar = new ProtoCalendar(this.options);
+    this.calendarRender.render(this.calendar);
+    if (options.year && options.month && options.day) {
+      var date = new Date(this.options.year, this.options.month, this.options.day);
+      if (options.hour && options.minute && options.second) {
+        date.setHours(options.hour, options.minute && options.second);
+      }
+      this.selectDate(date, true);
+    } else {
+      this.selectDate(null);
+    }
+    this.observeEventsOnce();
+    this.observeEvents();
+    this.onChangeHandlers = [];
+  },
+
+  initializeDate: function() {
+    var date = ProtoCalendar.newDate();
+    if (!this.options.year) {
+      if (date.getFullYear() >= this.options.startYear && date.getFullYear() <= this.options.endYear) { 
+        this.options.year = date.getFullYear();
+      } else {
+        this.options.year = this.options.startYear;
+      }
+    }
+    if (!this.options.month) {
+      this.options.month = date.getMonth();
+    }
+    if (!this.options.day) {
+      this.options.day = date.getDate();
+    }
+  },
+
+  observeEventsOnce: function() {
+    var calrndr = this.calendarRender;
+    calrndr.getPrevButton().observe('click', this.showPrevMonth.bindAsEventListener(this));
+    calrndr.getNextButton().observe('click', this.showNextMonth.bindAsEventListener(this));
+    var othis = this;
+    var yearSelect = calrndr.getYearSelect();
+    var monthSelect = calrndr.getMonthSelect();
+    var year = this.calendar.getYear();
+    var month = this.calendar.getMonth();
+    yearSelect.observe('change', function() {
+                         othis.setMonth(parseInt(yearSelect[yearSelect.selectedIndex].value, 10), parseInt(monthSelect[monthSelect.selectedIndex].value, 10));
+                       });
+    monthSelect.observe('change', function() {
+                          othis.setMonth(parseInt(yearSelect[yearSelect.selectedIndex].value, 10), parseInt(monthSelect[monthSelect.selectedIndex].value, 10));
+                       });
+    // add auto focus
+    if (this.options.enableHourMinute) {
+      var hour = calrndr.getHourInput();
+      var minute = calrndr.getMinuteInput();
+      hour.observe('keyup', this._autoFocus.bindAsEventListener(hour, minute));
+      hour.observe('keydown', this._disablePaste.bindAsEventListener(hour));
+      hour.observe('contextmenu', this._disableContextMenu.bindAsEventListener(hour));
+      var nextEl = this.options.enableSecond ? calrndr.getSecondInput() : calrndr.getOkButton();
+      minute.observe('keyup', this._autoFocus.bindAsEventListener(minute, nextEl));
+      minute.observe('keydown', this._disablePaste.bindAsEventListener(minute));
+      minute.observe('contextmenu', this._disableContextMenu.bindAsEventListener(minute));
+      if (navigator.appVersion.match(/\bMSIE\b/)) {
+        hour.setStyle({'imeMode': 'disabled'});
+        minute.setStyle({'imeMode': 'disabled'});
+      }
+    }
+    if (this.options.enableSecond) {
+      var second = calrndr.getSecondInput();
+      second.observe('keyup', this._autoFocus.bindAsEventListener(second, calrndr.getOkButton()));
+      second.observe('keydown', this._disablePaste.bindAsEventListener(second));
+      second.observe('contextmenu', this._disableContextMenu.bindAsEventListener(second));
+      if (navigator.appVersion.match(/\bMSIE\b/)) {
+        second.setStyle({'imeMode': 'disabled'});
+      }
+    }
+    if (this.options.enableHourMinute) calrndr.getOkButton().observe('click', this.onSubmit.bind(this));
+  },
+  _disableContextMenu: function(event) {
+    Event.stop(event);
+    return false;
+  },
+  _disablePaste: function(event) {
+    // ctrl + v || shift + insert
+    if ((event.keyCode == 86 && event.ctrlKey) || (event.keyCode == 45 && event.shiftKey)) {
+      Event.stop(event);
+      return false;
+    }
+  },
+  _autoFocus: function(event, nextEl) {
+    // shift || tab
+    if (event.keyCode == 16 || event.keyCode == 9 || (event.keyCode == 9 && event.shiftKey)) {
+      Event.stop(event);
+      return false;
+    }
+    var v = this.value;
+    if (v.length && v.length == 2) {
+      nextEl.focus();
+      nextEl.select();
+    }
+    return true;
+  },
+  observeEvents: function() {
+    var othis = this;
+    this.calendarRender.getDayDivs().each(function(el) {
+                                            Event.observe(el, 'click', othis.onClickHandler.bindAsEventListener(othis));
+                                          });
+  },
+
+  onClickHandler: function(event) {
+    Event.stop(event);
+    var date = this.calendarRender.getDateFromEl(Event.element(event));
+    if (date) {
+      this.selectDate(date);
+      if (!this.options.enableHourMinute) {
+        this.onChangeHandler();
+        setTimeout(this.hideCalendar.bind(this), 150);
+      }
+    }
+  },
+
+  onSubmit: function() {
+    this.hideError();
+    var date = this.selectedDate;
+    if (!date) return this.options.onNoDateError();
+    date = this.calendarRender.injectHourMinute(date);
+    if (!date) {
+      this.options.onHourMinuteError();
+    } else {
+      this.selectDate(date, true);
+      if (this.options.enableHourMinute) this.calendarRender.selectTime(date);
+      this.onChangeHandler();
+      this.hideCalendar();
+    }
+  },
+
+  selectDate: function(date, redraw) {
+    this.calendarRender.deselectDate(this.selectedDate);
+    this.selectedDate = date;
+    if (!date) return;
+    if (redraw && (date.getFullYear() != this.calendar.getYear() || date.getMonth() != this.calendar.getMonth())) {
+      this.setMonth(date.getFullYear(), date.getMonth());
+    }
+    this.calendarRender.selectDate(this.selectedDate);
+  },
+
+  getSelectedDate: function() {
+    return this.selectedDate;
+  },
+
+  addChangeHandler: function(func) {
+    this.onChangeHandlers.push(func);
+  },
+
+  onChangeHandler: function() {
+    this.onChangeHandlers.each(function(f) { f(); });
+  },
+
+  showCalendar: function() {
+    this.calendarRender.show();
+  },
+
+  hideCalendar: function() {
+    this.calendarRender.hide();
+  },
+
+  blurCalendar: function(event) {
+    if (event.keyCode == 9) {
+      this.hideImmediatelyCalendar();
+    }
+  },
+
+  hideImmediatelyCalendar: function() {
+    this.calendarRender.hideImmediately();
+  },
+
+  toggleCalendar: function() {
+    this.calendarRender.toggle();
+  },
+
+  showPrevMonth: function(event) {
+    this.shiftMonthByOffset(-1);
+    if (event) Event.stop(event);
+  },
+
+  showNextMonth: function(event) {
+    this.shiftMonthByOffset(1);
+    if (event) Event.stop(event);
+  },
+
+  shiftMonthByOffset: function(offset) {
+    if (offset == 0) return;
+    var newDate = new Date(this.calendar.getDate().getTime());
+    newDate.setMonth(newDate.getMonth() + offset);
+    if (this.options.startYear > newDate.getFullYear() || this.options.endYear < newDate.getFullYear()) return;
+    this.calendar.setMonthByOffset(offset);
+    this.afterSet();
+  },
+
+  setMonth: function(year, month) {
+    if (this.calendar.getYear() == year && this.calendar.getMonth() == month) return;
+    this.calendar.setYear(year);
+    this.calendar.setMonth(month);
+    this.afterSet();
+  },
+
+  afterSet: function() {
+    this.calendarRender.rerender(this.calendar);
+    this.selectDate(this.selectedDate);
+    this.observeEvents();
+  },
+
+  getContainer: function() {
+    return this.calendarRender.getContainer();
+  },
+
+  defaultOnHourMinuteError: function() {
+    this.calendarRender.defaultOnError('HOUR_MINUTE_ERROR');
+  },
+
+  defaultOnNoDateError: function() {
+    this.calendarRender.defaultOnError('NO_DATE_ERROR');
+  },
+
+  hideError: function() {
+    this.calendarRender.hideError();
+  }
+};
+
+//Don't instantiate this, extend BaseCalendar
+var BaseCalendar = Class.create();
+BaseCalendar.bindOnLoad = function(f) {
+  if (document.observe) {
+    document.observe('dom:loaded', f);
+  } else {
+    Event.observe(window, 'load', f);
+  }
+};
+
+
+BaseCalendar.prototype = {
+  initialize: function(options) {
+    throw "Cannot instantiate BaseCalendar.";
+  },
+
+  initializeOptions: function(options) {
+    if (!options) options = {};
+    this.options = Object.extend({
+                                   startYear: ProtoCalendar.newDate().getFullYear() - 10,
+                                   endYear: ProtoCalendar.newDate().getFullYear() + 10,
+                                   minDate: new Date(1900, 0, 1),
+                                   maxDate: new Date(3000, 0, 1),
+                                   format: ProtoCalendar.LangFile[options.lang || ProtoCalendar.LangFile.defaultLang]['DEFAULT_FORMAT'],
+                                   enableHourMinute: false,
+                                   enableSecond: false,
+                                   lang: ProtoCalendar.LangFile.defaultLang,
+                                   triggers: []
+                                 }, options);
+  },
+
+  initializeBase: function() {
+    this.calendarController = new ProtoCalendarController(new ProtoCalendarRender(this.options), this.options);
+    this.langFile = ProtoCalendar.LangFile[this.options.lang] || ProtoCalendar.LangFile.defaultLangFile();
+    this.triggers = [];
+    this.options.triggers.each(this.addTrigger.bind(this));
+    this.changeHandlers = [];
+    this.observeEvents();
+  },
+
+  addTrigger: function(el) {
+    this.triggers.push($(el));
+    $(el).setStyle({'cursor': 'pointer'});
+  },
+
+  observeEvents: function() {
+    Event.observe(document.body, 'click', this.windowClickHandler.bindAsEventListener(this));
+    this.calendarController.addChangeHandler(this.onCalendarChange.bind(this));
+    this.doObserveEvents();
+  },
+
+  doObserveEvents: function() {
+    //Override this
+  },
+
+  windowClickHandler: function(event) {
+    var target = $(Event.element(event));
+    if (this.triggers.include(target)) {
+      this.calendarController.toggleCalendar();
+    } else if (target != this.input && !Element.descendantOf(target, this.calendarController.getContainer())) {
+      this.calendarController.hideCalendar();
+    }
+  },
+
+  addChangeHandler: function(f) {
+    this.changeHandlers.push(f);
+  },
+
+  onCalendarChange: function() {
+    this.changeHandlers.each(function(f) { f(); });
+  }
+};
+
+var InputCalendar = Class.create();
+InputCalendar.createOnLoaded = function(input, options) {
+  BaseCalendar.bindOnLoad(function() {
+    new InputCalendar(input, options);
+  });
+};
+InputCalendar.initCalendars = function(inputs, options) {
+  if (document.observe) {
+    document.observe('dom:loaded', function() {
+      $$(inputs).each(function(input) {
+        new InputCalendar(input, options);
+      });
+    });
+  } else {
+    Event.observe(window, 'load', function() {
+      $$(inputs).each(function(input) {
+        new InputCalendar(input, options);
+      });
+    });
+  }
+};
+Object.extend(InputCalendar.prototype, BaseCalendar.prototype);
+Object.extend(
+  InputCalendar.prototype,
+  {
+    initialize: function(input, options) {
+      this.input = $(input); // used in doObserveEvents()
+      this.initializeOptions(options);
+      this.options = Object.extend({
+                                     alignTo: input,
+                                     inputReadOnly: false,
+                                     labelFormat: undefined,
+                                     labelEl: undefined
+                                   }, this.options);
+      this.initializeBase();
+      this.initializeInput();
+      this.initializeLabel();
+    },
+
+    initializeInput: function() {
+      this.dateFormat = new ProtoCalendar.DateFormat(this.options.format);
+      if (this.input.value && this.dateFormat.parse(this.input.value)) {
+        this.onInputChange();
+      } else {
+        this.onCalendarChange();
+      }
+      if (this.options.enableHourMinute) {
+        this.calendarController.calendarRender.selectTime(this.calendarController.selectedDate);
+      }
+      if (this.options.inputReadOnly) {
+        this.input.setAttribute('readOnly', this.options.inputReadOnly);
+      }
+    },
+
+    initializeLabel: function() {
+      this.labelFormat = new ProtoCalendar.DateFormat(this.options.labelFormat || this.langFile['LABEL_FORMAT']);
+      var labelElm = $(this.options.labelEl);
+      if ((! labelElm) && this.options.labelFormat) {
+        var labelId = this.input.id + '_label';
+        new Insertion.After(this.input, "<div id='" + labelId + "'></div>");
+        labelElm = $(labelId);
+      }
+      this.labelEl = labelElm;
+      this.changeLabel();
+    },
+
+    changeLabel: function() {
+      if (!this.labelEl) return;
+      if (this.calendarController.getSelectedDate()) {
+        this.labelEl.innerHTML = this.labelFormat.format(this.calendarController.getSelectedDate(), this.options.lang);
+      }
+    },
+
+    doObserveEvents: function() {
+      this.input.observe('change', this.onInputChange.bind(this));
+      this.input.observe('focus', this.calendarController.showCalendar.bind(this.calendarController));
+      this.input.observe('keydown', this.calendarController.blurCalendar.bindAsEventListener(this.calendarController));
+      this.addChangeHandler(this.changeInputValue.bind(this));
+      this.addChangeHandler(this.changeLabel.bind(this));
+    },
+
+    onInputChange: function() {
+      var date = this.dateFormat.parse(this.input.value);
+      if (date) {
+        this.calendarController.selectDate(date, true);
+        if (this.options.enableHourMinute) this.calendarController.calendarRender.selectTime(date);
+      } else {
+        var inputValue = this.input.value.toLowerCase();
+        var date;
+        if (this.langFile['today'] && this.langFile['today'] == inputValue || inputValue == 'today') {
+          date = ProtoCalendar.newDate();
+        } else if (this.langFile['tomorrow'] && this.langFile['tomorrow'] == inputValue || inputValue == 'tomorrow') {
+          date = ProtoCalendar.newDate();
+          date.setDate(date.getDate() + 1);
+        } else if (this.langFile['yesterday'] && this.langFile['yesterday'] == inputValue || inputValue == 'yesterday') {
+          date = ProtoCalendar.newDate();
+          date.setDate(date.getDate() - 1);
+        } else if (this.langFile.parseDate && (date = this.langFile.parseDate(inputValue))) {
+          //done is parseDate
+        } else {
+          date = undefined;
+        }
+        this.calendarController.selectDate(date, true);
+        this.onCalendarChange();
+      }
+      this.changeLabel();
+    },
+
+    changeInputValue: function() {
+      this.input.value = this.dateFormat.format(this.calendarController.getSelectedDate(), this.options.lang);
+    }
+  });
+
+
+ProtoCalendar.DateFormat = Class.create();
+Object.extend(ProtoCalendar.DateFormat,
+              {
+                MONTH_ABBRS: ProtoCalendar.LangFile.en.MONTH_ABBRS,
+                MONTH_NAMES: ProtoCalendar.LangFile.en.MONTH_NAMES,
+                WEEKDAY_ABBRS: ProtoCalendar.LangFile.en.WEEKDAY_ABBRS,
+                WEEKDAY_NAMES: ProtoCalendar.LangFile.en.WEEKDAY_NAMES,
+                formatRegexp: /(?:d{3,4}i|d{1,4}|m{1,4}|yy(?:yy)?|([hHMs])\1?|TT|tt|[lL])|.+?/g,
+                zeroize: function (value, length) {
+                  if (!length) length = 2;
+                  value = String(value);
+                  for (var i = 0, zeros = ''; i < (length - value.length); i++) {
+                    zeros += '0';
+                  }
+                  return zeros + value;
+                }
+              });
+
+ProtoCalendar.DateFormat.prototype =  {
+  initialize: function(format) {
+    this.dateFormat = format;
+    this.parserInited = false;
+    this.formatterInited = false;
+  },
+
+  format: function(date, lang) {
+    if (!this.formatterInited) this.initFormatter();
+    if (!date) return '';
+    var langFile = ProtoCalendar.LangFile[lang || ProtoCalendar.LangFile.defaultLang];
+    var str = '';
+    this.formatHandlers.each(function(f) {
+                               str += f(date, langFile);
+                             });
+    return str;
+  },
+
+  initFormatter: function() {
+    var handlers = [];
+    var matches = this.dateFormat.match(ProtoCalendar.DateFormat.formatRegexp);
+    for (var i = 0, n = matches.length; i < n; i++) {
+      switch(matches[i]) {
+      case 'd':       handlers.push(function(date, lf) { return date.getDate(); }); break;
+      case 'dd':      handlers.push(function(date, lf) { return ProtoCalendar.DateFormat.zeroize(date.getDate()) }); break;
+      case 'ddd':     handlers.push(function(date, lf) { return ProtoCalendar.DateFormat.WEEKDAY_ABBRS[date.getDay()]; }); break;
+      case 'dddd':    handlers.push(function(date, lf) { return ProtoCalendar.DateFormat.WEEKDAY_NAMES[date.getDay()]; }); break;
+      case 'dddi':    handlers.push(function(date, lf) { return lf.WEEKDAY_ABBRS[date.getDay()]; }); break;
+      case 'ddddi':   handlers.push(function(date, lf) { return lf.WEEKDAY_NAMES[date.getDay()]; }); break;
+      case 'm':       handlers.push(function(date, lf) { return date.getMonth() + 1; }); break;
+      case 'mm':      handlers.push(function(date, lf) { return ProtoCalendar.DateFormat.zeroize(date.getMonth() + 1); }); break;
+      case 'mmm':     handlers.push(function(date, lf) { return lf.MONTH_ABBRS[date.getMonth()]; }); break;
+      case 'mmmm':    handlers.push(function(date, lf) { return (lf.MONTH_NAMES || ProtoCalendar.DateFormat)[date.getMonth()]; }); break;
+      case 'yy':      handlers.push(function(date, lf) { return String(date.getFullYear()).substr(2); }); break;
+      case 'yyyy':    handlers.push(function(date, lf) { return date.getFullYear(); }); break;
+      case 'h':       handlers.push(function(date, lf) { return date.getHours() % 12 || 12; }); break;
+      case 'hh':      handlers.push(function(date, lf) { return ProtoCalendar.DateFormat.zeroize(date.getHours() % 12 || 12); }); break;
+      case 'H':       handlers.push(function(date, lf) { return date.getHours(); }); break;
+      case 'HH':      handlers.push(function(date, lf) { return ProtoCalendar.DateFormat.zeroize(date.getHours()); }); break;
+      case 'M':       handlers.push(function(date, lf) { return date.getMinutes(); }); break;
+      case 'MM':      handlers.push(function(date, lf) { return ProtoCalendar.DateFormat.zeroize(date.getMinutes()); }); break;
+      case 's':       handlers.push(function(date, lf) { return date.getSeconds(); }); break;
+      case 'ss':      handlers.push(function(date, lf) { return ProtoCalendar.DateFormat.zeroize(date.getSeconds()); }); break;
+      case 'l':       handlers.push(function(date, lf) { return ProtoCalendar.DateFormat.zeroize(date.getMilliseconds(), 3); }); break;
+      case 'tt':      handlers.push(function(date, lf) { return date.getHours() < 12 ? 'am' : 'pm'; }); break;
+      case 'TT':      handlers.push(function(date, lf) { return date.getHours() < 12 ? 'AM' : 'PM'; }); break;
+      default:        handlers.push(ProtoCalendar.createIdentity(matches[i]));
+      }
+    };
+    this.formatHandlers = handlers;
+    this.formatterInited = true;
+  },
+
+  parse: function(str) {
+    if (!this.parserInited) this.initParser();
+    if (!str) return undefined;
+    var results = str.match(this.parserRegexp);
+    if (!results) return undefined;
+    var date = ProtoCalendar.newDate();
+    for (var i = 0, n = this.parseHandlers.length; i < n; i++) {
+      if (this.parseHandlers[i] != undefined) {
+        (this.parseHandlers[i])(date, results[i+1]);
+      }
+    }
+    this.parseCallback(date);
+    return date;
+  },
+
+  initParser: function() {
+    var handlers = [];
+    var regstr = '';
+    var matches = this.dateFormat.match(ProtoCalendar.DateFormat.formatRegexp);
+    var hour, ampm;
+
+    for (var i = 0, n = matches.length; i < n; i++) {
+      regstr += '(';
+      switch(matches[i]) {
+      case 'd':
+      case 'dd':      regstr += '\\d{1,2}';
+                      handlers.push(function(date, value) { date.setDate(value); });
+                      break;
+      case 'm':
+      case 'mm':      regstr += '\\d{1,2}';
+                      handlers.push(function(date, value) { 
+                                      var m = parseInt(value, 10) - 1;
+                                      date.setMonth(m); 
+                                    });
+                      break;
+//       case 'mmm':     regstr += ProtoCalendar.DateFormat.MONTH_ABBRS.join('|');
+//                       handlers.push(function(date, value) {
+//                                       date.setMonth(ProtoCalendar.DateFormat.MONTH_ABBRS.indexOf(value)); });
+//                       break;
+//       case 'mmmm':    regstr += ProtoCalendar.DateFormat.MONTH_NAMES.join('|');
+//                       handlers.push(function(date, value) {
+//                                       date.setMonth(ProtoCalendar.DateFormat.MONTH_NAMES.indexOf(value)); });
+//                       break;
+      case 'yy':      regstr += '\\d{2}';
+                      handlers.push(function(date, value) {
+                                      var year = parseInt(value, 10);
+                                      year = year < 70 ? 2000 + year : 1900 + year;
+                                      date.setFullYear(year); });
+                      break;
+      case 'yyyy':    regstr += '\\d{4}';
+                      handlers.push(function(date, value) { date.setFullYear(value); });
+                      break;
+      case 'h':
+      case 'hh':      hour = true;
+                      regstr += '\\d{1,2}';
+                      handlers.push(function(date, value) {
+                                      value = value % 12 || 0;
+                                      date.setHours(value);
+                                      });
+                      break;
+      case 'H':
+      case 'HH':      regstr += '\\d{1,2}';
+                      handlers.push(function(date, value) { date.setHours(value); });
+                      break;
+      case 'M':
+      case 'MM':      regstr += '\\d{1,2}';
+                      handlers.push(function(date, value) { date.setMinutes(value); });
+                      break;
+      case 's':
+      case 'ss':      regstr += '\\d{1,2}';
+                      handlers.push(function(date, value) { date.setSeconds(value); });
+                      break;
+      case 'l':       regstr += '\\d{1,3}';
+                      handlers.push(function(date, value) { date.setMilliSeconds(value); });
+                      break;
+      case 'tt':      regstr += 'am|pm';
+                      handlers.push(function(date, value) { ampm = value; });
+                      break;
+      case 'TT':      regstr += 'AM|PM';
+                      handlers.push(function(date, value) { ampm = value.toLowerCase(); });
+                      break;
+      case 'mmm':
+      case 'mmmm':
+      case 'ddd':
+      case 'dddd':
+      case 'dddi':
+      case 'ddddi':   regstr += '.+?';
+                      handlers.push(undefined);
+                      break;
+
+      default:        regstr += matches[i];
+                      handlers.push(undefined);
+      }
+      regstr += ')';
+    }
+    this.parserRegexp = new RegExp(regstr);
+    this.parseHandlers = handlers;
+
+    if (ampm == 'pm' && hour) {
+      this.parseCallback = this.normalizeHour.bind(this);
+    } else {
+      this.parseCallback = function() {};
+    }
+    this.parserInited = true;
+  },
+
+  normalizeHour: function(date) {
+    var hour = date.getHours();
+    hour = hour == 12 ? 0 : hour + 12;
+    date.setHours(hour);
+  }
+};
+
+ProtoCalendar.createIdentity = function(v) {
+  return function() { return v; }
+}
+
+var SelectCalendar = Class.create();
+SelectCalendar.selectTimeOption = function(select, value) {
+  var newValue = value - 0;
+  newValue = newValue < 10 ? "0" + newValue : newValue;
+  SelectCalendar.selectOption(select, newValue);
+}
+
+SelectCalendar.selectOption = function(select, value) {
+  var selectEl = $(select);
+  var options = selectEl.options;
+  for (var i = 0; i < options.length; i++) {
+    if (options[i].value === value.toString()) {
+      options[i].selected = true;
+      return;
+    }
+  }
+}
+
+SelectCalendar.createOnLoaded = function(select, options) {
+  BaseCalendar.bindOnLoad(function() { new SelectCalendar(select, options); });
+};
+Object.extend(SelectCalendar.prototype, BaseCalendar.prototype);
+Object.extend(
+  SelectCalendar.prototype,
+  {
+    initialize: function(select, options) {
+      this.yearSelect = $(select.yearSelect);
+      this.monthSelect = $(select.monthSelect);
+      this.daySelect = $(select.daySelect);
+      this.initializeOptions(options);
+      if (this.options.enableHourMinute) {
+        this.hourSelect = $(select.hourSelect);
+        this.minuteSelect = $(select.minuteSelect);
+        if (this.options.enableSecond) {
+          this.secondSelect = $(select.secondSelect);
+        }
+      }
+      this.options = Object.extend({alignTo: select.yearSelect}, this.options);
+      this.initializeBase();
+      this.initializeSelect();
+    },
+
+    initializeSelect: function() {
+      if (this.getSelectedDate()) {
+        this.onSelectChange();
+      } else {
+        this.onCalendarChange();
+      }
+    },
+
+    doObserveEvents: function() {
+      this.yearSelect.observe('change', this.onSelectChange.bind(this));
+      this.monthSelect.observe('change', this.onSelectChange.bind(this));
+      this.daySelect.observe('change', this.onSelectChange.bind(this));
+      if (this.options.enableHourMinute) {
+        this.hourSelect.observe('change', this.onSelectChange.bind(this));
+        this.minuteSelect.observe('change', this.onSelectChange.bind(this));
+        if (this.options.enableSecond) {
+          this.secondSelect.observe('change', this.onSelectChange.bind(this));
+        }
+      }
+      this.addChangeHandler(this.changeSelectValue.bind(this));
+    },
+
+    onSelectChange: function() {
+      var date = this.getSelectedDate();
+      if (!date) return;
+      this.calendarController.selectDate(date, true);
+      if (this.options.enableHourMinute) {
+        this.calendarController.calendarRender.selectTime(date);
+      }
+      this.onCalendarChange();
+    },
+
+    changeSelectValue: function() {
+      var date = this.calendarController.getSelectedDate();
+      if (date) {
+        SelectCalendar.selectOption(this.yearSelect, date.getFullYear());
+        SelectCalendar.selectOption(this.monthSelect, date.getMonth() + 1);
+        SelectCalendar.selectOption(this.daySelect, date.getDate());
+        if (this.options.enableHourMinute) {
+          SelectCalendar.selectTimeOption(this.hourSelect, date.getHours());
+          SelectCalendar.selectTimeOption(this.minuteSelect, date.getMinutes());
+          if (this.options.enableSecond) {
+            SelectCalendar.selectTimeOption(this.secondSelect, date.getSeconds());
+          }
+        }
+      }
+    },
+
+    getSelectedDate: function() {
+      if (this.yearSelect.value == '' 
+          || this.monthSelect.value == '' 
+          || this.daySelect.value == '') {
+        return undefined;
+      }
+      var d = ProtoCalendar.newDate();
+      d.setFullYear(this.yearSelect.value);
+      d.setMonth(this.monthSelect.value - 1);
+      d.setDate(this.daySelect.value);
+      if (this.options.enableHourMinute) {
+        if (this.hourSelect.value == '' || this.minuteSelect.value == '') {
+          return undefined;
+        }
+        d.setHours(this.hourSelect.value - 0);
+        d.setMinutes(this.minuteSelect.value - 0);
+        if (this.options.enableSecond) {
+          if (this.secondSelect.value == '') {
+            return undefined;
+          }
+          d.setSeconds(this.secondSelect.value - 0);
+        }
+      }
+      if (isNaN(d.getTime())) {
+        return undefined;
+      } else {
+        return d;
+      }
+    }
+  });
+
diff --git a/public/javascripts/calendar/protocalendar_min.js b/public/javascripts/calendar/protocalendar_min.js
new file mode 100644 (file)
index 0000000..2ff02a5
--- /dev/null
@@ -0,0 +1,10 @@
+/*  protocalendar.js\r
+ *  (c) 2009 Spookies\r
+ * \r
+ *  License : MIT-style license.\r
+ *  Web site: http://labs.spookies.jp/product/protocalendar\r
+ *\r
+ *  protocalendar.js - depends on prototype.js 1.6 or later\r
+ *  http://www.prototypejs.org/\r
+ */\r
+var ProtoCalendar=Class.create();ProtoCalendar.Version="1.1.8.2";ProtoCalendar.LangFile=new Object();ProtoCalendar.LangFile.en={HOUR_MINUTE_ERROR:"The time is not valid.",NO_DATE_ERROR:"No day has been selected.",OK_LABEL:"OK",DEFAULT_FORMAT:"mm/dd/yyyy",LABEL_FORMAT:"ddd mm/dd/yyyy",MONTH_ABBRS:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],MONTH_NAMES:["January","February","March","April","May","June","July","August","September","October","November","December"],YEAR_LABEL:" ",MONTH_LABEL:" ",WEEKDAY_ABBRS:["Sun","Mon","Tue","Wed","Thr","Fri","Sat"],WEEKDAY_NAMES:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],YEAR_AND_MONTH:false};ProtoCalendar.LangFile.defaultLang="en";ProtoCalendar.LangFile.defaultLangFile=function(){return ProtoCalendar.LangFile[defaultLang]};ProtoCalendar.newDate=function(){var a=new Date();a.setDate(1);return a};ProtoCalendar.withinViewport=function(c){var f=ProtoCalendar.callWithVisibility(c,function(){return c.getDimensions()});var d=f.width;var b=f.height;var e=ProtoCalendar.callWithVisibility(c,function(){return c.viewportOffset()});var a=e.left;var g=e.top;return(g>=0)&&(g+b<=document.viewport.getHeight())};ProtoCalendar.callWithVisibility=function(d,f){d=$(d);var h=$(d).getStyle("display");if(h!="none"&&h!=null){return f()}var c=d.style;var g=c.visibility;var e=c.position;var b=c.display;c.visibility="hidden";c.position="absolute";c.display="block";var a=f();c.display=b;c.position=e;c.visibility=g;return a};Object.extend(ProtoCalendar,{JAN:0,FEB:1,MAR:2,APR:3,MAY:4,JUNE:5,JULY:6,AUG:7,SEPT:8,OCT:9,NOV:10,DEC:11,SUNDAY:0,MONDAY:1,TUESDAY:2,WEDNESDAY:3,THURSDAY:4,FRIDAY:5,SATURDAY:6,getNumDayOfMonth:function(a,b){return 32-new Date(a,b,32).getDate()},getDayOfWeek:function(b,c,a){return new Date(b,c,a).getDay()}});ProtoCalendar.prototype={initialize:function(c){var b=ProtoCalendar.newDate();this.options=Object.extend({month:b.getMonth(),year:b.getFullYear(),lang:ProtoCalendar.LangFile.defaultLang},c||{});var a=ProtoCalendar.LangFile[this.options.lang]["getHolidays"];if(a){this.initializeHolidays=a.bind(top,this)}else{this.initializeHolidays=function(){this.holidays=[]}}this.date=new Date(this.options.year,this.options.month,1)},getMonth:function(){return this.date.getMonth()},getYear:function(){return this.date.getFullYear()},invalidate:function(){this.holidays=undefined},setMonth:function(a){if(a!=this.getMonth()){this.invalidate()}return this.date.setMonth(a)},setYear:function(a){if(a!=this.getYear()){this.invalidate()}return this.date.setFullYear(a)},getDate:function(){return this.date},setDate:function(a){this.invalidate();this.date=a},setYearByOffset:function(a){if(a!=0){this.invalidate()}this.date.setFullYear(this.date.getFullYear()+a)},setMonthByOffset:function(a){if(a!=0){this.invalidate()}this.date.setMonth(this.date.getMonth()+a)},getNumDayOfMonth:function(){return ProtoCalendar.getNumDayOfMonth(this.getYear(),this.getMonth())},getDayOfWeek:function(a){return ProtoCalendar.getDayOfWeek(this.getYear(),this.getMonth(),a)},clone:function(){return new ProtoCalendar({year:this.getYear(),month:this.getMonth()})},getHoliday:function(a){if(!this.holidays){this.initializeHolidays()}var b=this.holidays[a];return b?b:false},initializeHolidays:function(){}};var AbstractProtoCalendarRender=Class.create();Object.extend(AbstractProtoCalendarRender,{id:1,WEEK_DAYS_SUNDAY:[0,1,2,3,4,5,6],WEEK_DAYS_MONDAY:[1,2,3,4,5,6,0],WEEK_DAYS_INDEX_SUNDAY:[0,1,2,3,4,5,6],WEEK_DAYS_INDEX_MONDAY:[6,0,1,2,3,4,5],getId:function(){var a=AbstractProtoCalendarRender.id;AbstractProtoCalendarRender.id+=1;return a}});AbstractProtoCalendarRender.prototype={initialize:function(a){this.id=AbstractProtoCalendarRender.getId();this.options=Object.extend({weekFirstDay:ProtoCalendar.MONDAY,containerClass:"cal-container",tableClass:"cal-table",headerTopClass:"cal-header-top",headerClass:"cal-header",headerBottomClass:"cal-header-bottom",bodyTopClass:"cal-body-top",bodyClass:"cal-body",bodyBottomClass:"cal-body-bottom",bodyId:this.getIdPrefix()+"-body",footerTopClass:"cal-footer-top",footerClass:"cal-footer",footerBottomClass:"cal-footer-bottom",footerId:this.getIdPrefix()+"-footer",yearSelectClass:"cal-select-year",yearSelectId:this.getIdPrefix()+"-select-year",monthSelectClass:"cal-select-month",monthSelectId:this.getIdPrefix()+"-select-month",borderClass:"cal-border",hourMinuteInputClass:"cal-input-hour-minute",hourMinuteInputId:this.getIdPrefix()+"-input-hour-minute",hourInputClass:"cal-input-hour",hourInputId:this.getIdPrefix()+"-input-hour",minuteInputClass:"cal-input-minute",minuteInputId:this.getIdPrefix()+"-input-minute",secondInputClass:"cal-input-second",secondInputId:this.getIdPrefix()+"-input-second",okButtonClass:"cal-ok-button",okButtonId:this.getIdPrefix()+"-ok-button",errorDivClass:"cal-error-list",errorDivId:this.getIdPrefix()+"-error-list",labelRowClass:"cal-label-row",labelCellClass:"cal-label-cell",nextButtonClass:"cal-next-btn",prevButtonClass:"cal-prev-btn",dayCellClass:"cal-day-cell",dayClass:"cal-day",weekdayClass:"cal-weekday",sundayClass:"cal-sunday",saturdayClass:"cal-saturday",holidayClass:"cal-holiday",otherdayClass:"cal-otherday",disabledDayClass:"cal-disabled",selectedDayClass:"cal-selected",nextBtnId:this.getIdPrefix()+"-next-btn",prevBtnId:this.getIdPrefix()+"-prev-btn",lang:ProtoCalendar.LangFile.defaultLang,showEffect:"Appear",hideEffect:"Fade",ifInvisible:"Flip",scrollMargin:20},a||{});this.langFile=ProtoCalendar.LangFile[this.options.lang];this.weekFirstDay=this.options.weekFirstDay;this.initWeekData();this.container=this.createContainer();this.alignTo=$(this.options.alignTo);this.alignOrient="Below";if(navigator.appVersion.match(/\bMSIE\b/)){this.iframe=this.createIframe()}this.resizeHandler=this.setPosition.bind(this)},createContainer:function(){var a=$(document.createElement("div"));a.addClassName(this.options.containerClass);a.setStyle({position:"absolute",top:"0px",left:"0px",zindex:1,display:"none"});a.hide();document.body.appendChild(a);return a},createIframe:function(){var a=document.createElement("iframe");a.setAttribute("src","javascript:false;");a.setAttribute("frameBorder","0");a.setAttribute("scrolling","no");Element.setStyle(a,{position:"absolute",top:"0px",left:"0px",zindex:10,display:"none",overflow:"hidden",filter:"progid:DXImageTransform.Microsoft.Alpha(opacity=0)"});document.body.appendChild(a);return $(a)},getWeekdayLabel:function(a){return this.langFile.WEEKDAY_ABBRS[a]},getWeekdays:function(){return this.weekdays},initWeekData:function(){if(this.weekFirstDay==ProtoCalendar.SUNDAY){this.weekLastDay=ProtoCalendar.SATURDAY;this.weekdays=AbstractProtoCalendarRender.WEEK_DAYS_SUNDAY;this.weekdaysIndex=AbstractProtoCalendarRender.WEEK_DAYS_INDEX_SUNDAY}else{this.weekFirstDay==ProtoCalendar.MONDAY;this.weekLastDay=ProtoCalendar.SUNDAY;this.weekdays=AbstractProtoCalendarRender.WEEK_DAYS_MONDAY;this.weekdaysIndex=AbstractProtoCalendarRender.WEEK_DAYS_INDEX_MONDAY}},getCalendarBeginDay:function(b){var c=this.getDayIndexOfWeek(b,1);var a=new Date(b.getYear(),b.getMonth(),1-c);return a},getCalendarEndDay:function(c){var a=c.getNumDayOfMonth();var d=6-this.getDayIndexOfWeek(c,a);var b=new Date(c.getYear(),c.getMonth(),a+d+1);return b},getDayIndexOfWeek:function(b,a){return this.weekdaysIndex[b.getDayOfWeek(a)]},getIdPrefix:function(){return"cal"+this.id},getDayDivId:function(a){return this.getIdPrefix()+"-year"+a.getFullYear()+"-month"+a.getMonth()+"-day"+a.getDate()},setPosition:function(){if(!this.alignTo){return true}this.setAlignment(this.alignTo,this.container,this.alignOrient);var b=ProtoCalendar.withinViewport(this.container);if(!b&&this.options.ifInvisible=="Flip"){this.alignOrient=(this.alignOrient=="Above"?"Below":"Above");this.setAlignment(this.alignTo,this.container,this.alignOrient)}if(this.iframe){var a=Element.getDimensions(this.container);this.iframe.setAttribute("width",a.width);this.iframe.setAttribute("height",a.height);this.setAlignment(this.alignTo,this.iframe,this.alignOrient)}if(this.options.ifInvisible=="Scroll"){this.scrollIfInvisible()}return true},setAlignment:function(d,a,e){var c=Position.cumulativeOffset(d);a.setStyle({left:c[0]+"px"});if(e=="Above"){var b=ProtoCalendar.callWithVisibility(a,function(){return a.offsetHeight});a.setStyle({top:(c[1]-b)+"px"})}else{if(e=="Below"){a.setStyle({top:(c[1]+d.offsetHeight)+"px"})}else{}}},show:function(b){Event.observe(window,"resize",this.resizeHandler);this.setPosition();if(typeof Effect!="undefined"){var a=this.options.showEffect||"Appear";if(!this._effect||this._effect.state=="finished"){this._effect=new Effect[a](this.container,{duration:0.5})}}else{this.container.show()}if(this.iframe){this.iframe.show()}},scrollIfInvisible:function(){var c=this.container;var f=ProtoCalendar.callWithVisibility(c,function(){return c.getDimensions()});var d=f.width;var b=f.height;var e=ProtoCalendar.callWithVisibility(c,function(){return c.viewportOffset()});var a=e.left;var h=e.top;var g=h+b-document.viewport.getHeight();if(g>0){window.scrollBy(0,g+this.options.scrollMargin)}},hide:function(b){Event.stopObserving(window,"resize",this.resizeHandler);if(!this.container.visible()){return}if(typeof Effect!="undefined"){var a=this.options.hideEffect||"Fade";if(!this._effect||this._effect.state=="finished"){this._effect=new Effect[a](this.container,{duration:0.3})}}else{this.container.hide()}if(this.iframe){this.iframe.hide()}},hideImmediately:function(a){if(!this.container.visible()){return}this.container.hide();if(this.iframe){this.iframe.hide()}},toggle:function(a){this.container.visible()?this.hide():this.show()},render:function(a){},rerender:function(a){},getContainer:function(){return this.container},getPrevButton:function(){return $(this.options.prevBtnId)},getNextButton:function(){return $(this.options.nextBtnId)},getYearSelect:function(){return $(this.options.yearSelectId)},getMonthSelect:function(){return $(this.options.monthSelectId)},getHourInput:function(){return $(this.options.hourInputId)},getMinuteInput:function(){return $(this.options.minuteInputId)},getSecondInput:function(){return $(this.options.secondInputId)},getOkButton:function(){return $(this.options.okButtonId)},getBody:function(){return $(this.options.bodyId)},getDayDivs:function(){var b=[];var a=this.dayDivs;for(var c=0;c<a.length;c++){b.push(document.getElementById(a[c]))}return b},getDateFromEl:function(b){var a=$(b);return new Date(a.readAttribute("year"),a.readAttribute("month"),a.readAttribute("day"))},injectHourMinute:function(a){if(!a||isNaN(a.getTime())){return undefined}var b=new Date(a.getFullYear(),a.getMonth(),a.getDate());b.setHours(parseInt(this.getHourInput().value,10));b.setMinutes(this.getMinuteInput().value);if(this.options.enableSecond){b.setSeconds(this.getSecondInput().value)}return isNaN(b.getTime())?undefined:b},selectDate:function(a){var b=$(this.getDayDivId(a));if(b){b.addClassName(this.options.selectedDayClass)}},selectTime:function(a){if(!a){return}this.getHourInput().value=a.getHours();this.getMinuteInput().value=a.getMinutes();if(this.options.enableSecond){this.getSecondInput().value=a.getSeconds()}},deselectDate:function(b){if(b){var a=$(this.getDayDivId(b));if(a){a.removeClassName(this.options.selectedDayClass)}}},evaluateWithOptions:function(a){var b=new Template(a);return b.evaluate(this.options)},defaultOnError:function(a){this.ensureErrorDiv();this.errorDiv.show();this.errorDiv.innerHTML+="<li>"+this.langFile[a]+"</li>"},hideError:function(){this.ensureErrorDiv();this.errorDiv.innerHTML="";this.errorDiv.hide()},ensureErrorDiv:function(){if(!this.errorDiv){var a='<div class="#{errorDivClass}" id="#{errorDivId}"><ul></ul></div>';new Insertion.Before($(this.options.footerId),this.evaluateWithOptions(a));this.errorDiv=$(this.options.errorDivId)}},isSelectable:function(a){return(this.options.minDate-a)<=0&&(a-this.options.maxDate)<=0}};var ProtoCalendarRender=Class.create();Object.extend(ProtoCalendarRender.prototype,AbstractProtoCalendarRender.prototype);Object.extend(ProtoCalendarRender.prototype,{render:function(b){var a="";a+=this.renderHeader(b);a+='<div class="#{bodyTopClass}"></div><div class="#{bodyClass}" id="#{bodyId}">';a+='</div><div class="#{bodyBottomClass}"></div>';if(this.options.enableHourMinute){a+=this.renderHourMinute()}a+=this.renderFooter(b);this.container.innerHTML=this.evaluateWithOptions(a);this.rerender(b)},rerender:function(a){this.getBody().innerHTML=this.evaluateWithOptions(this.renderBody(a));SelectCalendar.selectOption(this.getMonthSelect(),a.getMonth());SelectCalendar.selectOption(this.getYearSelect(),a.getYear());if(this.container.visible()){this.setPosition()}},renderHeader:function(b){var a="";a+='<div class="#{headerTopClass}"></div><div class="#{headerClass}"><a href="#" id="#{prevBtnId}" class="#{prevButtonClass}">&lt;&lt;</a>'+this.createSelect(b.getYear(),b.getMonth())+'<a href="#" id="#{nextBtnId}" class="#{nextButtonClass}">&gt;&gt;</a></div><div class="#{headerBottomClass}"></div>';return a},renderFooter:function(a){return'<div class="#{footerTopClass}"></div><div class="#{footerClass}" id="#{footerId}"></div><div class="#{footerBottomClass}"></div>'},renderHourMinute:function(){if(!this.hourMinuteHtml){var a='<div class="#{borderClass}"></div><div id="#{hourMinuteInputId}" class="#{hourMinuteInputClass}">';a+='<input type="text" name="hour" size="2" maxlength="2" class="#{hourInputClass}" id="#{hourInputId}" />:<input type="text" name="minute" size="2" maxlength="2" class="#{minuteInputClass}" id="#{minuteInputId}" />';if(this.options.enableSecond){a+=':<input type="text" name="second" size="2" maxlength="2" class="#{secondInputClass}" id="#{secondInputId}"/>'}a+='<input type="button" value="'+this.langFile.OK_LABEL+'" class="#{okButtonClass}" name="ok_button" id="#{okButtonId}"/>';a+="</div>";this.hourMinuteHtml=a}return this.hourMinuteHtml},createSelect:function(c,d){var b=this.createYearSelect(c)+this.langFile.YEAR_LABEL;var a=this.createMonthSelect(d)+this.langFile.MONTH_LABEL;if(this.langFile.YEAR_AND_MONTH){return b+a}else{return a+b}},createYearSelect:function(b){var a="";a+='<select id="#{yearSelectId}" class="#{yearSelectClass}">';for(var d=this.options.startYear,c=this.options.endYear;d<=c;d+=1){a+='<option value="'+d+'"'+(d==b?" selected":"")+">"+d+"</option>"}a+="</select>";return a},createMonthSelect:function(c){if(!this.monthSelectHtml){var b="";b+='<select id="#{monthSelectId}" class="#{monthSelectClass}">';for(var a=ProtoCalendar.JAN;a<=ProtoCalendar.DEC;a+=1){b+='<option value="'+a+'"'+(a==c?" selected":"")+">"+this.langFile.MONTH_ABBRS[a]+"</option>"}b+="</select>";this.monthSelectHtml=b}return this.monthSelectHtml},renderBody:function(g){this.dayDivs=[];var j='<table class="#{tableClass}" cellspacing="0">';j+='<tr class="#{labelRowClass}">';var b=this;if(!this.headHtml){this.headHtml="";$A(this.getWeekdays()).each(function(m){var i="";if(m==ProtoCalendar.SUNDAY){i=" #{sundayClass}"}if(m==ProtoCalendar.SATURDAY){i=" #{saturdayClass}"}b.headHtml+='<th class="#{labelCellClass}'+i+'">'+b.getWeekdayLabel(m)+"</th>"})}j+=this.headHtml;var e=this.getCalendarBeginDay(g);var a=this.getCalendarEndDay(g);j+="<tbody>";var c=Math.round((a-e)/1000/60/60/24);for(var h=0;h<c;h+=1,e.setDate(e.getDate()+1)){var k;var f=g.getHoliday(e.getDate());if(e.getMonth()!=g.getMonth()){k=this.options.otherdayClass}else{if(f){k=this.options.holidayClass}else{if(e.getDay()==ProtoCalendar.SUNDAY){k=this.options.sundayClass}else{if(e.getDay()==ProtoCalendar.SATURDAY){k=this.options.saturdayClass}else{k=this.options.weekdayClass}}}}if(e.getDay()==this.weekFirstDay){j+="<tr>"}var l=this.getDayDivId(e);var d="";if(this.isSelectable(e)){d='<a class="#{dayClass}" href="#" id="'+l+(f?'" title="'+f:"")+'" year="'+e.getFullYear()+'" month="'+e.getMonth()+'" day="'+e.getDate()+'">'+e.getDate()+"</a>";this.dayDivs.push(l)}else{k+=" "+this.options.disabledDayClass;d=e.getDate()}j+='<td class="'+k+' #{dayCellClass}">'+d+"</td>";if(e.getDay()==this.weekLastDay){j+="</tr>"}}j+="</tbody></table>";return j}});var ProtoCalendarController=Class.create();ProtoCalendarController.prototype={initialize:function(c,b){this.options=Object.extend({onHourMinuteError:this.defaultOnHourMinuteError.bind(this),onNoDateError:this.defaultOnNoDateError.bind(this)},b);this.calendarRender=c;this.initializeDate();this.calendar=new ProtoCalendar(this.options);this.calendarRender.render(this.calendar);if(b.year&&b.month&&b.day){var a=new Date(this.options.year,this.options.month,this.options.day);if(b.hour&&b.minute&&b.second){a.setHours(b.hour,b.minute&&b.second)}this.selectDate(a,true)}else{this.selectDate(null)}this.observeEventsOnce();this.observeEvents();this.onChangeHandlers=[]},initializeDate:function(){var a=ProtoCalendar.newDate();if(!this.options.year){if(a.getFullYear()>=this.options.startYear&&a.getFullYear()<=this.options.endYear){this.options.year=a.getFullYear()}else{this.options.year=this.options.startYear}}if(!this.options.month){this.options.month=a.getMonth()}if(!this.options.day){this.options.day=a.getDate()}},observeEventsOnce:function(){var g=this.calendarRender;g.getPrevButton().observe("click",this.showPrevMonth.bindAsEventListener(this));g.getNextButton().observe("click",this.showNextMonth.bindAsEventListener(this));var c=this;var i=g.getYearSelect();var d=g.getMonthSelect();var j=this.calendar.getYear();var h=this.calendar.getMonth();i.observe("change",function(){c.setMonth(parseInt(i[i.selectedIndex].value,10),parseInt(d[d.selectedIndex].value,10))});d.observe("change",function(){c.setMonth(parseInt(i[i.selectedIndex].value,10),parseInt(d[d.selectedIndex].value,10))});if(this.options.enableHourMinute){var f=g.getHourInput();var e=g.getMinuteInput();f.observe("keyup",this._autoFocus.bindAsEventListener(f,e));f.observe("keydown",this._disablePaste.bindAsEventListener(f));f.observe("contextmenu",this._disableContextMenu.bindAsEventListener(f));var b=this.options.enableSecond?g.getSecondInput():g.getOkButton();e.observe("keyup",this._autoFocus.bindAsEventListener(e,b));e.observe("keydown",this._disablePaste.bindAsEventListener(e));e.observe("contextmenu",this._disableContextMenu.bindAsEventListener(e));if(navigator.appVersion.match(/\bMSIE\b/)){f.setStyle({imeMode:"disabled"});e.setStyle({imeMode:"disabled"})}}if(this.options.enableSecond){var a=g.getSecondInput();a.observe("keyup",this._autoFocus.bindAsEventListener(a,g.getOkButton()));a.observe("keydown",this._disablePaste.bindAsEventListener(a));a.observe("contextmenu",this._disableContextMenu.bindAsEventListener(a));if(navigator.appVersion.match(/\bMSIE\b/)){a.setStyle({imeMode:"disabled"})}}if(this.options.enableHourMinute){g.getOkButton().observe("click",this.onSubmit.bind(this))}},_disableContextMenu:function(a){Event.stop(a);return false},_disablePaste:function(a){if((a.keyCode==86&&a.ctrlKey)||(a.keyCode==45&&a.shiftKey)){Event.stop(a);return false}},_autoFocus:function(c,a){if(c.keyCode==16||c.keyCode==9||(c.keyCode==9&&c.shiftKey)){Event.stop(c);return false}var b=this.value;if(b.length&&b.length==2){a.focus();a.select()}return true},observeEvents:function(){var a=this;this.calendarRender.getDayDivs().each(function(b){Event.observe(b,"click",a.onClickHandler.bindAsEventListener(a))})},onClickHandler:function(b){Event.stop(b);var a=this.calendarRender.getDateFromEl(Event.element(b));if(a){this.selectDate(a);if(!this.options.enableHourMinute){this.onChangeHandler();setTimeout(this.hideCalendar.bind(this),150)}}},onSubmit:function(){this.hideError();var a=this.selectedDate;if(!a){return this.options.onNoDateError()}a=this.calendarRender.injectHourMinute(a);if(!a){this.options.onHourMinuteError()}else{this.selectDate(a,true);if(this.options.enableHourMinute){this.calendarRender.selectTime(a)}this.onChangeHandler();this.hideCalendar()}},selectDate:function(a,b){this.calendarRender.deselectDate(this.selectedDate);this.selectedDate=a;if(!a){return}if(b&&(a.getFullYear()!=this.calendar.getYear()||a.getMonth()!=this.calendar.getMonth())){this.setMonth(a.getFullYear(),a.getMonth())}this.calendarRender.selectDate(this.selectedDate)},getSelectedDate:function(){return this.selectedDate},addChangeHandler:function(a){this.onChangeHandlers.push(a)},onChangeHandler:function(){this.onChangeHandlers.each(function(a){a()})},showCalendar:function(){this.calendarRender.show()},hideCalendar:function(){this.calendarRender.hide()},blurCalendar:function(a){if(a.keyCode==9){this.hideImmediatelyCalendar()}},hideImmediatelyCalendar:function(){this.calendarRender.hideImmediately()},toggleCalendar:function(){this.calendarRender.toggle()},showPrevMonth:function(a){this.shiftMonthByOffset(-1);if(a){Event.stop(a)}},showNextMonth:function(a){this.shiftMonthByOffset(1);if(a){Event.stop(a)}},shiftMonthByOffset:function(b){if(b==0){return}var a=new Date(this.calendar.getDate().getTime());a.setMonth(a.getMonth()+b);if(this.options.startYear>a.getFullYear()||this.options.endYear<a.getFullYear()){return}this.calendar.setMonthByOffset(b);this.afterSet()},setMonth:function(a,b){if(this.calendar.getYear()==a&&this.calendar.getMonth()==b){return}this.calendar.setYear(a);this.calendar.setMonth(b);this.afterSet()},afterSet:function(){this.calendarRender.rerender(this.calendar);this.selectDate(this.selectedDate);this.observeEvents()},getContainer:function(){return this.calendarRender.getContainer()},defaultOnHourMinuteError:function(){this.calendarRender.defaultOnError("HOUR_MINUTE_ERROR")},defaultOnNoDateError:function(){this.calendarRender.defaultOnError("NO_DATE_ERROR")},hideError:function(){this.calendarRender.hideError()}};var BaseCalendar=Class.create();BaseCalendar.bindOnLoad=function(a){if(document.observe){document.observe("dom:loaded",a)}else{Event.observe(window,"load",a)}};BaseCalendar.prototype={initialize:function(a){throw"Cannot instantiate BaseCalendar."},initializeOptions:function(a){if(!a){a={}}this.options=Object.extend({startYear:ProtoCalendar.newDate().getFullYear()-10,endYear:ProtoCalendar.newDate().getFullYear()+10,minDate:new Date(1900,0,1),maxDate:new Date(3000,0,1),format:ProtoCalendar.LangFile[a.lang||ProtoCalendar.LangFile.defaultLang]["DEFAULT_FORMAT"],enableHourMinute:false,enableSecond:false,lang:ProtoCalendar.LangFile.defaultLang,triggers:[]},a)},initializeBase:function(){this.calendarController=new ProtoCalendarController(new ProtoCalendarRender(this.options),this.options);this.langFile=ProtoCalendar.LangFile[this.options.lang]||ProtoCalendar.LangFile.defaultLangFile();this.triggers=[];this.options.triggers.each(this.addTrigger.bind(this));this.changeHandlers=[];this.observeEvents()},addTrigger:function(a){this.triggers.push($(a));$(a).setStyle({cursor:"pointer"})},observeEvents:function(){Event.observe(document.body,"click",this.windowClickHandler.bindAsEventListener(this));this.calendarController.addChangeHandler(this.onCalendarChange.bind(this));this.doObserveEvents()},doObserveEvents:function(){},windowClickHandler:function(a){var b=$(Event.element(a));if(this.triggers.include(b)){this.calendarController.toggleCalendar()}else{if(b!=this.input&&!Element.descendantOf(b,this.calendarController.getContainer())){this.calendarController.hideCalendar()}}},addChangeHandler:function(a){this.changeHandlers.push(a)},onCalendarChange:function(){this.changeHandlers.each(function(a){a()})}};var InputCalendar=Class.create();InputCalendar.createOnLoaded=function(a,b){BaseCalendar.bindOnLoad(function(){new InputCalendar(a,b)})};InputCalendar.initCalendars=function(a,b){if(document.observe){document.observe("dom:loaded",function(){$$(a).each(function(c){new InputCalendar(c,b)})})}else{Event.observe(window,"load",function(){$$(a).each(function(c){new InputCalendar(c,b)})})}};Object.extend(InputCalendar.prototype,BaseCalendar.prototype);Object.extend(InputCalendar.prototype,{initialize:function(a,b){this.input=$(a);this.initializeOptions(b);this.options=Object.extend({alignTo:a,inputReadOnly:false,labelFormat:undefined,labelEl:undefined},this.options);this.initializeBase();this.initializeInput();this.initializeLabel()},initializeInput:function(){this.dateFormat=new ProtoCalendar.DateFormat(this.options.format);if(this.input.value&&this.dateFormat.parse(this.input.value)){this.onInputChange()}else{this.onCalendarChange()}if(this.options.enableHourMinute){this.calendarController.calendarRender.selectTime(this.calendarController.selectedDate)}if(this.options.inputReadOnly){this.input.setAttribute("readOnly",this.options.inputReadOnly)}},initializeLabel:function(){this.labelFormat=new ProtoCalendar.DateFormat(this.options.labelFormat||this.langFile.LABEL_FORMAT);var b=$(this.options.labelEl);if((!b)&&this.options.labelFormat){var a=this.input.id+"_label";new Insertion.After(this.input,"<div id='"+a+"'></div>");b=$(a)}this.labelEl=b;this.changeLabel()},changeLabel:function(){if(!this.labelEl){return}if(this.calendarController.getSelectedDate()){this.labelEl.innerHTML=this.labelFormat.format(this.calendarController.getSelectedDate(),this.options.lang)}},doObserveEvents:function(){this.input.observe("change",this.onInputChange.bind(this));this.input.observe("focus",this.calendarController.showCalendar.bind(this.calendarController));this.input.observe("keydown",this.calendarController.blurCalendar.bindAsEventListener(this.calendarController));this.addChangeHandler(this.changeInputValue.bind(this));this.addChangeHandler(this.changeLabel.bind(this))},onInputChange:function(){var b=this.dateFormat.parse(this.input.value);if(b){this.calendarController.selectDate(b,true);if(this.options.enableHourMinute){this.calendarController.calendarRender.selectTime(b)}}else{var a=this.input.value.toLowerCase();var b;if(this.langFile.today&&this.langFile.today==a||a=="today"){b=ProtoCalendar.newDate()}else{if(this.langFile.tomorrow&&this.langFile.tomorrow==a||a=="tomorrow"){b=ProtoCalendar.newDate();b.setDate(b.getDate()+1)}else{if(this.langFile.yesterday&&this.langFile.yesterday==a||a=="yesterday"){b=ProtoCalendar.newDate();b.setDate(b.getDate()-1)}else{if(this.langFile.parseDate&&(b=this.langFile.parseDate(a))){}else{b=undefined}}}}this.calendarController.selectDate(b,true);this.onCalendarChange()}this.changeLabel()},changeInputValue:function(){this.input.value=this.dateFormat.format(this.calendarController.getSelectedDate(),this.options.lang)}});ProtoCalendar.DateFormat=Class.create();Object.extend(ProtoCalendar.DateFormat,{MONTH_ABBRS:ProtoCalendar.LangFile.en.MONTH_ABBRS,MONTH_NAMES:ProtoCalendar.LangFile.en.MONTH_NAMES,WEEKDAY_ABBRS:ProtoCalendar.LangFile.en.WEEKDAY_ABBRS,WEEKDAY_NAMES:ProtoCalendar.LangFile.en.WEEKDAY_NAMES,formatRegexp:/(?:d{3,4}i|d{1,4}|m{1,4}|yy(?:yy)?|([hHMs])\1?|TT|tt|[lL])|.+?/g,zeroize:function(d,c){if(!c){c=2}d=String(d);for(var b=0,a="";b<(c-d.length);b++){a+="0"}return a+d}});ProtoCalendar.DateFormat.prototype={initialize:function(a){this.dateFormat=a;this.parserInited=false;this.formatterInited=false},format:function(a,d){if(!this.formatterInited){this.initFormatter()}if(!a){return""}var b=ProtoCalendar.LangFile[d||ProtoCalendar.LangFile.defaultLang];var c="";this.formatHandlers.each(function(e){c+=e(a,b)});return c},initFormatter:function(){var a=[];var c=this.dateFormat.match(ProtoCalendar.DateFormat.formatRegexp);for(var b=0,d=c.length;b<d;b++){switch(c[b]){case"d":a.push(function(f,e){return f.getDate()});break;case"dd":a.push(function(f,e){return ProtoCalendar.DateFormat.zeroize(f.getDate())});break;case"ddd":a.push(function(f,e){return ProtoCalendar.DateFormat.WEEKDAY_ABBRS[f.getDay()]});break;case"dddd":a.push(function(f,e){return ProtoCalendar.DateFormat.WEEKDAY_NAMES[f.getDay()]});break;case"dddi":a.push(function(f,e){return e.WEEKDAY_ABBRS[f.getDay()]});break;case"ddddi":a.push(function(f,e){return e.WEEKDAY_NAMES[f.getDay()]});break;case"m":a.push(function(f,e){return f.getMonth()+1});break;case"mm":a.push(function(f,e){return ProtoCalendar.DateFormat.zeroize(f.getMonth()+1)});break;case"mmm":a.push(function(f,e){return e.MONTH_ABBRS[f.getMonth()]});break;case"mmmm":a.push(function(f,e){return(e.MONTH_NAMES||ProtoCalendar.DateFormat)[f.getMonth()]});break;case"yy":a.push(function(f,e){return String(f.getFullYear()).substr(2)});break;case"yyyy":a.push(function(f,e){return f.getFullYear()});break;case"h":a.push(function(f,e){return f.getHours()%12||12});break;case"hh":a.push(function(f,e){return ProtoCalendar.DateFormat.zeroize(f.getHours()%12||12)});break;case"H":a.push(function(f,e){return f.getHours()});break;case"HH":a.push(function(f,e){return ProtoCalendar.DateFormat.zeroize(f.getHours())});break;case"M":a.push(function(f,e){return f.getMinutes()});break;case"MM":a.push(function(f,e){return ProtoCalendar.DateFormat.zeroize(f.getMinutes())});break;case"s":a.push(function(f,e){return f.getSeconds()});break;case"ss":a.push(function(f,e){return ProtoCalendar.DateFormat.zeroize(f.getSeconds())});break;case"l":a.push(function(f,e){return ProtoCalendar.DateFormat.zeroize(f.getMilliseconds(),3)});break;case"tt":a.push(function(f,e){return f.getHours()<12?"am":"pm"});break;case"TT":a.push(function(f,e){return f.getHours()<12?"AM":"PM"});break;default:a.push(ProtoCalendar.createIdentity(c[b]))}}this.formatHandlers=a;this.formatterInited=true},parse:function(d){if(!this.parserInited){this.initParser()}if(!d){return undefined}var c=d.match(this.parserRegexp);if(!c){return undefined}var a=ProtoCalendar.newDate();for(var b=0,e=this.parseHandlers.length;b<e;b++){if(this.parseHandlers[b]!=undefined){(this.parseHandlers[b])(a,c[b+1])}}this.parseCallback(a);return a},initParser:function(){var b=[];var f="";var e=this.dateFormat.match(ProtoCalendar.DateFormat.formatRegexp);var a,c;for(var d=0,g=e.length;d<g;d++){f+="(";switch(e[d]){case"d":case"dd":f+="\\d{1,2}";b.push(function(h,i){h.setDate(i)});break;case"m":case"mm":f+="\\d{1,2}";b.push(function(i,j){var h=parseInt(j,10)-1;i.setMonth(h)});break;case"yy":f+="\\d{2}";b.push(function(h,j){var i=parseInt(j,10);i=i<70?2000+i:1900+i;h.setFullYear(i)});break;case"yyyy":f+="\\d{4}";b.push(function(h,i){h.setFullYear(i)});break;case"h":case"hh":a=true;f+="\\d{1,2}";b.push(function(h,i){i=i%12||0;h.setHours(i)});break;case"H":case"HH":f+="\\d{1,2}";b.push(function(h,i){h.setHours(i)});break;case"M":case"MM":f+="\\d{1,2}";b.push(function(h,i){h.setMinutes(i)});break;case"s":case"ss":f+="\\d{1,2}";b.push(function(h,i){h.setSeconds(i)});break;case"l":f+="\\d{1,3}";b.push(function(h,i){h.setMilliSeconds(i)});break;case"tt":f+="am|pm";b.push(function(h,i){c=i});break;case"TT":f+="AM|PM";b.push(function(h,i){c=i.toLowerCase()});break;case"mmm":case"mmmm":case"ddd":case"dddd":case"dddi":case"ddddi":f+=".+?";b.push(undefined);break;default:f+=e[d];b.push(undefined)}f+=")"}this.parserRegexp=new RegExp(f);this.parseHandlers=b;if(c=="pm"&&a){this.parseCallback=this.normalizeHour.bind(this)}else{this.parseCallback=function(){}}this.parserInited=true},normalizeHour:function(b){var a=b.getHours();a=a==12?0:a+12;b.setHours(a)}};ProtoCalendar.createIdentity=function(a){return function(){return a}};var SelectCalendar=Class.create();SelectCalendar.selectTimeOption=function(a,b){var c=b-0;c=c<10?"0"+c:c;SelectCalendar.selectOption(a,c)};SelectCalendar.selectOption=function(a,d){var e=$(a);var b=e.options;for(var c=0;c<b.length;c++){if(b[c].value===d.toString()){b[c].selected=true;return}}};SelectCalendar.createOnLoaded=function(a,b){BaseCalendar.bindOnLoad(function(){new SelectCalendar(a,b)})};Object.extend(SelectCalendar.prototype,BaseCalendar.prototype);Object.extend(SelectCalendar.prototype,{initialize:function(a,b){this.yearSelect=$(a.yearSelect);this.monthSelect=$(a.monthSelect);this.daySelect=$(a.daySelect);this.initializeOptions(b);if(this.options.enableHourMinute){this.hourSelect=$(a.hourSelect);this.minuteSelect=$(a.minuteSelect);if(this.options.enableSecond){this.secondSelect=$(a.secondSelect)}}this.options=Object.extend({alignTo:a.yearSelect},this.options);this.initializeBase();this.initializeSelect()},initializeSelect:function(){if(this.getSelectedDate()){this.onSelectChange()}else{this.onCalendarChange()}},doObserveEvents:function(){this.yearSelect.observe("change",this.onSelectChange.bind(this));this.monthSelect.observe("change",this.onSelectChange.bind(this));this.daySelect.observe("change",this.onSelectChange.bind(this));if(this.options.enableHourMinute){this.hourSelect.observe("change",this.onSelectChange.bind(this));this.minuteSelect.observe("change",this.onSelectChange.bind(this));if(this.options.enableSecond){this.secondSelect.observe("change",this.onSelectChange.bind(this))}}this.addChangeHandler(this.changeSelectValue.bind(this))},onSelectChange:function(){var a=this.getSelectedDate();if(!a){return}this.calendarController.selectDate(a,true);if(this.options.enableHourMinute){this.calendarController.calendarRender.selectTime(a)}this.onCalendarChange()},changeSelectValue:function(){var a=this.calendarController.getSelectedDate();if(a){SelectCalendar.selectOption(this.yearSelect,a.getFullYear());SelectCalendar.selectOption(this.monthSelect,a.getMonth()+1);SelectCalendar.selectOption(this.daySelect,a.getDate());if(this.options.enableHourMinute){SelectCalendar.selectTimeOption(this.hourSelect,a.getHours());SelectCalendar.selectTimeOption(this.minuteSelect,a.getMinutes());if(this.options.enableSecond){SelectCalendar.selectTimeOption(this.secondSelect,a.getSeconds())}}}},getSelectedDate:function(){if(this.yearSelect.value==""||this.monthSelect.value==""||this.daySelect.value==""){return undefined}var a=ProtoCalendar.newDate();a.setFullYear(this.yearSelect.value);a.setMonth(this.monthSelect.value-1);a.setDate(this.daySelect.value);if(this.options.enableHourMinute){if(this.hourSelect.value==""||this.minuteSelect.value==""){return undefined}a.setHours(this.hourSelect.value-0);a.setMinutes(this.minuteSelect.value-0);if(this.options.enableSecond){if(this.secondSelect.value==""){return undefined}a.setSeconds(this.secondSelect.value-0)}}if(isNaN(a.getTime())){return undefined}else{return a}}});
\ No newline at end of file
diff --git a/public/stylesheets/calendar/ext-simple.css b/public/stylesheets/calendar/ext-simple.css
new file mode 100644 (file)
index 0000000..36ef60f
--- /dev/null
@@ -0,0 +1,225 @@
+/*******************************************************************************\r
+ container\r
+*********************************************************************************/\r
+.cal-container, #cal-container {\r
+  background-color: #c7d8ed;\r
+  border: 1px solid #274992;\r
+  overflow:hidden;\r
+  padding: 0px;\r
+  position:absolute;\r
+  width: 200px;\r
+  z-index: 10;\r
+\r
+  font-size: 13px;\r
+}\r
+\r
+.cal-container iframe {\r
+  border:none;\r
+  height:100%;\r
+  left:0px;\r
+  margin:0;\r
+  padding:0;\r
+  position:absolute;\r
+  top:0px;\r
+  width:100%;\r
+  z-index:0;\r
+}\r
+\r
+/*******************************************************************************\r
+ select\r
+*********************************************************************************/\r
+.cal-select-month{\r
+  background-color: #274992;\r
+  color: #fff;\r
+  font-weight: bold;\r
+}\r
+\r
+.cal-select-year{\r
+  background-color: #274992;\r
+  color: #fff;\r
+  font-weight: bold;\r
+}\r
+\r
+/*******************************************************************************\r
+ calendar\r
+*********************************************************************************/\r
+table.cal-table {\r
+  margin-left: auto;\r
+  margin-right: auto;\r
+  width: 100%;\r
+}\r
+\r
+.cal-header {\r
+  background-color: #274992;\r
+  color: #fff;\r
+  text-align: center;\r
+  padding: 3px;\r
+\r
+}\r
+\r
+.cal-body {\r
+  padding: 0px;\r
+  text-align: center;\r
+}\r
+\r
+\r
+.cal-weekday {\r
+  background-color: #fff;\r
+  text-align: center;\r
+}\r
+\r
+.cal-otherday {\r
+  color: #fff;\r
+  background-color: #fff;\r
+  text-align: center;\r
+}\r
+\r
+.cal-sunday {\r
+  background-color: #fff;\r
+  text-align: center;\r
+}\r
+\r
+.cal-saturday {\r
+  background-color: #fff;\r
+  text-align: center;\r
+}\r
+\r
+.cal-holiday {\r
+  background-color: #fff;\r
+  text-align: center;\r
+}\r
+\r
+.cal-label-cell {\r
+  color: #274992;\r
+  font-size: 75%;\r
+  text-align: center;\r
+}\r
+\r
+.cal-label-row .cal-sunday {\r
+  background-color: #c7d8ed;\r
+  color: #274992;\r
+  text-align: center;\r
+}\r
+\r
+.cal-label-row .cal-saturday {\r
+  background-color: #c7d8ed;\r
+  color: #274992;\r
+  text-align: center;\r
+}\r
+\r
+.cal-day-cell {\r
+  border: 1px solid #fff;\r
+  height: 21px;\r
+  line-height: 1.7;\r
+  padding: 0;\r
+  width: 14%;\r
+}\r
+\r
+.cal-input-hour-minute {\r
+  padding-bottom: 2px;\r
+  text-align: center;\r
+}\r
+.cal-error-list {\r
+  padding: 3px 5px 3px 5px;\r
+  font-size: 80%;\r
+  list-style: none;\r
+  background-color: #F7CEE1;\r
+}\r
+.cal-error-list li {\r
+  background: #F7CEE1 url(../images/error.gif) no-repeat center left;\r
+  text-indent: 20px;\r
+  padding-top: 2px;\r
+  padding-bottom: 2px;\r
+}\r
+/* for ie bug */\r
+* html .cal-error-list li {\r
+  text-indent: 5px;\r
+}\r
+.cal-ok-button {\r
+  margin-left: 2px;\r
+}\r
+\r
+/*******************************************************************************\r
+ link\r
+*********************************************************************************/\r
+.cal-selected{\r
+  background-color: #c7d8ed;\r
+  color: #000;\r
+  font-weight: bolder;\r
+  text-align: center;\r
+}\r
+\r
+.cal-next-btn {\r
+  padding-bottom:4px;\r
+  padding-left:8px;\r
+  color: #fff;\r
+  cursor: pointer;\r
+  font-weight: bold;\r
+  text-decoration: none;\r
+}\r
+\r
+.cal-prev-btn {\r
+  padding-bottom:4px;\r
+  padding-right:8px;\r
+  color: #fff;\r
+  cursor: pointer;\r
+  font-weight: bold;\r
+  text-decoration: none;\r
+}\r
+\r
+.cal-day-cell a:link,\r
+.cal-day-cell a:visited,\r
+.cal-day-cell a:active {\r
+  color: #000;\r
+  display:block;\r
+  text-decoration: none;\r
+  \r
+}\r
+\r
+.cal-otherday a:link,\r
+.cal-otherday a:visited{\r
+  border: 1px solid #fff;\r
+  color: #dfdfdf;\r
+}\r
+\r
+.cal-weekday a:link,\r
+.cal-weekday a:visited{\r
+  border: 1px solid #fff;\r
+}\r
+\r
+.cal-saturday a:link,\r
+.cal-saturday a:visited{\r
+  border: 1px solid #fff;\r
+}\r
+\r
+#cal-sunday a:link,\r
+.cal-sunday a:visited{\r
+  border: 1px solid #fff;\r
+}\r
+\r
+.cal-prev-btn:hover {\r
+  background-position: top right;\r
+}\r
+\r
+.cal-next-btn:hover {\r
+  background-position: top right;\r
+}\r
+\r
+.cal-day-cell a:hover{\r
+  background-color: #ddecfe;\r
+  text-decoration: none;\r
+  color: #000;\r
+\r
+}\r
+\r
+\r
+\r
+.cal-day-cell a:link.cal-selected,\r
+.cal-day-cell a:visited.cal-selected,\r
+.cal-day-cell a:active.cal-selected {\r
+  color: #000;\r
+  display:block;\r
+  text-decoration: none;\r
+  border: 1px solid #80bfff;\r
+}\r
+\r
diff --git a/public/stylesheets/calendar/jquery-calendar.css b/public/stylesheets/calendar/jquery-calendar.css
new file mode 100644 (file)
index 0000000..6edde63
--- /dev/null
@@ -0,0 +1,221 @@
+/*******************************************************************************\r
+ container\r
+*********************************************************************************/\r
+.cal-container, #cal-container {\r
+  background-color: #777;\r
+  color: #fff;\r
+  border: 1px solid #777;\r
+  overflow:hidden;\r
+  padding: 0px;\r
+  position:absolute;\r
+  width: 200px;\r
+  z-index: 10;\r
+\r
+  font-size: 13px;\r
+}\r
+\r
+.cal-container iframe {\r
+  border:none;\r
+  height:100%;\r
+  left:0px;\r
+  margin:0;\r
+  padding:0;\r
+  position:absolute;\r
+  top:0px;\r
+  width:100%;\r
+  z-index:0;\r
+}\r
+\r
+/*******************************************************************************\r
+ select\r
+*********************************************************************************/\r
+.cal-select-month{\r
+  background-color: #000;\r
+  color: #fff;\r
+  font-weight: bold;\r
+}\r
+\r
+.cal-select-year{\r
+  background-color: #000;\r
+  color: #fff;\r
+  font-weight: bold;\r
+}\r
+\r
+/*******************************************************************************\r
+ calendar\r
+*********************************************************************************/\r
+table.cal-table {\r
+  margin-left: auto;\r
+  margin-right: auto;\r
+  width: 100%;\r
+}\r
+\r
+.cal-header {\r
+  background-color: #000;\r
+  color: #fff;\r
+  text-align: center;\r
+  padding: 3px;\r
+}\r
+\r
+.cal-body {\r
+  padding: 0px;\r
+  text-align: center;\r
+}\r
+\r
+\r
+.cal-weekday {\r
+  background-color: #efefef;\r
+  text-align: center;\r
+}\r
+\r
+.cal-otherday {\r
+  color: #fff;\r
+  background-color: #fff;\r
+  text-align: center;\r
+}\r
+\r
+.cal-sunday {\r
+  background-color: #ddd;\r
+  text-align: center;\r
+}\r
+\r
+.cal-saturday {\r
+  background-color: #ddd;\r
+  text-align: center;\r
+}\r
+\r
+.cal-holiday {\r
+  background-color: #ddd;\r
+  text-align: center;\r
+}\r
+\r
+.cal-label-cell {\r
+  color: #ffffff;\r
+  font-size: 75%;\r
+  text-align: center;\r
+}\r
+\r
+.cal-label-row .cal-sunday {\r
+  background-color: #777;\r
+  color: #ffffff;\r
+  text-align: center;\r
+}\r
+\r
+.cal-label-row .cal-saturday {\r
+  background-color: #777;\r
+  color: #ffffff;\r
+  text-align: center;\r
+}\r
+\r
+.cal-day-cell {\r
+  border: 1px solid #ddd;\r
+  line-height: 1.7;\r
+  height: 21px;\r
+  padding: 0;\r
+  width: 14%;\r
+}\r
+\r
+.cal-input-hour-minute {\r
+  padding-bottom: 2px;\r
+  text-align: center;\r
+}\r
+.cal-error-list {\r
+  padding: 3px 5px 3px 5px;\r
+  font-size: 80%;\r
+  list-style: none;\r
+  background-color: #F7CEE1;\r
+}\r
+.cal-error-list li {\r
+  color: #333;\r
+  background: #F7CEE1 url(../images/error.gif) no-repeat center left;\r
+  text-indent: 20px;\r
+  padding-top: 2px;\r
+  padding-bottom: 2px;\r
+}\r
+/* for ie bug */\r
+* html .cal-error-list li {\r
+  text-indent: 5px;\r
+}\r
+.cal-ok-button {\r
+  margin-left: 2px;\r
+}\r
+\r
+/*******************************************************************************\r
+ link\r
+*********************************************************************************/\r
+\r
+.cal-next-btn {\r
+  padding-bottom:4px;\r
+  padding-left:8px;\r
+  color: #fff;\r
+  cursor: pointer;\r
+  font-weight: bold;\r
+  text-decoration: none;\r
+}\r
+\r
+.cal-prev-btn {\r
+  padding-bottom:4px;\r
+  padding-right:8px;\r
+  color: #fff;\r
+  cursor: pointer;\r
+  font-weight: bold;\r
+  text-decoration: none;\r
+}\r
+\r
+.cal-day-cell a:link,\r
+.cal-day-cell a:visited,\r
+.cal-day-cell a:active {\r
+  color: #000;\r
+  display:block;\r
+  text-decoration: none;\r
+  \r
+}\r
+\r
+.cal-otherday a:link,\r
+.cal-otherday a:visited{\r
+  color: #fff;\r
+}\r
+\r
+.cal-weekday a:link,\r
+.cal-weekday a:visited{\r
+  border: 1px solid #efefef;\r
+}\r
+\r
+.cal-saturday a:link,\r
+.cal-saturday a:visited{\r
+  border: 1px solid #ddd;\r
+}\r
+\r
+.cal-sunday a:link,\r
+.cal-sunday a:visited{\r
+  border: 1px solid #ddd;\r
+}\r
+\r
+.cal-otherday a:link,\r
+.cal-otherday a:visited{\r
+  border: 1px solid #fff;\r
+}\r
+\r
+.cal-day-cell a:hover {\r
+  background-color: #fff;\r
+  color: #ADAAB5;\r
+  text-decoration: none;\r
+  border: 1px solid #000;\r
+}\r
+\r
+.cal-selected {\r
+  background-color: #ffbfbf;\r
+  color: #000;\r
+  font-weight: bold;\r
+  text-align: center;\r
+  border: 1px solid #ddd;\r
+}\r
+\r
+.cal-day-cell a:link.cal-selected,\r
+.cal-day-cell a:visited.cal-selected,\r
+.cal-day-cell a:active.cal-selected {\r
+  color: #000;\r
+  display:block;\r
+  text-decoration: none;\r
+}\r
+\r
diff --git a/public/stylesheets/calendar/metal.css b/public/stylesheets/calendar/metal.css
new file mode 100644 (file)
index 0000000..4e3ae19
--- /dev/null
@@ -0,0 +1,246 @@
+/*******************************************************************************
+ container
+*********************************************************************************/
+.cal-container, #cal-container {
+  background-color: #fff;
+  border: 1px solid #000;
+  overflow:hidden;
+  padding: 0;
+  margin: 0;
+  position:absolute;
+  width: 200px;
+  z-index: 10;
+
+  font-size: 13px;
+}
+
+.cal-container iframe {
+  border:none;
+  height:100%;
+  left:0px;
+  margin:0;
+  padding:0;
+  position:absolute;
+  top:0px;
+  width:100%;
+  z-index:0;
+}
+
+/*******************************************************************************
+ calendar
+*********************************************************************************/
+table.cal-table {
+  margin-left: auto;
+  margin-right: auto;
+  width: 100%;
+}
+
+.cal-header {
+  background-image: url(../images/metal/base_dark.gif);
+  color: #A4ADB8;
+  font-size:0px;
+  line-height:0px;
+  text-indent:-5000px;
+  height:30px;
+  padding: 8px 6px 5px 6px;
+}
+
+.cal-body {
+  background-image: url(../images/metal/base_light.gif);
+  padding: 5px;
+  text-align: center;
+}
+.cal-footer-top {
+  display: none;
+}
+
+.cal-weekday {
+  color:#ADAAB5;
+  text-align: center;
+}
+
+.cal-otherday {
+  text-align: center;
+}
+
+.cal-sunday {
+  color:#EC383E;
+  text-align: center;
+}
+
+.cal-saturday {
+  color:#0072BC;
+  text-align: center;
+}
+
+.cal-holiday {
+  color:#EC383E;
+  text-align: center;
+}
+
+.cal-label-cell {
+  padding-bottom: 7px;
+  color: ADAAB5;
+  font-size: 75%;
+  text-align: center;
+}
+
+.cal-label-row .cal-sunday {
+  color: #F78E73;
+  text-align: center;
+}
+
+.cal-label-row .cal-saturday {
+  color: #73A2DE;
+  text-align: center;
+}
+
+.cal-day-cell {
+  width: 14%;
+  height: 18px;
+  line-height: 1.7;
+}
+
+.cal-input-hour-minute {
+  background-image: url(../images/metal/base_dark.gif);
+  padding-top: 6px;
+  text-align: center;
+  height:28px;
+}
+.cal-error-list {
+  background-color: #F7CEE1;
+  padding: 2px 5px 2px 5px;
+  font-size: 80%;
+  list-style: none;
+}
+.cal-error-list li {
+  padding-top: 2px;
+  padding-bottom: 2px;
+  background: #F7CEE1 url(../images/error.gif) no-repeat center left;
+  margin-left: 5px;
+  text-indent: 20px;
+}
+/* for ie bug */
+* html .cal-error-list li {
+  text-indent: 5px;
+}
+
+.cal-ok-button {
+  margin-left: 10px;
+}
+
+/*******************************************************************************
+ link
+*********************************************************************************/
+
+.cal-select-year{
+  float: left;
+  margin:0 0 0 5px;
+  width:60px;
+  padding: 0; 
+}
+.cal-select-month{
+  float: left;
+  margin:0 0 0 10px; 
+  padding: 0;
+  width:60px;
+}
+
+.cal-next-btn {
+  background-image:url(../images/metal/button_right_off.gif);
+  cursor: pointer;
+  display:block;
+  float:right;
+  height:25px;
+  text-indent: -10000px;
+  width:24px;
+}
+.cal-next-btn:hover {
+  background-image:url(../images/metal/button_right_on.gif);
+}
+
+.cal-prev-btn {
+  background-image:url(../images/metal/button_left_off.gif);
+  cursor: pointer;
+  display:block;
+  float:left;
+  height:25px;
+  text-indent: -10000px;
+  width:24px;
+}
+.cal-prev-btn:hover {
+  background-image:url(../images/metal/button_left_on.gif);
+}
+
+.cal-day-cell a:link,
+.cal-day-cell a:visited,
+.cal-day-cell a:active {
+  color: #000;
+  display:block;
+  font-weight:bold;
+  text-decoration: none;
+}
+
+/*******************************************************************************
+*********************************************************************************/
+
+.cal-sunday a:link,
+.cal-sunday a:visited,
+.cal-sunday a:active {
+  color: #FA4A1C;
+  display:block;
+  font-weight:bold;
+  text-decoration: none;
+}
+.cal-saturday a:link,
+.cal-saturday a:visited,
+.cal-saturday a:active {
+  color: #2D64C8;
+  display:block;
+  font-weight:bold;
+  text-decoration: none;
+}
+
+.cal-holiday a:link,
+.cal-holiday a:visited,
+.cal-holiday a:active {
+  color: #FA4A1C;
+  display:block;
+  font-weight:bold;
+  text-decoration: none;
+}
+
+.cal-otherday a:link,
+.cal-otherday a:visited,
+.cal-otherday a:active {
+  color: #8A8A8A;
+  display:block;
+  font-weight:bold;
+  text-decoration: none;
+}
+
+.cal-day-cell a:hover {
+  background: #FFBEDE;
+  text-decoration: none;
+}
+
+.cal-selected {
+  background-color:#FFBEDE;
+  font-weight: bold;
+  text-align: center;
+}
+
+.cal-table td.cal-disabled {
+  color: #585756;
+  text-decoration: line-through;
+  cursor: default;
+}
+
+.cal-day-cell a:link.cal-selected,
+.cal-day-cell a:visited.cal-selected,
+.cal-day-cell a:active.cal-selected {
+  background:#FFBEDE;
+  display:block;
+  text-decoration: none;
+}
+
diff --git a/public/stylesheets/calendar/paper.css b/public/stylesheets/calendar/paper.css
new file mode 100644 (file)
index 0000000..e0ecff9
--- /dev/null
@@ -0,0 +1,277 @@
+/*******************************************************************************
+ container
+*********************************************************************************/
+.cal-container, #cal-container {
+  background-color: #fff;
+  overflow: hidden;
+  padding: 0;
+  margin: 0;
+  position: absolute;
+  width: 200px;
+  z-index: 10;
+
+  font-size: 13px;
+}
+
+.cal-container iframe {
+  border:none;
+  height:100%;
+  left:0px;
+  margin:0;
+  padding:0;
+  position:absolute;
+  top:0px;
+  width:100%;
+  z-index:0;
+}
+
+/*******************************************************************************
+ calendar
+*********************************************************************************/
+table.cal-table {
+  margin-left: auto;
+  margin-right: auto;
+  width: 90%;
+}
+
+.cal-header-top {
+  height: 11px;
+  background: #fff url(../images/paper/base_header.gif) no-repeat bottom center;
+}
+.cal-header {
+  background: #fff url(../images/paper/base_body.gif) repeat-y top center;
+  color: #fff;
+  height:30px;
+  margin: 0;
+  padding: 0;
+  font-size: 0px;
+  line-height:0px;
+  font-decoration: none;
+  text-indent:-5000px;
+
+}
+.cal-body-top {
+  font-size: 0px;
+  height: 2px;
+  background: #fff url(../images/paper/base_line.gif) no-repeat top center;
+}
+.cal-border {
+  font-size: 0px;
+  height: 2px;
+  background: #000 url(../images/paper/base_line.gif) no-repeat top center;
+}
+.cal-body {
+  background:url(../images/paper/base_body.gif) repeat-y top center;
+  padding: 4px 2px 2px 2px;
+  text-align: center;
+}
+.cal-footer-top {
+  display: none;
+}
+
+.cal-footer {
+  margin:0px;
+  height: 29px;
+  background:url(../images/paper/base_footer.gif) no-repeat bottom center;
+}
+.cal-weekday {
+  text-align: center;
+}
+
+.cal-otherday {
+  text-align: center;
+}
+
+.cal-sunday {
+  color:#F78E73;
+  text-align: center;
+}
+
+.cal-saturday {
+  color:#73A2DE;
+  text-align: center;
+}
+
+.cal-holiday {
+  color:#F78E73;
+  text-align: center;
+}
+
+.cal-label-cell {
+  padding-bottom: 7px;
+  color: #8A8A8A;
+  font-size: 80%;
+  text-align: center;
+}
+
+.cal-label-row .cal-sunday {
+  color: #F3866A;
+  text-align: center;
+}
+
+.cal-label-row .cal-saturday {
+  color: #699AD8;
+  text-align: center;
+}
+
+.cal-day-cell {
+  width: 14%;
+  height: 15px;
+  line-height: 1.7;
+}
+.cal-input-hour-minute {
+  background:url(../images/paper/base_body.gif) repeat-y top center;
+  padding-top: 5px;
+  text-align: center;
+}
+.cal-error-list {
+  background: #fff url(../images/paper/base_body.gif) repeat-y top center;
+  padding: 7px 5px 0 5px;
+  font-size: 80%;
+  list-style: none;
+}
+.cal-error-list li {
+  padding-top: 2px;
+  margin-left: 5px;
+  text-indent: 5px;
+  background: url(../images/error.gif) no-repeat center left;
+  text-indent: 20px;
+}
+/* for ie bug */
+* html .cal-error-list li {
+  text-indent: 5px;
+}
+
+.cal-ok-button {
+  margin-left: 2px;
+}
+
+/*******************************************************************************
+ link
+*********************************************************************************/
+
+.cal-select-year {
+  float: left;
+  margin: 0 0 0 3px;
+  width: 60px;
+  padding: 0;
+}
+.cal-select-month {
+  float: left;
+  margin: 0 0 0 3px; 
+  padding: 0;
+  width: 60px;
+}
+
+.cal-next-btn {
+  background: #fff url(../images/paper/button_right_off.gif) no-repeat center left;
+  cursor: pointer;
+  display: block;
+  float: right;
+  height: 25px;
+  text-indent: -10000px;
+  width:24px;
+  margin:0 5px 0 0;
+}
+.cal-next-btn:hover {
+  background: #fff url(../images/paper/button_right_on.gif) no-repeat center left;
+}
+
+.cal-prev-btn {
+  margin:0 0 0 5px;
+  background: #fff url(../images/paper/button_left_off.gif) no-repeat center left;
+  cursor: pointer;
+  display: block;
+  float: left;
+  height: 25px;
+  text-indent: -10000px;
+  width: 24px;
+}
+
+.cal-prev-btn:hover{
+  background: #fff url(../images/paper/button_left_on.gif) no-repeat center right;
+}
+
+.cal-day-cell a:link,
+.cal-day-cell a:visited,
+.cal-day-cell a:active {
+  color: #000;
+  display:block;
+  font-weight:bold;
+  text-decoration: none;
+}
+
+/*******************************************************************************
+
+*********************************************************************************/
+
+.cal-sunday a:link,
+.cal-sunday a:visited,
+.cal-sunday a:active {
+  color: #FA4A1C;
+  display:block;
+  font-weight:bold;
+  text-decoration: none;
+}
+.cal-saturday a:link,
+.cal-saturday a:visited,
+.cal-saturday a:active {
+  color: #2D64C8;
+  display:block;
+  font-weight:bold;
+  text-decoration: none;
+}
+
+.cal-holiday a:link,
+.cal-holiday a:visited,
+.cal-holiday a:active {
+  color: #FA4A1C;
+  display:block;
+  font-weight:bold;
+  text-decoration: none;
+}
+
+.cal-otherday a:link,
+.cal-otherday a:visited,
+.cal-otherday a:active {
+  color: #8A8A8A;
+  display:block;
+  font-weight:bold;
+  text-decoration: none;
+}
+
+/*******************************************************************************
+
+*********************************************************************************/
+
+.cal-day-cell a:hover {
+  background: #fff url(../images/paper/check.gif) no-repeat top center;
+  font-weight: bold;
+/*  background: #FFBEDE; */
+  text-decoration: none;
+}
+
+.cal-selected {
+  background: #fff url(../images/paper/check.gif) no-repeat top center;
+  font-weight: bold;
+  text-align: center;
+}
+
+.cal-disabled {
+  background: url(../images/paper/disabled.gif) no-repeat top center;
+  cursor: default;
+}
+
+.cal-day-cell a:link.cal-selected,
+.cal-day-cell a:visited.cal-selected {
+  background: #fff url(../images/paper/check.gif) no-repeat top center;
+  display:block;
+  text-decoration: none;
+}
+
+.cal-day-cell a:active.cal-selected {
+  background:#FFBEDE;
+  display:block;
+  text-decoration: none;
+}
+
diff --git a/public/stylesheets/calendar/simple.css b/public/stylesheets/calendar/simple.css
new file mode 100644 (file)
index 0000000..7fc0fd3
--- /dev/null
@@ -0,0 +1,194 @@
+/*******************************************************************************
+ container
+*********************************************************************************/
+.cal-container, #cal-container {
+  background-color: #fff;
+  border: 1px solid #0066B3;
+  overflow:hidden;
+  padding: 0px;
+  position:absolute;
+  width: 200px;
+  z-index: 10;
+
+  font-size: 13px;
+}
+
+.cal-container iframe {
+  border:none;
+  height:100%;
+  left:0px;
+  margin:0;
+  padding:0;
+  position:absolute;
+  top:0px;
+  width:100%;
+  z-index:0;
+}
+
+/*******************************************************************************
+ calendar
+*********************************************************************************/
+table.cal-table {
+  margin-left: auto;
+  margin-right: auto;
+  width: 100%;
+}
+
+.cal-header {
+  background-color: #84AADE;
+  color: #fff;
+  text-align: center;
+  padding: 3px;
+}
+
+.cal-body {
+  padding: 5px;
+  text-align: center;
+}
+
+.cal-footer {
+}
+
+.cal-footer-top {
+  display: none;
+}
+
+.cal-weekday {
+  background-color: #A2A19F;
+  text-align: center;
+}
+
+.cal-otherday {
+  color: #fff;
+  background-color: #cccccc;
+  text-align: center;
+}
+
+.cal-sunday {
+  background-color: #F78E73;
+  text-align: center;
+}
+
+.cal-saturday {
+  background-color: #73A2DE;
+  text-align: center;
+}
+
+.cal-holiday {
+  background-color: #F78E73;
+  text-align: center;
+}
+
+.cal-label-cell {
+  color: #A2A19F;
+  font-size: 75%;
+  text-align: center;
+}
+
+.cal-label-row .cal-sunday {
+  background-color: #fff;
+  color: #F78E73;
+  text-align: center;
+}
+
+.cal-label-row .cal-saturday {
+  background-color: #fff;
+  color: #73A2DE;
+  text-align: center;
+}
+
+.cal-day-cell {
+  height: 21px;
+  border: 1px solid #fff;
+  line-height: 1.7;
+  width: 14%;
+}
+
+.cal-input-hour-minute {
+  padding-bottom: 2px;
+  text-align: center;
+}
+.cal-error-list {
+  background-color: #E6EFFB;
+  padding: 3px 5px 3px 5px;
+  font-size: 80%;
+  list-style: none;
+}
+.cal-error-list li {
+  background: #E6EFFB url(../images/error.gif) no-repeat center left;
+  text-indent: 20px;
+  padding-top: 2px;
+  padding-bottom: 2px;
+}
+/* for ie bug */
+* html .cal-error-list li {
+  text-indent: 5px;
+}
+.cal-ok-button {
+  margin-left: 2px;
+}
+
+.cal-select-year {
+  width: 60px;
+}
+.cal-select-month {
+  width: 60px;
+}
+
+/*******************************************************************************
+ link
+*********************************************************************************/
+
+.cal-next-btn {
+  padding-bottom:4px;
+  padding-left:8px;
+  color: #fff;
+  cursor: pointer;
+  font-weight: bold;
+  text-decoration: none;
+}
+
+.cal-prev-btn {
+  padding-bottom:4px;
+  padding-right:8px;
+  color: #fff;
+  cursor: pointer;
+  font-weight: bold;
+  text-decoration: none;
+}
+
+.cal-day-cell a:link,
+.cal-day-cell a:visited,
+.cal-day-cell a:active {
+  color: #fff;
+  display:block;
+  text-decoration: none;
+}
+
+.cal-day-cell a:hover {
+  background-color: #fff;
+  color: #ADAAB5;
+  text-decoration: none;
+}
+
+.cal-selected {
+  background-color: #fff;
+  color: #ADAAB5;
+  font-weight: bold;
+  text-align: center;
+}
+
+.cal-disabled {
+  color: #898989 !important;
+  background-color: #585756 !important;
+  cursor: default;
+}
+
+.cal-day-cell a:link.cal-selected,
+.cal-day-cell a:visited.cal-selected,
+.cal-day-cell a:active.cal-selected {
+  color: #ADAAB5;
+  display:block;
+  text-decoration: none;
+}
+
diff --git a/spec/helpers/admin/base_helper_spec.rb b/spec/helpers/admin/base_helper_spec.rb
new file mode 100644 (file)
index 0000000..388790a
--- /dev/null
@@ -0,0 +1,28 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+describe Admin::BaseHelper do
+
+  #Delete this example and add some real ones or delete this file
+  it "should include the Admin::BaseHelper" do
+    included_modules = (class << helper; self; end).send :included_modules
+    included_modules.should include(Admin::BaseHelper)
+  end
+  
+  describe "calendar_date_select" do  
+    
+    subject {@object = Order.new() }
+
+    it "should return 'script' " do
+      helper.calendar_date_select(@object,:mthd,{},{}).index("script").should_not == nil
+    end
+
+    it "should return 'img'" do
+      helper.calendar_date_select(@object,:mthd,{},{}).index("img").should_not == nil
+    end
+
+    it "should return 'SelectCalendar.createOnLoaded'" do
+      helper.calendar_date_select(@object,:mthd,{},{}).index("SelectCalendar.createOnLoaded").should_not == nil
+    end
+
+  end
+end