Monday 21 February 2022

Pass data from the model to js for a specific day and time

I have a model in which we can choose the opening hours of the institution for each day of the week, from such and such to such and such, for example Monday 12:00 AM - 11:30 PM

<?php

namespace common\models;

use yii\behaviors\TimestampBehavior;
use yii\db\ActiveRecord;
use yii\db\Expression;

class WorkHours extends _source_WorkHours
{
    public const WEEK_DAY_MON = 'Mon';
    public const WEEK_DAY_TUE = 'Tue';
    public const WEEK_DAY_WED = 'Wed';
    public const WEEK_DAY_THU = 'Thu';
    public const WEEK_DAY_FRI = 'Fri';
    public const WEEK_DAY_SAT = 'Sat';
    public const WEEK_DAY_SUN = 'Sun';


    /**
     * {@inheritdoc}
     */
    public function behaviors(): array
    {
        return [
            'timestamp' => [
                'class'      => TimestampBehavior::class,
                'attributes' => [
                    ActiveRecord::EVENT_BEFORE_INSERT => ['created_at'],
                ],
                'value'      => new Expression('NOW()'),
            ],
        ];
    }

    public static function weekDays(): array
    {
        return [
            self::WEEK_DAY_MON => 'Monday',
            self::WEEK_DAY_TUE => 'Tuesday',
            self::WEEK_DAY_WED => 'Wednesday',
            self::WEEK_DAY_THU => 'Thursday',
            self::WEEK_DAY_FRI => 'Friday',
            self::WEEK_DAY_SAT => 'Saturday',
            self::WEEK_DAY_SUN => 'Sunday',
        ];
    }

    public static function getWeekDay(string $val): string
    {
        $ar = self::weekDays();

        return $ar[$val] ?? $val;
    }

    public static function hoursList(): array
    {
        $list = [];
        for ($i = 0; $i < 24; $i++) {
            $A = 'AM';
            $n = $i;
            if ($i >= 12) {
                $A = 'PM';
                $n = $i - 12;
            }

            $n = $n < 10 ? '0' . $n : $n;
            $_A = ($i === 12 ? 'AM' : $A);
            $list[$i . '.00'] = $n . '.00 ' . ($i === 0 ? 'PM' : $_A);
            $list[$i . '.30'] = $n . '.30 ' . $A;
        }
        return $list;
    }
}

Next, using the script, we pass all these fields, and in the end we can select any day, at any time, from 00:00 PM to 11:30 PM

$this->registerJsFile('/js/restaurant-reserve.js', ['depends' => [JqueryAsset::class]]);
$this->registerJs('restaurantReserve.init()');

<a class="btn btn-fourth <?= $restaurantReservationForm->getErrors('date') ? 'btn-error' : '' ?>" id="reservation-date" data-date="<?= $restaurantReservationForm->getDate()
                   ? $restaurantReservationForm->getDate()->format('m/d/Y') : '' ?>>">
  <span class="icon br-calender"></span> <span class="js-value">
                    <?= $restaurantReservationForm->date
                        ? (new DateTime($restaurantReservationForm->date))->format('d M') : '-- ---' ?>
                </span>
</a>
<a class="btn btn-fourth <?= $restaurantReservationForm->getErrors('time') ? 'btn-error' : '' ?>" id="reservation-time" role="button" data-bs-toggle="dropdown" aria-expanded="false">
  <span class="icon br-clock"></span> <span class="js-value">
                    <?= $restaurantReservationForm->time
                        ? WorkHours::hoursList()[$restaurantReservationForm->time] : '-- : --' ?>
                </span>
</a>
<ul class="dropdown-menu dropdown-menu-height-fixed" aria-labelledby="reservation-time">
  <?php foreach (WorkHours::hoursList() as $k => $v) { ?>
    <li>
      <a class="dropdown-item <?= $restaurantReservationForm->time === $k ? 'active' : ''
                        ?>" href="#" data-value="<?= $k ?>">
        <?= $v ?>
      </a>
    </li>
    <?php } ?>
</ul>

Here is the script

let restaurantReserve = {
    init: function () {
        let _self = this;

        $('#reservation-date').datepicker({startDate: '+0d'}).on('changeDate', function (e) {
            const arDate = e.date.toString().split(' ');
            let input = $('[name="RestaurantReservationForm[date]"]');
            input.val(arDate[3] + '-' + (e.date.getMonth() + 1) + '-' + arDate[2]);
            _self.unSetError(input);
            $('#reservation-date .js-value').text(arDate[2] + ' ' + arDate[1]);
        });

        $('[aria-labelledby="reservation-time"] li a').click(function () {
            $(this).closest('ul').find('a').removeClass('active');
            $(this).addClass('active');
            let input = $('[name="RestaurantReservationForm[time]"]');
            input.val($(this).data('value'));
            _self.unSetError(input);
            $('#reservation-time .js-value').text($(this).text());
        });

        $('[aria-labelledby="reservation-person"] li a').click(function () {
            $(this).closest('ul').find('a').removeClass('active');
            $(this).addClass('active');
            let input = $('[name="RestaurantReservationForm[personCount]"]');
            input.val($(this).data('value'));
            _self.unSetError(input);
            $('#reservation-person .js-value').text($(this).data('value'));
        });
    },
    setError: function (ob) {
        $('#' + ob.data('btnId')).addClass('btn-error');
    },
    unSetError: function (ob) {
        $('#' + ob.data('btnId')).removeClass('btn-error');
    }
}

