JavaScript Note#2 jQuery DatePicker Default Value

สำหรับปัญหาครั้งนี้เกิดจากว่า DatePicker ที่เราตั้งค่าเอาไว้ให้เลือกแบบ ‘yyyy’ หรือ ‘mm yyyy’ มันจะรีเซตตัวเองเป็นเดือน/ปีปัจจุบันทุกครั้งที่เราเลือก

อ่ะ… ท่าจะนึกไม่ออก งั้นจะอธิบาย Scenario ให้ฟัง

เริ่มจากว่าเรามี TextBox อันหนึ่งสำหรับแสดงค่าปี หรือเดือน-ปีในหน้าเว็บ เขียนด้วย

<asp:TextBox ID=”dateTextbox” runat=”server” CssClass=”ui_date">

จะเห็นว่าเป็น TextBox ธรรมดา แต่สังเกตว่า CssClass=”ui_date” อยู่ ตรงนี้แหละที่จัดการกับ DatePicker โดยเราต้องเขียน JavaScript เป็น

$(function () {
$(“.ui_date”).datepicker({
dateFormat: “yy”,
changeYear: true,
stepMonths: 12,
onClose: function (dateText, inst) {
var year = $(“#ui-datepicker-div
.ui-datepicker-year :selected”).val();
$(this).datepicker(‘setDate’, new Date(year));
}
});
....
}

ซึ่งเวลาเราคลิกที่ TextBox มันก็จะแสดงปี 2017 (ปีปัจจุบัน) พอเรากดที่ปีก็จะมี Dropdown ให้เลือก สมมติว่าเราเลือก 2014 ละกัน เลือกเสร็จก็กดกดพื้นที่ข้างนอกของบริเวณที่เลือก ตัวปีที่เลือกก็แสดงใน TextBox

แต่พอเรากดที่ TextBox อีกครั้ง แทนที่มันจะแสดงปี 2014 มันกลับแสดงปี 2017 เหมือนเดิม ปัญหาจะเกิดขึ้นถ้าเราเผลอคลิกที่พื้นที่ข้างนอกของบริเวณที่เลือก TextBox ก็จะถูกเซตเป็น 2017 อัตโนมัติ

วิธีแก้ คือ กำหนดค่า Default ให้กับ DatePicker ซึ่งกรณีเราแก้ 2 ที่
1. แก้ใน onClose ให้นอกจากเซตปีใน TextBox แล้ว ยังกำหนดให้เซต Default Value ของ DatePicker ใน TextBox อีกด้วย
2. แก้กรณีที่เป็น PostBack กลับมาจากหน้าอื่น (ซึ่งก็เกิดปัญหาเดียวกัน) โดยการใส่ไว้ใน $(function() {…}); ซึ่งจะถูกเรียกทุกครั้งที่หน้าเว็บเปิดเข้ามา

ลืมอธิบายไปว่า Flow ของหน้านี้คือเราทำการเลือกปีและค้นหาข้อมูล หลังจากนั้นเราสามารถกดเข้าไปดูข้อมูลได้อีกหน้า และกดกลับมาได้ ตรงนี้แหละที่จะเข้ากรณีที่ 2. ซึ่งก่อนจะเปิดหน้าอื่น ค่าปีที่เราเคยเลือกจะถูกเก็บไว้ใน HiddenField ที่มีชื่อว่า SHiddenSDate

โค้ดที่ได้ก็จะหน้าตาประมาณนี้

$(function () {
$(“.ui_date”).datepicker({
dateFormat: “yy”,
changeYear: true,
stepMonths: 12,
onClose: function (dateText, inst) {
var year = $(“#ui-datepicker-div
.ui-datepicker-year :selected”).val();
$(this).datepicker(‘option’, ‘defaultDate’,
new Date(year));

// Show default year as same as Textbox after select year
$(this).datepicker(‘setDate’, new Date(year));
}
});
// ==== Show default year (get from hidden field) after postback
var hidDate = document.getElementById('SHiddenSDate');
defYear = hidDate.value;
console.log("Default Year: " + defYear);
$("#dateTextbox").datepicker('option', 'defaultDate',
new Date(defYear));
$("#dateTextbox").datepicker('setDate', new Date(defYear));
    // ====
....
}

จบแล้ว ดีใจ ต้องขอบคุณ Stackoverflow และ Keyword ที่ทำให้หา Solution เจอ