เนื้อหานี้เป็นการอัพเดท แนวทางการสร้างตารางเวลา
โดยเพิ่มความสามารถ ให้สามารถรองรับการกำหนดวันเวลา
การทำซ้ำ หรือเป็นช่วงเวลาได้ เป็นการปรับเพิ่มเติมจากเนื้อหา
ของบทความก่อนหน้า
สร้างตารางเวลา schedule ด้วย php เบื้องต้น อย่างง่าย http://niik.in/607
https://www.ninenik.com/content.php?arti_id=607 via @ninenik
สามารถนำไปใช้กับตารางเรียน ตารางสอน หรือตารางกิจกรรม เพื่อแสดงข้อมูล
โดยในตัวอย่าง จะใช้ชุดข้อมูลตัวอย่าง ในรูปแบบ array สามารถนำไปประยุตก์ใช้กับฐานข้อมูลได้
จะมีตัวอย่างการโครงสร้างฐานข้อมูลของตารางเวลา และฟอร์มสำหรับบันทึกข้อมูลเป็นแนวทางให้
ตารางเวลานี้ใช้รูปแบบ css class ของ bootstrap หากนำไปใช้โดยไม่ได้ใช้งานกับ bootstrap เราจำเป็นต้อง
กำหนด style ให้สอดคล้องกับตัวอย่าง เพราะจะแสดงรูปแบบไม่ถูกต้อง
ตัวอย่างการประยุกต์กำหนดรุปแบบ คร่าวๆ เท่านั้น สามารถนำไปปรับแต่ง และให้ได้รูปแบบที่สวยงามเพิ่มเติมได้
ความสามารถและข้อจำกัด
- สามารถดึงข้อมูลจากฐานข้อมูลมาแสดงได้อย่างง่าย โดยใช้รูปแบบตามที่กำหนด
- การแสดงข้อมูลจะเป็นการแสดงข้อมูลของสัปดาห์ ค่าเริ่มต้น เป็นของสัปดาห์ปัจจุบัน ณ ขณะนั้น
- สามารถกำหนดจำนวนวันที่ต้องการแสดงได้ เช่น จ-ศ หรือ จ-อา.
- สามารถเพิ่มฟิลด์ข้อมูลเพิ่มเติมตามต้องการ โดยปรับแก้โค้ดส่วนที่เกี่ยวข้องให้สัมพันธ์กัน
- การเปลี่ยนสัปดาห์ ใช้วิธีส่งวันจันทร์แรกของสัปดาห์ เป็นเงื่อนไขในการแสดงข้อมูล
- สามารถกำหนดช่วงวันที่เริ่มต้น และสิ้นสุด และเลือกวันที่และเวลาที่มีกิจกรรมได้
- หากไม่กำหนดวันทำซ้ำ จะทำซ้ำทุกวันในวันเริ่มต้น จนถึงวันสิ้นสุด
- หากเป็นกิจกรรมวันเดียว ให้เลือกวันที่เริ่มต้น และวันทีสิ้นสุดเป็นวันเดียวกัน ไม่ต้องกำหนดวันทำซ้ำ
- การกำหนดกิจกรรม จะต้องไม่ทับซ้อนกันของช่วงวันที่หรือเวลา
โครงสร้างตาราง tbl_schedule
-- -- Table structure for table `tbl_schedule` -- CREATE TABLE `tbl_schedule` ( `schedule_id` int(11) NOT NULL, `schedule_title` varchar(256) NOT NULL, `schedule_detail` text NOT NULL, `schedule_room` varchar(150) NOT NULL, `schedule_building` varchar(150) NOT NULL, `schedule_startdate` date NOT NULL, `schedule_enddate` date NOT NULL, `schedule_starttime` time NOT NULL, `schedule_endtime` time NOT NULL, `schedule_repeatday` varchar(20) NOT NULL, `schedule_createdate` timestamp NOT NULL DEFAULT current_timestamp() ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -- Indexes for dumped tables -- -- -- Indexes for table `tbl_schedule` -- ALTER TABLE `tbl_schedule` ADD PRIMARY KEY (`schedule_id`); -- -- AUTO_INCREMENT for dumped tables -- -- -- AUTO_INCREMENT for table `tbl_schedule` -- ALTER TABLE `tbl_schedule` MODIFY `schedule_id` int(11) NOT NULL AUTO_INCREMENT; COMMIT;
โครงสร้างข้างต้น ได้เพิ่มฟิลด์ schedule_detail, schedule_room, schedule_building เพิ่มเติมเข้ามา แต่ไม่ได้ใช้งานใน
ฟอร์มตัวอย่าง เป็นเสมือนแนวทาง สำหรับข้อมตารางเรียนเช่น รายละเอียดสำหรับลิ้งค์ไปหน้าใหม่ ห้องเรียน อาคาร เป็นต้น
เราสามารถเพิ่มฟิลด์ข้อมูลอื่นๆ ตามต้องการได้ แต่ฟิลด์หลักที่ไม่ได้กล่าวถึง จำเป็นต้องมี
โค้ดฟอร์มบันทึกข้อมูล Schedule
เมื่อเราได้โครงสร้างตาราง สำหรับใช้ในการบันทึกข้อมูลแล้ว ต่อไป จะเป็นส่วนของฟอร์มสำหรับบันทึกข้อมูล
ในที่นี้จะบันทึกเฉพาะส่วนสำคัญ หากต้องการเพิ่มฟิลด์ใดๆ สามารถปรับได้ตามต้องการ
ไฟล์ form_schedule.php
<?php // โค้ดไฟล์ dbconnect.php ดูได้ที่ http://niik.in/que_2398_5642 require_once("dbconnect.php"); ?> <?php // การบันทึกข้อมูลอย่างง่ายเบื้องตั้น if(isset($_POST['btn_add']) && $_POST['btn_add']!=""){ $p_schedule_title = (isset($_POST['schedule_title']))?$_POST['schedule_title']:""; $p_schedule_startdate = (isset($_POST['schedule_startdate']))?$_POST['schedule_startdate']:"0000-00-00"; $p_schedule_enddate = (isset($_POST['schedule_enddate']))?$_POST['schedule_enddate']:"0000-00-00"; $p_schedule_enddate = ($p_schedule_enddate=="0000-00-00")?$p_schedule_startdate:$p_schedule_enddate; $p_schedule_starttime = (isset($_POST['schedule_starttime']))?$_POST['schedule_starttime']:"00:00:00"; $p_schedule_endtime = (isset($_POST['schedule_endtime']))?$_POST['schedule_endtime']:"00:00:00"; $p_schedule_repeatday = (isset($_POST['schedule_repeatday']))?$_POST['schedule_repeatday']:""; $p_schedule_allday = (isset($_POST['schedule_allday']))?1:0; $sql = " INSERT INTO tbl_schedule SET schedule_title='".$p_schedule_title."', schedule_startdate='".$p_schedule_startdate."', schedule_enddate='".$p_schedule_enddate."', schedule_starttime='".$p_schedule_starttime."', schedule_endtime='".$p_schedule_endtime."', schedule_repeatday='".$p_schedule_repeatday."' "; $mysqli->query($sql); header("Location:form_schedule.php"); exit; } ?> <!DOCTYPE html> <html lang='en'> <head> <meta charset='utf-8' /> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tempusdominus-bootstrap-4/5.1.2/css/tempusdominus-bootstrap-4.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.0-2/css/all.min.css"> <style type="text/css"> .wrap-form{width:800px;margin: auto;} </style> </head> <body> <br> <br> <div class="wrap-form"> <form action="" method="post" accept-charset="utf-8"> <div class="form-group row"> <label for="schedule_title" class="col-sm-2 col-form-label text-right">หัวข้อ</label> <div class="col-12 col-sm-8"> <input type="text" class="form-control" name="schedule_title" autocomplete="off" value="" required> <div class="invalid-feedback"> กรุณากรอก หัวข้อ </div> </div> </div> <div class="form-group row"> <label for="schedule_startdate" class="col-sm-2 col-form-label text-right">วันที่เริ่มต้น</label> <div class="col-12 col-sm-8"> <div class="input-group date" id="schedule_startdate" data-target-input="nearest"> <input type="text" class="form-control datetimepicker-input" name="schedule_startdate" data-target="#schedule_startdate" autocomplete="off" value="" required> <div class="input-group-append" data-target="#schedule_startdate" data-toggle="datetimepicker"> <div class="input-group-text"><i class="far fa-calendar-alt"></i></div> </div> </div> <div class="invalid-feedback"> กรุณากรอก วันที่เริ่มต้น </div> </div> </div> <div class="form-group row"> <label for="schedule_enddate" class="col-sm-2 col-form-label text-right">วันที่สิ้นสุด</label> <div class="col-12 col-sm-8"> <div class="input-group date" id="schedule_enddate" data-target-input="nearest"> <div class="input-group-prepend"> <div class="input-group-text"><i class="far fa-times-circle"></i></div> </div> <input type="text" class="form-control datetimepicker-input" name="schedule_enddate" data-target="#schedule_enddate" autocomplete="off" value="" > <div class="input-group-append" data-target="#schedule_enddate" data-toggle="datetimepicker"> <div class="input-group-text"><i class="far fa-calendar-alt"></i></div> </div> </div> <div class="invalid-feedback"> กรุณากรอก วันที่สิ้นสุด </div> </div> </div> <div class="form-group row"> <label for="schedule_starttime" class="col-sm-2 col-form-label text-right">เวลาเริ่มต้น</label> <div class="col-12 col-sm-8"> <div class="input-group date" id="schedule_starttime" data-target-input="nearest"> <div class="input-group-prepend"> <div class="input-group-text"><i class="far fa-times-circle"></i></div> </div> <input type="text" class="form-control datetimepicker-input" name="schedule_starttime" data-target="#schedule_starttime" autocomplete="off" value="" > <div class="input-group-append" data-target="#schedule_starttime" data-toggle="datetimepicker"> <div class="input-group-text"><i class="far fa-clock"></i></div> </div> </div> <div class="invalid-feedback"> กรุณากรอก เวลาเริ่มต้น </div> </div> </div> <div class="form-group row"> <label for="schedule_endtime" class="col-sm-2 col-form-label text-right">เวลาสิ้นสุด</label> <div class="col-12 col-sm-8"> <div class="input-group date" id="schedule_endtime" data-target-input="nearest"> <div class="input-group-prepend"> <div class="input-group-text"><i class="far fa-times-circle"></i></div> </div> <input type="text" class="form-control datetimepicker-input" name="schedule_endtime" data-target="#schedule_endtime" autocomplete="off" value="" > <div class="input-group-append" data-target="#schedule_endtime" data-toggle="datetimepicker"> <div class="input-group-text"><i class="far fa-clock"></i></div> </div> </div> <div class="invalid-feedback"> กรุณากรอก เวลาสิ้นสุด </div> </div> </div> <div class="form-group row"> <label for="schedule_endtime" class="col-2 col-form-label text-right">ทำซ้ำวัน</label> <div class="col-12 col-sm-10 pt-2"> <?php $dayTH = array('อา.','จ.','อ.','พ.','พฤ.','ศ.','ส.'); ?> <div class="input-group"> <?php foreach($dayTH as $k => $day_value){?> <div class="form-check ml-3" style="width:50px;"> <input class="custom-control-input repeatday_chk" type="checkbox" name="schedule_repeatday_chk" id="schedule_repeatday_chk<?=$k?>" value="<?=$k?>"> <label class="custom-control-label" for="schedule_repeatday_chk<?=$k?>"><?=$day_value?></label> </div> <?php } ?> <input type="hidden" name="schedule_repeatday" id="schedule_repeatday" value="" /> </div> <br> </div> </div> <div class="form-group row"> <div class="col-sm-2 offset-sm-2 text-right pt-3"> <button type="submit" name="btn_add" value="1" class="btn btn-primary btn-block">เพิ่มข้อมูล</button> </div> </div> </form> </div> <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha256-4+XzXVhsDmqanXGHaHvgh1gMQKX40OUvDEBTu8JcmNs=" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.26.0/moment-with-locales.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/tempusdominus-bootstrap-4/5.1.2/js/tempusdominus-bootstrap-4.min.js"></script> <script type="text/javascript"> $(function () { // เมื่อเฃือกวันทำซ้ำ วนลูป สร้างชุดข้อมูล $(document.body).on("change",".repeatday_chk",function(){ $("#schedule_repeatday").val(""); var repeatday_chk = []; $(".repeatday_chk:checked").each(function(k, ele){ repeatday_chk.push($(ele).val()); }); $("#schedule_repeatday").val(repeatday_chk.join(",")); // จะได้ค่าเปน เช่น 1,3,4 }); $('#schedule_startdate,#schedule_enddate').datetimepicker({ format: 'YYYY-MM-DD' }); $('#schedule_starttime,#schedule_endtime').datetimepicker({ format: 'HH:mm' }); $(".input-group-prepend").find("div").css("cursor","pointer").click(function(){ $(this).parents(".input-group").find(":text").val(""); }); }); </script> </body> </html>
ดูตัวอย่างแบบฟอร์มได้ที่ DEMO 1 ด้านล่าง
ไฟล์ตัวอย่างตารางเวลา Schedule
ไฟล์ demo_schedule.php
<?php // โค้ดไฟล์ dbconnect.php ดูได้ที่ http://niik.in/que_2398_5642 require_once("dbconnect.php"); ?> <!DOCTYPE html> <html lang='en'> <head> <meta charset='utf-8' /> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <!-- <meta http-equiv="Content-Security-Policy" content="block-all-mixed-content">--> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tempusdominus-bootstrap-4/5.1.2/css/tempusdominus-bootstrap-4.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.0-2/css/all.min.css"> <title>Document</title> <style type="text/css"> div.table-responsive::-webkit-scrollbar, div.table-responsive::-webkit-scrollbar { width: 10px; height: 2px; } ::-webkit-scrollbar { width: 10px; height: 7px; } ::-webkit-scrollbar-button { width: 0px; height: 0px; } ::-webkit-scrollbar-thumb { background: #CACACA; border: 0px none #CACACA; border-radius: 50px; } ::-webkit-scrollbar-thumb:active { background: #000000; } .wrap_schedule_control{ margin:auto; width:800px; } .wrap_schedule{ cursor: grab; margin:auto; width:800px; } .time_schedule{ font-size:12px; } .day_schedule{ font-size:12px; } .time_schedule_text{ } .day_schedule_text{ width:80px; font-size: 12px; padding: 10px 5px; } .day-head-label{ position: relative; right: 10px; top: 0; } .time-head-label{ position: relative; left: 10px; bottom: 0; } .diagonal-cross{ border-bottom: 2px solid #dee2e6; /* -webkit-transform: translateY(20px) translateX(5px) rotate(26deg); */ position: relative; top: -20px; left: 0; transform: translateY(20px) translateX(5px) rotate(20deg); } .sc-detail{ font-size: 11px; background-color: #63E327; color: #FFFFFF; } .sc-detail a{ color: #FF4F00; font-size: 14px; } </style> </head> <body> <?php // ส่วนของตัวแปรสำหรับกำหนด $dayTH=array("จันทร์","อังคาร","พุธ","พฤหัสบดี","ศุกร์","เสาร์","อาทิตย์"); $monthTH=array( "","มกราคม","กุมภาพันธ์","มีนาคม","เมษายน","พฤษภาคม","มิถุนายน", "กรกฎาคม","สิงหาคม","กันยายน","ตุลาคม","พฤศจิกายน","ธันวาคม" ); $monthTH_brev=array( "","ม.ค.","ก.พ.","มี.ค.","เม.ย.","พ.ค.","มิ.ย.","ก.ค.","ส.ค.","ก.ย.","ต.ค.","พ.ย.","ธ.ค." ); function thai_date_short($time){ // 19 ธ.ค. 2556 global $dayTH,$monthTH_brev; $thai_date_return = date("j",$time); $thai_date_return.=" ".$monthTH_brev[date("n",$time)]; $thai_date_return.= " ".(date("Y",$time)+543); return $thai_date_return; } ////////////////////// ส่วนของการจัดการตารางเวลา ///////////////////// $sc_startTime=date("Y-m-d 08:00:00"); // กำหนดเวลาเริ่มต้ม เปลี่ยนเฉพาะเลขเวลา $sc_endtTime=date("Y-m-d 18:00:00"); // กำหนดเวลาสื้นสุด เปลี่ยนเฉพาะเลขเวลา $sc_t_startTime=strtotime($sc_startTime); $sc_t_endTime=strtotime($sc_endtTime); $sc_numStep="60"; // ช่วงช่องว่างเวลา หน่ายนาที 60 นาที = 1 ชั่วโมง $num_dayShow=5; // จำนวนวันที่โชว์ 1 - 7 $sc_timeStep=array(); $sc_numCol=0; $hour_block_width = 90; ////////////////////// ส่วนของการจัดการตารางเวลา ///////////////////// // ส่วนของการกำหนดวัน สามารถนำไปประยุกต์กรณีทำตารางเวลาแบบ เลื่อนดูแต่ละสัปดาห์ได้ $now_day=date("Y-m-d"); // วันปัจจุบัน ให้แสดงตารางที่มีวันปัจจุบัน เมื่อแสดงครั้งแรก if(isset($_GET['uts']) && $_GET['uts']!=""){ // เมื่อมีการเปลี่ยนสัปดาห์ $now_day=date("Y-m-d",trim($_GET['uts'])); // เปลี่ยนวันที่ แปลงจากค่าวันจันทร์ที่ส่งมา $now_day=date("Y-m-d",strtotime($now_day." monday this week")); } // หาตัวบวก หรือลบ เพื่อหาวันที่ของวันจันทร์ในสัปดาห์ $start_weekDay=date("Y-m-d",strtotime("monday this week")); // หาวันจันทร์ของสัปดาห์ if(isset($_GET['uts']) && $_GET['uts']!=""){ // ถ้ามีส่งค่าเปลี่ยนสัปดาห์มา $start_weekDay=$now_day; // ให้ใช้วันแรก เป็นวันที่ส่งมา } // หววันที่วันอาทิตย์ของสัปดาห์นั้นๆ $end_weekDay=date("Y-m-d",strtotime($start_weekDay." +7 day")); $timestamp_prev=strtotime($start_weekDay." -7 day");// ค่าวันจันทร์ของอาทิตย์ก่อหน้า $timestamp_next=strtotime($start_weekDay." +7 day"); // ค่าวันจันทร์ของอาทิตย์ถัดไป while($sc_t_startTime<=$sc_t_endTime){ $sc_timeStep[$sc_numCol]=date("H:i",$sc_t_startTime); $sc_t_startTime=$sc_t_startTime+($sc_numStep*60); $sc_numCol++; // ได้จำนวนคอลัมน์ที่จะแสดง } function getduration($datetime1, $datetime2){ $datetime1 = (preg_match('/-/',$datetime1))?(int)strtotime($datetime1):(int)$datetime1; $datetime2 = (preg_match('/-/',$datetime2))?(int)strtotime($datetime2):(int)$datetime2; $duration = ($datetime2 >= $datetime1)?$datetime2 - $datetime1:$datetime1 - $datetime2; return $duration; } function timeblock($time,$sc_numCol,$sc_timeStep){ global $sc_numStep; $time = (preg_match('/:/',$time))?(int)strtotime($time):(int)$time; for($i_time=0;$i_time<$sc_numCol-1;$i_time++){ if($time>=strtotime($sc_timeStep[$i_time]) && $time<strtotime($sc_timeStep[$i_time+1])){ if($time>strtotime($sc_timeStep[$i_time]) ){ $duation = getduration($time,strtotime($sc_timeStep[$i_time])); $float_duration = ((($duation/60)*100)/$sc_numStep)*0.01; return $i_time+$float_duration; }else{ return $i_time; } } } } ///////////////// ส่วนของข้อมูล ที่ดึงจากฐานข้อมูบ //////////////////////// $data_schedule=array(); $sql=" SELECT * FROM tbl_schedule WHERE (schedule_startdate >= '".$start_weekDay."' AND schedule_startdate < '".$end_weekDay."') OR ('".$start_weekDay."' > schedule_startdate AND schedule_enddate < '".$end_weekDay."' AND schedule_enddate >= '".$start_weekDay."' ) OR ('".$start_weekDay."' > schedule_startdate AND '".$end_weekDay."' < schedule_enddate AND schedule_enddate >= '".$start_weekDay."' ) ORDER BY schedule_startdate "; $result = $mysqli->query($sql); if($result){ while($row = $result->fetch_assoc()){ $repeat_day = ($row['schedule_repeatday']!="")?explode(",",$row['schedule_repeatday']):[]; $data_schedule[] = array( "id"=>$row['schedule_id'], "start_date"=>$row['schedule_startdate'], "end_date"=>$row['schedule_enddate'], "start_time"=>$row['schedule_starttime'], "end_time"=>$row['schedule_endtime'], "repeat_day"=>$repeat_day, "title"=>$row['schedule_title'], "room"=>"ห้องบรรยาย ", "building"=>"ตึก A" ); } } ///////////////// ส่วนของข้อมูล ที่ดึงจากฐานข้อมูบ //////////////////////// ///////////////// ตัวอย่างรูปแบบข้อมูล ////////////////// /*$demo_year_month=date("Y-m"); $data_schedule=array( array( "id"=>1, "start_date"=>"{$demo_year_month}-12", // รุปแบบ 0000-00-00 "end_date"=>"{$demo_year_month}-21", "start_time"=>"08:00:00", "end_time"=>"09:30:00", "repeat_day"=>array(1,3,5), "title"=>"test data 1", "room"=>"ห้องบรรยาย 1", "building"=>"ตึก A" ), array( "id"=>2, "start_date"=>"{$demo_year_month}-15", "end_date"=>"{$demo_year_month}-21", "start_time"=>"10:00:00", "end_time"=>"11:00:00", "repeat_day"=>array(2,4), "title"=>"test data 2", "room"=>"ห้องบรรยาย 2", "building"=>"ตึก B" ), array( "id"=>3, "start_date"=>"{$demo_year_month}-15", "end_date"=>"{$demo_year_month}-25", "start_time"=>"14:30:00", "end_time"=>"16:00:00", "repeat_day"=>[], "title"=>"test data 3", "room"=>"ห้องบรรยาย 3", "building"=>"ตึก C" ), array( "id"=>4, "start_date"=>"{$demo_year_month}-19", "end_date"=>"{$demo_year_month}-28", "start_time"=>"16:30:00", "end_time"=>"18:00:00", "repeat_day"=>[1,4,5], "title"=>"test data 4", "room"=>"ห้องบรรยาย 4", "building"=>"ตึก D" ), );*/ ///////////////// ตัวอย่างรูปแบบข้อมูล ////////////////// ?> <?php ////////////////////// ส่วนของการจัดรูปแบบข้อมูลก่อนแสดงในตารางเวลา /////////////////////// $data_day_schedule = []; $checkDayKey = ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"]; if(isset($data_schedule) && count($data_schedule)>0){ foreach($data_schedule as $row){ if((strtotime($row['start_date'])>=strtotime($start_weekDay) && strtotime($row['start_date'])<strtotime($end_weekDay)) || (strtotime($start_weekDay)>strtotime($row['start_date']) && strtotime($row['end_date'])<strtotime($end_weekDay) && strtotime($row['end_date'])>=strtotime($start_weekDay) ) || (strtotime($start_weekDay)>strtotime($row['start_date']) && strtotime($end_weekDay)<strtotime($row['end_date']) && strtotime($row['end_date'])>=strtotime($start_weekDay) ) ){ if(isset($row['repeat_day']) && count($row['repeat_day'])>0){ // have day repeat for($i=0;$i<$num_dayShow;$i++){ if(strtotime($start_weekDay." +{$i} day")>=strtotime($row['start_date']) && strtotime($start_weekDay." +{$i} day")<=strtotime($row['end_date'])){ $dayKey = date("D",strtotime($start_weekDay." +{$i} day")); if(in_array($i+1,$row['repeat_day'])){ $data_day_schedule[$dayKey][] = [ "start_time" => $row['start_time'], "end_time" => $row['end_time'], "duration" => getduration(strtotime($row['start_time']),strtotime($row['end_time'])), "timeblock"=> timeblock($row['start_time'],$sc_numCol,$sc_timeStep), "title" => $row['title'], "room" => $row['room'], "building" => $row['building'], ]; } } } }else{ // else repeat all day for($i=0;$i<$num_dayShow;$i++){ if(strtotime($start_weekDay." +{$i} day")>=strtotime($row['start_date']) && strtotime($start_weekDay." +{$i} day")<=strtotime($row['end_date'])){ $dayKey = date("D",strtotime($start_weekDay." +{$i} day")); $data_day_schedule[$dayKey][] = [ "start_time" => $row['start_time'], "end_time" => $row['end_time'], "duration" => getduration(strtotime($row['start_time']),strtotime($row['end_time'])), "timeblock"=> timeblock($row['start_time'],$sc_numCol,$sc_timeStep), "title" => $row['title'], "room" => $row['room'], "building" => $row['building'], ]; } } } } } } ////////////////////// ส่วนของการจัดรูปแบบข้อมูลก่อนแสดงในตารางเวลา /////////////////////// ?> <div class="wrap_schedule_control mt-5"> <div class="d-flex"> <div class="text-left d-flex align-items-center"> <?php $num_dayShow_in_schedule = $num_dayShow-1; ?> ตารางเรียนวันที่ <?=thai_date_short(strtotime($start_weekDay))?> ถึง <?=thai_date_short(strtotime($start_weekDay."+{$num_dayShow_in_schedule} day"))?> </div> <div class="col-auto text-right ml-auto"> <div class="input-group date" id="select_date" data-target-input="nearest"> <input type="text" name="select_date" class="form-control datetimepicker-input d-none" data-target="#select_date"/> <div class="input-group-append" data-target="#select_date" data-toggle="datetimepicker"> <div class="input-group-text"><i class="far fa-calendar-alt"></i></div> </div> </div> </div> <div class="col-auto text-right"> <button class="btn btn-light btn-sm mr-2" type="button" onClick="window.location='demo_schedule.php?uts=<?=$timestamp_prev?>'">< Prev</button> <button class="btn btn-light btn-sm" type="button" onClick="window.location='demo_schedule.php?uts=<?=$timestamp_next?>'">Next ></button> <button class="btn btn-primary btn-sm ml-3" type="button" onClick="window.location='demo_schedule.php'">Home</button> </div> </div> </div> <br> <div class="table-responsive wrap_schedule"> <table class="table table-bordered"> <thead class="thead-light"> <tr class="time_schedule"> <th class="p-0"> <div class="day-head-label text-right"> เวลา </div> <div class="diagonal-cross"></div> <div class="time-head-label text-left"> วัน </div> </th> <?php for($i_time=0;$i_time<$sc_numCol-1;$i_time++){ ?> <th class="px-0 text-nowrap th-time"> <div class="time_schedule_text text-center" style="width: <?=$hour_block_width ?>px;"> <?=$sc_timeStep[$i_time]?> - <?=$sc_timeStep[$i_time+1]?> </div> </th> <?php }?> </tr> </thead> <tbody> <?php // วนลูปแสดงจำนวนวันตามที่กำหนด for($i_day=0;$i_day<$num_dayShow;$i_day++){ $dayInSchedule_chk=date("Y-m-d",strtotime($start_weekDay." +".$i_day." day")); $dayKeyChk = date("D",strtotime($start_weekDay." +".$i_day." day")); // $dayInSchedule_show=date("d-m-Y",strtotime($start_weekDay." +".$i_day." day")); $dayInSchedule_show = thai_date_short(strtotime($start_weekDay." +".$i_day." day")); ?> <tr> <td class="p-0 text-center table-active"> <div class="day_schedule_text text-nowrap" style="min-height: 60px;"> <?=$dayTH[$i_day]?> <br> <?=$dayInSchedule_show?> </div> </td> <td class="p-0 position-relative" colspan="10"> <div class="position-absolute"> <div class="d-flex align-content-stretch" style="min-height: 60px;"> <?php for($i=1;$i<$sc_numCol;$i++){ ?> <div class="bg-light text-center border-right" style="width: <?=$hour_block_width ?>px;margin-right: 1px;"> </div> <?php } ?> </div> </div> <div class="position-absolute" style="z-index: 100;"> <?php if(isset($data_day_schedule[$dayKeyChk]) && count($data_day_schedule[$dayKeyChk])>0){ foreach($data_day_schedule[$dayKeyChk] as $row_day){ $sc_width = ($row_day['duration']/60)*($hour_block_width/$sc_numStep); $sc_start_x = $row_day['timeblock']*$hour_block_width+(int)$row_day['timeblock']; ?> <div class="position-absolute text-center sc-detail" style=" width: <?=$sc_width?>px;margin-right: 1px; margin-left: <?=$sc_start_x?>px; min-height: 60px;"> <a href="#"><?=$row_day['title']?></a><br> <?=$row_day['room']?><br> <?=$row_day['building']?> </div> <?php } ?> <?php } ?> </div> </td> </tr> <?php }?> </tbody> </table> </div> <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha256-4+XzXVhsDmqanXGHaHvgh1gMQKX40OUvDEBTu8JcmNs=" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.26.0/moment-with-locales.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/tempusdominus-bootstrap-4/5.1.2/js/tempusdominus-bootstrap-4.min.js"></script> <script type="text/javascript"> $(function(){ $('#select_date').datetimepicker({ useCurrent:false, locale: 'th', format: 'YYYY-MM-DD' }); $('#select_date').on('change.datetimepicker',function(e){ window.location='demo_schedule.php?uts='+e.date.format("X"); }); }); </script> <script type="text/javascript"> // ส่วนของ script สำหรับให้สามารถลากตารางเวลา ซ้ายขวา โดยไม่ต้องเลื่อน scroll bar document.addEventListener('DOMContentLoaded', function() { const ele = document.querySelector('.wrap_schedule'); ele.style.cursor = 'grab'; let pos = { top: 0, left: 0, x: 0, y: 0 }; const mouseDownHandler = function(e) { ele.style.cursor = 'grabbing'; ele.style.userSelect = 'none'; pos = { left: ele.scrollLeft, top: ele.scrollTop, // Get the current mouse position x: e.clientX, y: e.clientY, }; document.addEventListener('mousemove', mouseMoveHandler); document.addEventListener('mouseup', mouseUpHandler); }; const mouseMoveHandler = function(e) { // How far the mouse has been moved const dx = e.clientX - pos.x; const dy = e.clientY - pos.y; // Scroll the element ele.scrollTop = pos.top - dy; ele.scrollLeft = pos.left - dx; }; const mouseUpHandler = function() { ele.style.cursor = 'grab'; ele.style.removeProperty('user-select'); document.removeEventListener('mousemove', mouseMoveHandler); document.removeEventListener('mouseup', mouseUpHandler); }; // Attach the handler ele.addEventListener('mousedown', mouseDownHandler); }); </script> </body> </html>
ดูตัวอย่างได้ที่ DEMO 2 จะแสดงตัวอย่างเฉพาะของเดือนปัจจุบันเท่านั้น
หวังว่าแนวทางข้างต้น จะสามารถนำไปประยุกต์ ปรับแต่ง ใช้งานเพิ่มเติมต่อไป