I have different establishments and each establishment has its own working hours. And I need to have a choice of time for a particular institution on a particular day. Let's say one establishment on Monday has a working time from 9:30 AM to 2.30 PM, as a result, the select should have a choice of time only in this interval.

What am I trying to do

To begin with, pass data from the database to the init function via json

$this->registerJs('restaurantReserve.init('. Json::encode($restaurant->workHours) .')');

As a result, we pass data to the script in the form of an array with a database [{"id":"1","restaurant_id":"1","day":"Mon","open":"9.30","close":"14.30","created_at":"2022-02-15 05:00:57"}]

Here's the plug, I have the necessary data, it remains only to add the script so that for each day there is a time interval taken from this data

I need another function like

restaurantDate: function (e) {
        .....
    }

But what to do in it, I still do not quite understand

let restaurantReserve = {
    init: function () {
        let _self = this;

        $('#reservation-date').datepicker({startDate: '+0d'}).on('changeDate', function (e) {
            const arDate = e.date.toString().split(' ');
            let input = $('[name="RestaurantReservationForm[date]"]');
            input.val(arDate[3] + '-' + (e.date.getMonth() + 1) + '-' + arDate[2]);
            _self.unSetError(input);
            $('#reservation-date .js-value').text(arDate[2] + ' ' + arDate[1]);
        });

        $('[aria-labelledby="reservation-time"] li a').click(function () {
            $(this).closest('ul').find('a').removeClass('active');
            $(this).addClass('active');
            let input = $('[name="RestaurantReservationForm[time]"]');
            input.val($(this).data('value'));
            _self.unSetError(input);
            $('#reservation-time .js-value').text($(this).text());
        });

        $('[aria-labelledby="reservation-person"] li a').click(function () {
            $(this).closest('ul').find('a').removeClass('active');
            $(this).addClass('active');
            let input = $('[name="RestaurantReservationForm[personCount]"]');
            input.val($(this).data('value'));
            _self.unSetError(input);
            $('#reservation-person .js-value').text($(this).data('value'));
        });
    },
    setError: function (ob) {
        $('#' + ob.data('btnId')).addClass('btn-error');
    },
    unSetError: function (ob) {
        $('#' + ob.data('btnId')).removeClass('btn-error');
    }
}
.btn {
    border: none;
    border-radius: 8px;
    height: 40px;
    padding: 10px 15px;
    font-weight: 800;
    font-size: 14px;
    margin-right: 10px;
    cursor: pointer;
}

