Button Control: Calendar Menu Button with Date on Button Face
このExampleも先の「Button Control: Simple Calendar Menu Button」と殆ど同じ内容のカレンダーピッカー。
唯一の違いは、これがForm送信を意識していることで、ピックアップした日付はhiddenのフィールド(select+opetionの月日と、テキストフィールドの年)に格納されるとともに、ボタンラベルとなる。
初期画面は以下。
ここで「Choose A Date」ボタンを押すと、カレンダーが現れる。
カレンダーで日付を選択すると、ラベルが変更となり、カレンダーピッカーは隠れる。
以下にmodule patternで書き直した、htmlの全文を示す。
カレンダーの作成、表示、選択といった流れは、「先の例」とまったく同じである。
以下のサンプルでは、window.loadの代わりに、以下のROMReadyによって処理を開始している。(以下のhtmlのように)大きいmarkup(id=datefields)のある場合には、かならずこのような配慮が必要である。
//DOMが完全にloadされたら、サンプルを初期化する。 YAHOO.util.Event.onDOMReady( //DomReadyイベントで発火するハンドラ YAHOO.EGP.CalendarButton.init, //ハンドラに渡すオブジェクト(関数) YAHOO.EGP.CalendarButton, //ハンドラは、上記のオブジェクトのスコープをもつ。 true ); >|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/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/container/container_core-min.js"></script> <script type="text/javascript" src="scripts/yui/calendar/calendar-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> <style type="text/css" id="defaultstyle"> #container { margin: 2px; padding: 3px; width: 500px; /* height: auto; */ border:1px dashed #999999; } /* Set the "zoom" property to "normal" since it is set to "1" by the ".example-container .bd" rule in yui.css and this causes a Menu instance's width to expand to 100% of the browser viewport. */ div.yuimenu .bd { zoom: normal; } #calendarmenu { position: absolute; } /* Restore default padding of 10px for the calendar containtainer that is overridden by the ".example-container .bd .bd" rule in yui.css. */ #calendarcontainer { padding:10px; } #personalinfo { border: solid 1px #666; padding: .5em; } #calendarpicker { vertical-align: baseline; } div.field { padding: .25em; } input#year { width: 4em; } </style> <script type="text/javascript"> // //モジュールパターンで実装する。 // YAHOO.namespace("EGP"); YAHOO.EGP.CalendarButton = function() { var Event = YAHOO.util.Event; var Dom = YAHOO.util.Dom; var oCalendarMenu; var oButton; // カレンダー表示ボタンクリック時のハンドラー var onButtonClick = function () { // OVerlayインスタンスのボディー部にid=buttoncalendarでカレンダーインスタンス // を作る。 // (※)カレンダーインスタンスは1回しか作成されない。 var oCalendar = new YAHOO.widget.Calendar("buttoncalendar", oCalendarMenu.body.id); // カレンダーのselectイベントに、markupとボタンへの日付の編集と、カレンダーの非表示を // sbscribeする。 oCalendar.selectEvent.subscribe(function (p_sType, p_aArgs) { var aDate, nMonth, nDay, nYear; var wkStr; if (p_aArgs) { //ラベルの編集 aDate = p_aArgs[0][0]; nMonth = aDate[1]; nDay = aDate[2]; nYear = aDate[0]; wkStr = nYear + "/" + nMonth + "/" + nDay; oButton.set("label", wkStr); // 隠しフィールドの編集 Dom.get("month").selectedIndex = (nMonth - 1); Dom.get("day").selectedIndex = (nDay - 1); Dom.get("year").value = nYear; }else{ wkStr="date unknown"; } oCalendarMenu.hide(); }); // Calendar表示時の処理 // 本日をフォーカスさせ、ページを送ったら先頭日にフォーカスを当てる(点線の枠)。 oCalendar.renderEvent.subscribe(focusDay, oCalendar, true); // Calendarのレンダリング oCalendar.render(); // Buttonのクリックは1回だけなので、unsubscribeする。 // この後のボタンクリックは、ボタンインスタンスを再表示してMenu処理をするだけ。 // (これは、oButton生成時に設定される) this.unsubscribe("click", onButtonClick); }; // 日にちにfocusを当てるための関数。 var focusDay = function () { // Calelndarインスタンスを生成したDOM(id="buttoncalendar")から // Table Bodyをとってくる。http://www.howtocreate.co.uk/tutorials/javascript/domtables var oCalendarTBody = Dom.get("buttoncalendar").tBodies[0], // カレンダーの全ての日を取ってくる(aタグで書かれている)。 aElements = oCalendarTBody.getElementsByTagName("a"), oAnchor; if (aElements.length > 0) { // Dom.batch(Array,fn)は、Array要素に対して、繰り返しfnを適用する。 Dom.batch(aElements, function (element) { // elementの親ノードが"today"というclassをもてば、アンカー // をそのエレメントに貼る。 // この場合は、td要素。 if (Dom.hasClass(element.parentNode, "today")) { oAnchor = element; } }); // アンカーが貼られなかったら、先頭日に貼る。(月が送られたときの処理) if (!oAnchor) { oAnchor = aElements[0]; } // 0msec後にoAnchorにたいして、functionを実行。 YAHOO.lang.later(0, oAnchor, function () { try { oAnchor.focus(); } catch(e) {} }); } }; return{ init: function() { // Calendarインスタンスを入れるOverlayインスタンスの作成。 // id=calendarmenuとする。 oCalendarMenu = new YAHOO.widget.Overlay("calendarmenu", { visible: false }); // 年月日を隠しフィールドの取得 var oDateFields = Dom.get("datefields"); oMonthField = Dom.get("month"), oDayField = Dom.get("day"), oYearField = Dom.get("year"); // 年月日を隠しフィールドにする oMonthField.style.display = "none"; oDayField.style.display = "none"; oYearField.style.display = "none"; // ボタンの作成 oButton = new YAHOO.widget.Button({ type: "menu", id: "calendarpicker", label: "Choose A Date", menu: oCalendarMenu, container: "datefields" }); // ボタンのappendToイベントに対して、Calendarインスタンスを入れるための // 空のbodyをセットする。 // このbodyのidをcalendarcontainerとする。 oButton.on("appendTo", function () { oCalendarMenu.setBody(" "); oCalendarMenu.body.id = "calendarcontainer"; }); // ボタンのクリックイベントのハンドラとして、onButtonClickを設定する。 oButton.on("click", onButtonClick); // oCalendarMenu上でkeyが押され、それがesc keyの場合、フォーカスを // ボタンに返す。 Event.on(oCalendarMenu.element, "keydown", function (p_oEvent) { if (Event.getCharCode(p_oEvent) === 27) { oCalendarMenu.hide(); oButton.focus(); } }, null, oButton ); } }; }(); //DOMが完全にloadされたら、サンプルを初期化する。 YAHOO.util.Event.onDOMReady( //DomReadyイベントで発火するハンドラ YAHOO.EGP.CalendarButton.init, //ハンドラに渡すオブジェクト(関数) YAHOO.EGP.CalendarButton, //ハンドラは、上記のオブジェクトのスコープをもつ。 true ); </script> </HEAD> <BODY class="yui-skin-sam"> <div id="container"> <p> Calendar Buttonの作り方のサンプルです。 </p> <form id="button-example-form" name="button-example-form" method="post"> <fieldset id="personalinfo"> <legend>Personal Information</legend> <div class="field"> <label for="firstname">First Name: </label> <input type="text" id="firstname" name="firstname" value=""> </div> <div class="field"> <label for="lastname">Last Name: </label> <input type="text" id="lastname" name="lastname" value=""> </div> <div class="field" id="datefields"> <label for="month">Birthday: </label> <select id="month" name="month"> <option value="01">01</option> <option value="02">02</option> <option value="03">03</option> <option value="04">04</option> <option value="05">05</option> <option value="06">06</option> <option value="07">07</option> <option value="08">08</option> <option value="09">09</option> <option value="10">10</option> <option value="11">11</option> <option value="12">12</option> </select> <select id="day" name="day"> <option value="01">01</option> <option value="02">02</option> <option value="03">03</option> <option value="04">04</option> <option value="05">05</option> <option value="06">06</option> <option value="07">07</option> <option value="08">08</option> <option value="09">09</option> <option value="10">10</option> <option value="11">11</option> <option value="12">12</option> <option value="13">13</option> <option value="14">14</option> <option value="15">15</option> <option value="16">16</option> <option value="17">17</option> <option value="18">18</option> <option value="19">19</option> <option value="20">20</option> <option value="21">21</option> <option value="22">22</option> <option value="23">23</option> <option value="24">24</option> <option value="25">25</option> <option value="26">26</option> <option value="27">27</option> <option value="28">28</option> <option value="29">29</option> <option value="30">30</option> <option value="31">31</option> </select> <input type="text" id="year" name="year" value=""> </div> <div class="field"> <input type="submit" id="submit-button" name="submit-button" value="Submit Form"> </div> </fieldset> </form> </div> </BODY> </HTML>