首页 > 解决方案 > 如何根据特定服务进行时隙多选

问题描述

我需要你的帮助来解决以下问题。我是 PHP 新手,我正在为一个提供用户预订服务的网站构建一个预订日历,我的网站是一个水疗网站,所以我的任务是制作一个带有时间段的日历,我制作了日历和时间段,问题是如何根据特定服务使时隙多选。
例如,我有三个服务:

  1. 服务1
  2. 服务 2
  3. 服务 3

例如,用户选择服务1 ,可以在一个时段预订3或4次,以此类推。

我希望我能解释我的问题。

这是我的时隙代码和输出:

<?php
    if (isset($_GET['date'])) {
        $date = $_GET['date'];
    }


    // Making Timelots >> Part 3
    $duration = 90;
    $cleanup = 30;
    $start = "10:00";
    $end = '24:00';

    function timeslots($duration, $cleanup, $start, $end)
    {
        $start = new DateTime($start);
        $end = new DateTime($end);
        $interval = new DateInterval('PT' . $duration . 'M');
        $cleanupinterval = new DateInterval('PT' . $cleanup . 'M');
        $slots = array();

        for ($intStart = $start; $intStart < $end; $intStart->add($interval)->add($cleanupinterval)) {
            $endperiod = clone $intStart;
            $endperiod->add($interval);
            if ($endperiod > $end) {
                break;
            }
            $slots[] = $intStart->format('H:iA') . '-' . $endperiod->format('H:iA');
        }

        return $slots;
    }

    ?>
    <!doctype html>
    <html lang="en">

    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title></title>
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">
        <style>
            @media only screen and (max-width: 760px),
            (min-device-width: 802px) and (max-device-width: 1020px) {

                /* Force table to not be like tables anymore */
                table,
                thead,
                tbody,
                th,
                td,
                tr {
                    display: block;

                }

                .empty {
                    display: none;
                }

                /* Hide table headers (but not display: none;, for accessibility) */
                th {
                    position: absolute;
                    top: -9999px;
                    left: -9999px;
                }

                tr {
                    border: 1px solid #ccc;
                }

                td {
                    /* Behave  like a "row" */
                    border: none;
                    border-bottom: 1px solid #eee;
                    position: relative;
                    padding-left: 50%;
                }



                /*
    Label the data
    */
                td:nth-of-type(1):before {
                    content: "Sunday";
                }

                td:nth-of-type(2):before {
                    content: "Monday";
                }

                td:nth-of-type(3):before {
                    content: "Tuesday";
                }

                td:nth-of-type(4):before {
                    content: "Wednesday";
                }

                td:nth-of-type(5):before {
                    content: "Thursday";
                }

                td:nth-of-type(6):before {
                    content: "Friday";
                }

                td:nth-of-type(7):before {
                    content: "Saturday";
                }


            }

            /* Smartphones (portrait and landscape) ----------- */

            @media only screen and (min-device-width: 320px) and (max-device-width: 480px) {
                body {
                    padding: 0;
                    margin: 0;
                }
            }

            /* iPads (portrait and landscape) ----------- */

            @media only screen and (min-device-width: 802px) and (max-device-width: 1020px) {
                body {
                    width: 495px;
                }
            }

            @media (min-width:641px) {
                table {
                    table-layout: fixed;
                }

                td {
                    width: 33%;
                }
            }

            .row {
                margin-top: 20px;
            }

            .today {
                background: yellow;
            }
        </style>
    </head>

    <body>
        <div class="container">
            <h1 class="text-center">Book for Date: <?php echo date('m/d/Y', strtotime($date)); ?></h1>
            <hr>
            <div class="row">
                <!-- part 4 -->
                <div class="col-md-12">
                    <?php echo isset($msg) ? $msg : ''; ?>
                </div>
                <!-- Part 3 -->
                <?php
                $timesolts = timeslots($duration, $cleanup, $start, $end);
                foreach ($timesolts as $ts) {
                ?>
                    <div class="col-2">
                        <div class="form-group">
                            <button class="btn btn-success book" data-timeslot="<?php echo $ts; ?>"><?php echo $ts; ?></button>
                        </div>
                    </div>
                <?php } ?>
            </div>
        </div>

        <!-- Modal Part 4 -->
        <div id="myModal" class="modal fade" role="dialog">
            <div class="modal-dialog">
                <!-- Modal content-->
                <div class="modal-content">
                    <div class="modal-header">
                        <button type="button" class="close" data-dismiss="modal">&times;</button>
                        <h4 class="modal-title">Booking: <span id="slot"></span></h4>
                    </div>
                    <div class="modal-body">
                        <div class="row">
                            <div class="col-md-12">
                                <form action="" method="POST">
                                    <div class="form-group">
                                        <label for="">Time Slot</label>
                                        <input required type="text" readonly name="timeslot" id="timeslot" class="form-control">
                                    </div>
                                    <div class="form-group">
                                        <label for="">services</label>
                                        <input required type="text" readonly name="service" id="service" class="form-control">
                                    </div>
                                    <div class="form-group">
                                        <label for="name">Name</label>
                                        <input required type="text" name="name" class="form-control">
                                    </div>
                                    <div class="form-group">
                                        <label for="email">Email</label>
                                        <input required type="email" name="email" class="form-control">
                                    </div>
                                    <div class="form-group pull-right">
                                        <button class="btn btn-primary" type="submit" name="submit">Submit</button>
                                    </div>
                                </form>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.bundle.min.js" integrity="sha384-LtrjvnR4Twt/qOuYxE721u19sVFLVSA4hf/rRt6PrZTmiPltdZcI7q7PXQBYTKyf" crossorigin="anonymous"></script>
        <script>
            $(function() {
                'use strict';
                $('.book').click(function() {
                    var timeslot = $(this).attr('data-timeslot');
                    $('#slot').html(timeslot);
                    $('#timeslot').val(timeslot);
                    $('#myModal').modal('show');
                });
            });
        </script>
    </body>

    </html>