.btn-fourth {
    text-decoration: none;
    background: #e3e5e8;
    color: #747b8b;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="reservation" action="/restaurants/123/" method="post">
   <div class="block-shadow block-white mb-4">
        <h5 class="fw-bold mb-3">Reserve a table</h5>
        <div class="btn-s">
            <a class="btn btn-fourth "
               id="reservation-date"
               data-date=">">
                <span class="icon br-calender"></span> <span class="js-value">
                    -- ---                </span>
            </a>
            <a class="btn btn-fourth "
               id="reservation-time" role="button" data-bs-toggle="dropdown" aria-expanded="false">
                <span class="icon br-clock"></span> <span class="js-value">
                    -- : --                </span>
            </a>
            <ul class="dropdown-menu dropdown-menu-height-fixed" aria-labelledby="reservation-time">
                                    <li><a class="dropdown-item " href="#" data-value="0.00">00.00 PM</a></li>
                                    <li><a class="dropdown-item " href="#" data-value="0.30">00.30 AM</a></li>
                                    <li><a class="dropdown-item " href="#" data-value="1.00">01.00 AM</a></li>
                                    <li><a class="dropdown-item " href="#" data-value="1.30">01.30 AM</a></li>
                                    <li><a class="dropdown-item " href="#" data-value="2.00">02.00 AM</a></li>
                                    <li><a class="dropdown-item " href="#" data-value="2.30">02.30 AM</a></li>
                                    <li><a class="dropdown-item " href="#" data-value="3.00">03.00 AM</a></li>
                                    <li><a class="dropdown-item " href="#" data-value="3.30">03.30 AM</a></li>
                                    <li><a class="dropdown-item " href="#" data-value="4.00">04.00 AM</a></li>
                                    <li><a class="dropdown-item " href="#" data-value="4.30">04.30 AM</a></li>
                                    <li><a class="dropdown-item " href="#" data-value="5.00">05.00 AM</a></li>
                                    <li><a class="dropdown-item " href="#" data-value="5.30">05.30 AM</a></li>
                                    <li><a class="dropdown-item " href="#" data-value="6.00">06.00 AM</a></li>
                                    <li><a class="dropdown-item " href="#" data-value="6.30">06.30 AM</a></li>
                                    <li><a class="dropdown-item " href="#" data-value="7.00">07.00 AM</a></li>
                                    <li><a class="dropdown-item " href="#" data-value="7.30">07.30 AM</a></li>
                                    <li><a class="dropdown-item " href="#" data-value="8.00">08.00 AM</a></li>
                                    <li><a class="dropdown-item " href="#" data-value="8.30">08.30 AM</a></li>
                                    <li><a class="dropdown-item " href="#" data-value="9.00">09.00 AM</a></li>
                                    <li><a class="dropdown-item " href="#" data-value="9.30">09.30 AM</a></li>
                                    <li><a class="dropdown-item " href="#" data-value="10.00">10.00 AM</a></li>
                                    <li><a class="dropdown-item " href="#" data-value="10.30">10.30 AM</a></li>
                                    <li><a class="dropdown-item " href="#" data-value="11.00">11.00 AM</a></li>
                                    <li><a class="dropdown-item " href="#" data-value="11.30">11.30 AM</a></li>
                                    <li><a class="dropdown-item " href="#" data-value="12.00">00.00 AM</a></li>
                                    <li><a class="dropdown-item " href="#" data-value="12.30">00.30 PM</a></li>
                                    <li><a class="dropdown-item " href="#" data-value="13.00">01.00 PM</a></li>
                                    <li><a class="dropdown-item " href="#" data-value="13.30">01.30 PM</a></li>
                                    <li><a class="dropdown-item " href="#" data-value="14.00">02.00 PM</a></li>
                                    <li><a class="dropdown-item " href="#" data-value="14.30">02.30 PM</a></li>
                                    <li><a class="dropdown-item " href="#" data-value="15.00">03.00 PM</a></li>
                                    <li><a class="dropdown-item " href="#" data-value="15.30">03.30 PM</a></li>
                                    <li><a class="dropdown-item " href="#" data-value="16.00">04.00 PM</a></li>
                                    <li><a class="dropdown-item " href="#" data-value="16.30">04.30 PM</a></li>
                                    <li><a class="dropdown-item " href="#" data-value="17.00">05.00 PM</a></li>
                                    <li><a class="dropdown-item " href="#" data-value="17.30">05.30 PM</a></li>
                                    <li><a class="dropdown-item " href="#" data-value="18.00">06.00 PM</a></li>
                                    <li><a class="dropdown-item " href="#" data-value="18.30">06.30 PM</a></li>
                                    <li><a class="dropdown-item " href="#" data-value="19.00">07.00 PM</a></li>
                                    <li><a class="dropdown-item " href="#" data-value="19.30">07.30 PM</a></li>
                                    <li><a class="dropdown-item " href="#" data-value="20.00">08.00 PM</a></li>
                                    <li><a class="dropdown-item " href="#" data-value="20.30">08.30 PM</a></li>
                                    <li><a class="dropdown-item " href="#" data-value="21.00">09.00 PM</a></li>
                                    <li><a class="dropdown-item " href="#" data-value="21.30">09.30 PM</a></li>
                                    <li><a class="dropdown-item " href="#" data-value="22.00">10.00 PM</a></li>
                                    <li><a class="dropdown-item " href="#" data-value="22.30">10.30 PM</a></li>
                                    <li><a class="dropdown-item " href="#" data-value="23.00">11.00 PM</a></li>
                                    <li><a class="dropdown-item " href="#" data-value="23.30">11.30 PM</a></li>
                            </ul>
        </div>
        <div class="form-group field-restaurantreservationform-personcount">
<input type="hidden" id="restaurantreservationform-personcount" class="form-control" name="RestaurantReservationForm[personCount]" data-btn-id="reservation-person">
</div>        <div class="form-group field-restaurantreservationform-date required">
<input type="hidden" id="restaurantreservationform-date" class="form-control" name="RestaurantReservationForm[date]" data-btn-id="reservation-date">
</div>        <div class="form-group field-restaurantreservationform-time">
<input type="hidden" id="restaurantreservationform-time" class="form-control" name="RestaurantReservationForm[time]" data-btn-id="reservation-time">
</div>        <div class="form-group field-restaurantreservationform-name required">
<label class="control-label" for="restaurantreservationform-name">Your Name</label>
<input type="text" id="restaurantreservationform-name" class="form-control" name="RestaurantReservationForm[name]" aria-required="true">

<p class="help-block help-block-error"></p>
</div>        <div class="form-group field-restaurantreservationform-emailphone required">
<label class="control-label" for="restaurantreservationform-emailphone">Email Address or Phone Number</label>
<input type="text" id="restaurantreservationform-emailphone" class="form-control" name="RestaurantReservationForm[emailPhone]" aria-required="true">


from Pass data from the model to js for a specific day and time

No comments:

Post a Comment