Calendar Control: Calendar inside a Container
このExampleのページ(上のリンク)にこう書いてある。
The default Calendar/CalendarGroup controls do not provide positioning or dragdrop support natively, as the Container family's Overlay control and its subclasses do.(YUIのExampleのページより引用)
デフォルトのCalendarやCalendarGroupは、位置決めやドラッグ・アンド・ドロップの機能をもってないが、OverlayやそのサブクラスといったContainerは、それをもっている。
そのために、CalendarをOverlay(のサブクラスPanel)のサブクラスであるDialogに仕込ませる。
というのが、Exampleの目的である。
Calendarについては、以前のExample「Button Control: Simple Calendar Menu Button」でボタンに仕込んだが、今回のようにPanelの仲間に忍ばせるというのも一般的な使い方だろう。
この忍ばせ方が(ボタンのときと違って)いたって簡単で、(添付のソースコードを見てもらうのが手っ取り早いが)Markupに忍ばせて、ここからDialogとCalendarを生成してしまう。
今回のサンプルでは、YUIのサンプルに手を加えて、カレンダーの表示を日本語に変えてみた。(下の図)
これには、CalendarのConfiguration Attributesを変えてやればよい。
(YUI.widget.CalendarのAPIドキュメントへのリンク)
月には「Jan,Feb …」の代わりに「睦月,如月…」が表示され、曜日の所は「日,月…」と表示される。
カレンダーから日にちを選んで、Selectボタンを押すと、以下のようになる。
以下に、Javascriptを含むHTMLの全文を示す。
ソースコードはモジュールパターンに書き直した。
<HTML> <HEAD> <META http-equiv="Content-Type" content="text/html; charset=UTF-8"> <TITLE>Ajax_Sampling</TITLE> <style type="text/css"> body { margin:0; padding:0; } </style> <link rel="stylesheet" type="text/css" href="scripts/yui/fonts/fonts-min.css" /> <link rel="stylesheet" type="text/css" href="scripts/yui/button/assets/skins/sam/button.css" /> <link rel="stylesheet" type="text/css" href="scripts/yui/container/assets/skins/sam/container.css" /> <link rel="stylesheet" type="text/css" href="scripts/yui/calendar/assets/skins/sam/calendar.css" /> <script type="text/javascript" src="scripts/yui/yahoo-dom-event/yahoo-dom-event.js"></script> <script type="text/javascript" src="scripts/yui/dragdrop/dragdrop-min.js"></script> <script type="text/javascript" src="scripts/yui/element/element-beta-min.js"></script> <script type="text/javascript" src="scripts/yui/button/button-min.js"></script> <script type="text/javascript" src="scripts/yui/container/container-min.js"></script> <script type="text/javascript" src="scripts/yui/calendar/calendar-min.js"></script> <style type="text/css" id="defaultstyle"> #main { margin: 2px; padding: 3px; width: 400px; height: auto; border:1px dashed #999999; } /* 最初はつぶしておく */ .container { height:0; } /* Clear calendar's float */ #container .bd:after { content:"."; display:block; clear:left; height:0; visibility:hidden; } /* Have calendar squeeze upto bd bounding box */ #container .bd { padding:0; } /* Remove calendar's border and set padding in ems instead of px, so we can specify an width in ems for the container */ #cal { border:none; padding:1em } /* Datefield look/feel */ .datefield { position:relative; top:10px; left:10px; white-space:nowrap; border:1px solid black; background-color:#eee; width:25em; padding:5px; } .datefield input, .datefield button, .datefield label { vertical-align:middle } .datefield label { font-weight:bold } .datefield input { width:15em } .datefield button { padding:0 5px 0 5px; margin-left:2px; } .datefield button img { padding:0; margin:0; vertical-align:middle } /* Example box .box { position:relative; height:30em; } */ </style> <script type="text/javascript"> YAHOO.namespace("EGP"); YAHOO.EGP.DialogCalendar = function() { var dialog, calendar; var Dom =YAHOO.util.Dom; var Event=YAHOO.util.Event; var okHandler = function () { if (calendar.getSelectedDates().length > 0) { var selDate = calendar.getSelectedDates()[0]; // Pretty Date Output, using Calendar's Locale values: Friday, 8 February 2008 var wStr = calendar.cfg.getProperty("WEEKDAYS_LONG")[selDate.getDay()]; var dStr = selDate.getDate(); var mStr = calendar.cfg.getProperty("MONTHS_LONG")[selDate.getMonth()]; var yStr = selDate.getFullYear(); Dom.get("date").value = yStr + "年, " + mStr + " " + dStr + "日 " + wStr; // Dom.get("date").value = wStr + ", " + dStr + " " + mStr + " " + yStr; } else { Dom.get("date").value = ""; } this.hide(); } var cancelHandler = function () { this.hide(); } return{ init: function() { calendar = new YAHOO.widget.Calendar("cal", { iframe:false, // Turn iframe off, since container has iframe support. hide_blank_weeks:true // Enable, to demonstrate how we handle changing height, using changeContent }); dialog = new YAHOO.widget.Dialog("container", { context:["show", "tl", "bl"], buttons:[ {text:"Select", isDefault:true, handler: okHandler}, {text:"Cancel", handler: cancelHandler}], // Sam Skin dialog needs to have a width defined (7*2em + 2*1em = 16em). width:"16em", draggable:false, close:true }); calendar.cfg.setProperty("MONTHS_LONG",["睦月","如月","弥生","卯月","皐月","水無月","文月","葉月","長月","神無月","霜月","師走",]); calendar.cfg.setProperty("MONTHS_SHORT",["睦","如","弥","卯","皐","水","文","葉","長","神","霜","師",]); calendar.cfg.setProperty("WEEKDAYS_LONG",["日曜日","月曜日","火曜日","水曜日","木曜日","金曜日","土曜日"]); calendar.cfg.setProperty("WEEKDAYS_SHORT",["日","月","火","水","木","金","土"]); calendar.render(); dialog.render(); // Using dialog.hide() instead of visible:false is a workaround for an IE6/7 container known issue with border-collapse:collapse. dialog.hide(); calendar.renderEvent.subscribe(function() { // Tell Dialog it's contents have changed, Currently used by container for IE6/Safari2 to sync underlay size dialog.fireEvent("changeContent"); }); Event.on("show", "click", function() { dialog.show(); if (YAHOO.env.ua.opera && document.documentElement) { // Opera needs to force a repaint document.documentElement.className += ""; } }); } }; }(); //DOMが完全にloadされたら、サンプルを初期化する。 YAHOO.util.Event.onDOMReady( //DomReadyイベントで発火するハンドラ YAHOO.EGP.DialogCalendar.init, //ハンドラに渡すオブジェクト(関数) YAHOO.EGP.DialogCalendar, //ハンドラは、上記のオブジェクトのスコープをもつ。 true ); </script> </HEAD> <BODY class="yui-skin-sam"> <div id="main"> <p> DialogにCalendarを仕込むサンプルです。 </p> <div class="box"> <!-- 入力フィールド --> <div class="datefield"> <label for="date">Date: </label> <input type="text" id="date" name="date" value="" /> <button type="button" id="show" title="Show Calendar"> <img src="http://developer.yahoo.com/yui/examples/calendar/assets/calbtn.gif" width="18" height="18" alt="Calendar" > </button> </div> <!-- MarkupでDialogとカレンダーの位置を決めてしまう --> <!-- container: Dialog用のmarkup --> <div id="container"> <div class="hd">Calendar</div> <div class="bd"> <!-- cal: Calendar用のmarkup --> <div id="cal"></div> </div> </div> </div> </div> </BODY> </HTML>