输出是这样的: 查看这张图片

如何解决这个问题呢?

标签: phpcalendar

解决方案


不要使用按钮来选择时间,而是使用复选框。它是适合这项工作的工具,因为它允许您选择和取消选择多个选项。

另外,通过一些 CSS 魔法,您可以通过设置复选框标签的样式使它们看起来像按钮。

查看下面的示例以查看这些复选框的输出。

编辑

您可以使用的一种模式是让<fieldset>元素与嵌套复选框配对以<legend>组成字段组。通过这种方式,您可以按时间段展示您的房间,并让用户以这种方式选择它们。它使表单非常灵活,因为您可以轻松控制将哪些数据发送到服务器。

要检查时间段是否有任何可用房间,您可以设置一个标志(真或假)并将其存储在每个时间段中。然后,当您将表单发送到后端时,它将检查是否已为该时间段预订了所有房间。如果他们有,例如$is_available价值将是假的。然后可以在模板中读取该值。

const form = document.querySelector('#room-form');

form.addEventListener('change', ({ target }) => {
  if (target.classList.contains('timeslot')) {
    const fieldset = target.closest('fieldset');
    fieldset.disabled = !target.checked;
    if (!target.checked) {
      const inputs = fieldset.querySelectorAll('input[type="checkbox"]');
      for (const input of inputs) {
        input.checked = false;
      }
    }
  }
});

/* Just for demonstration purposes */
form.addEventListener('submit', event => {
  const formData = new FormData(event.target);
  console.clear();
  for (const [ name, value ] of formData) {
    console.log('Name:', name, '-', 'Value:', value);
  }
  event.preventDefault();
});
/* Just for demonstration purposes */
form {
  display: flex;
  flex-wrap: wrap;
}

fieldset {
  flex: 1;
  border-radius: 3px;
  border: 1px solid #d0d0d0;
  background-color: #f0f0f0;
}

fieldset legend label {
  cursor: pointer;
  display: block;
  font-family: sans-serif;
  border: 1px solid #d0d0d0;
  border-radius: 3px;
  background-color: #f0f0f0;
  padding: 0.5rem;
}

fieldset legend label:hover {
  background-color: #d9d9d9;
}

fieldset:disabled .room label {
  opacity: 0.5;
}

button {
  flex: 1 1 100%;
  appearance: none;
  padding: 1rem;
  border-radius: 3px;
  border: 1px solid #d0d0d0;
  cursor: pointer;
  margin-top: 15px;
}

.room {
  display: block;
  margin: 0.5rem 1rem 0.5rem 0;
}

.room input {
  display: none;
}

.room label {
  font-family: sans-serif;
  display: block;
  background-color: #f7f7f7;
  padding: 1rem;
  border-radius: 3px;
  border: 1px solid #d0d0d0;
  cursor: pointer;
}

.room input:checked + label {
  background-color: green;
  border-color: green;
  color: white;
}
<form id="room-form">
  <fieldset disabled>
    <legend><label>10:00 - 12:00<input class="timeslot" type="checkbox" name="timeslot-10-12"/></label></legend>
    <div class="room">
      <input type="checkbox" id="room-1-10-12" name="timeslot-10-12-room" value="1"/>
      <label for="room-1-10-12">Room 1</label>
    </div>
    <div class="room">
      <input type="checkbox" id="room-2-10-12" name="timeslot-10-12-room" value="2"/>
      <label for="room-2-10-12">Room 2</label>
    </div>
    <div class="room">
      <input type="checkbox" id="room-3-10-12" name="timeslot-10-12-room" value="3"/>
      <label for="room-3-10-12">Room 3</label>
    </div>
    <div class="room">
      <input type="checkbox" id="room-4-10-12" name="timeslot-10-12-room" value="4"/>
      <label for="room-4-10-12">Room 4</label>
    </div>
  </fieldset>
  <fieldset disabled>
    <legend><label>12:00 - 14:00<input class="timeslot" type="checkbox" name="timeslot-12-14"/></label></legend>
    <div class="room">
      <input type="checkbox" id="room-1-12-14" name="timeslot-12-14-room" value="1"/>
      <label for="room-1-12-14">Room 1</label>
    </div>
    <div class="room">
      <input type="checkbox" id="room-2-12-14" name="timeslot-12-14-room" value="2"/>
      <label for="room-2-12-14">Room 2</label>
    </div>
    <div class="room">
      <input type="checkbox" id="room-3-12-14" name="timeslot-12-14-room" value="3"/>
      <label for="room-3-12-14">Room 3</label>
    </div>
    <div class="room">
      <input type="checkbox" id="room-4-12-14" name="timeslot-12-14-room" value="4"/>
      <label for="room-4-12-14">Room 4</label>
    </div>
  </fieldset>
  <fieldset disabled>
    <legend><label>14:00 - 16:00<input class="timeslot" type="checkbox" name="timeslot-14-16"/></label></legend>
    <div class="room">
      <input type="checkbox" id="room-1-14-16" name="timeslot-14-16-room" value="1"/>
      <label for="room-1-14-16">Room 1</label>
    </div>
    <div class="room">
      <input type="checkbox" id="room-2-14-16" name="timeslot-14-16-room" value="2"/>
      <label for="room-2-14-16">Room 2</label>
    </div>
    <div class="room">
      <input type="checkbox" id="room-3-14-16" name="timeslot-14-16-room" value="3"/>
      <label for="room-3-14-16">Room 3</label>
    </div>
    <div class="room">
      <input type="checkbox" id="room-4-14-16" name="timeslot-14-16-room" value="4"/>
      <label for="room-4-14-16">Room 4</label>
    </div>
  </fieldset>
  <button>Submit</button>
</form>


推荐阅读