Explore all Datepicker open source software, libraries, packages, source code, cloud functions and APIs.

Popular New Releases in Datepicker

ng-bootstrap

12.0.1

react-datepicker

4.6.0

ngx-bootstrap

v8.0.0

AndroidPicker

4.1.6

react-day-picker

v8.0.4

Popular Libraries in Datepicker

Android-PickerView

by Bigkoo doticonjavadoticon

star image 12799 doticonApache-2.0

This is a picker view for android , support linkage effect, timepicker and optionspicker.(时间选择器、省市区三级联动)

react-dates

by airbnb doticonjavascriptdoticon

star image 11488 doticonMIT

An easily internationalizable, mobile-friendly datepicker library for the web

ng-bootstrap

by ng-bootstrap doticontypescriptdoticon

star image 7904 doticonMIT

Angular powered Bootstrap

pickadate.js

by amsul doticonjavascriptdoticon

star image 7749 doticonMIT

The mobile-friendly, responsive, and lightweight jQuery date & time input picker.

react-datepicker

by Hacker0x01 doticonjavascriptdoticon

star image 6462 doticonMIT

A simple and reusable datepicker component for React

ngx-bootstrap

by valor-software doticontypescriptdoticon

star image 5363 doticonMIT

Fast and reliable Bootstrap widgets in Angular (supports Ivy engine)

AndroidPicker

by gzu-liyujiang doticonjavadoticon

star image 5358 doticonNOASSERTION

安卓选择器类库,包括日期及时间选择器(可用于出生日期、营业时间等)、单项选择器(可用于性别、民族、职业、学历、星座等)、二三级联动选择器(可用于车牌号、基金定投日期等)、城市地址选择器(分省级、地市级及区县级)、数字选择器(可用于年龄、身高、体重、温度等)、日历选日期择器(可用于酒店及机票预定日期)、颜色选择器、文件及目录选择器、图片选择器等……WheelPicker/DatePicker/TimePicker/OptionPicker/NumberPicker/LinkagePicker/AddressPicker/CarPlatePicker/CalendarPicker/ColorPicker/FilePicker/ImagePicker etc.

react-day-picker

by gpbl doticontypescriptdoticon

star image 4465 doticonMIT

Date picker component for React.

react-infinite-calendar

by clauderic doticonjavascriptdoticon

star image 3776 doticonMIT

✨ Infinite scrolling date-picker built with React, with localization, range selection, themes, keyboard support, and more.

Trending New libraries in Datepicker

DateTimePicker

by loperSeven doticonkotlindoticon

star image 644 doticon

:star::tada:一个高颜值日期时间选择器;极简API,内置弹窗,支持农历日期显示,可动态配置样式及主题,选择器支持完全自定义UI。

MDatePickerView

by MattLLLLL doticonswiftdoticon

star image 378 doticonMIT

Quick and easy date picker.

XPopupExt

by li-xiaojun doticonjavadoticon

star image 133 doticon

XPopup扩展功能库,基于XPopup强大的弹窗能力和PickerView的选择器逻辑,封装了时间选择器弹窗和城市选择器弹窗。

react-multi-date-picker

by shahabyazdi doticonjavascriptdoticon

star image 109 doticonMIT

a simple React datepicker component for working with gregorian, persian, arabic and indian calendars

SharpChisel

by shantanu561993 doticongodoticon

star image 96 doticon

C# Wrapper around Chisel from https://github.com/jpillora/chisel

persian-mobile-datepicker

by persian-tools doticontypescriptdoticon

star image 80 doticonMIT

Modern React Persian Mobile Date and Time picker

better-datepicker

by jumodada doticontypescriptdoticon

star image 64 doticonMIT

A PC Datepicker with only 9KB

react-native-jalali-datepicker

by MohamadKh75 doticonjavascriptdoticon

star image 53 doticonMIT

📅 React Native Jalali DatePicker component for both Android and iOS ✨

react-jewish-datepicker

by Shmulik-Kravitz doticontypescriptdoticon

star image 35 doticonGPL-3.0

React jewish datepicker

Top Authors in Datepicker

1

rajeshwarpatlolla

3 Libraries

star icon700

2

kekeh

3 Libraries

star icon838

3

Velg03961485

2 Libraries

star icon5

4

saeidrnb

2 Libraries

star icon34

5

nathancahill

2 Libraries

star icon7

6

contao-components

2 Libraries

star icon8

7

zigomir

2 Libraries

star icon142

8

Gillardo

2 Libraries

star icon340

9

sinankeskin

2 Libraries

star icon8

10

jkuri

2 Libraries

star icon93

1

3 Libraries

star icon700

2

3 Libraries

star icon838

3

2 Libraries

star icon5

4

2 Libraries

star icon34

5

2 Libraries

star icon7

6

2 Libraries

star icon8

7

2 Libraries

star icon142

8

2 Libraries

star icon340

9

2 Libraries

star icon8

10

2 Libraries

star icon93

Trending Kits in Datepicker

No Trending Kits are available at this moment for Datepicker

Trending Discussions on Datepicker

Datepicker not working / showing - Bootstrap 5

The unauthenticated git protocol on port 9418 is no longer supported

How to change the date picker from spinner to calendar dialogue in Android Kotlin

Use selected element when selector allow for multiple options

Dynamic form returns the same value for the first and second input

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

Module not found: Error: Can't resolve 'date-fns/addDays' in 'C:\Users\

Why does MUI DatePicker prevent rendering in my project (working sandbox MRE included?)

Using the MUI DatePicker with yup and react-hook-form - the error prop doesn't work as intended

JavaFX: Exception in Application Start Method java.lang.reflect.InvocationTargetException

QUESTION

Datepicker not working / showing - Bootstrap 5

Asked 2022-Apr-05 at 03:48

I am trying to add a timepicker to my page using bootstrap 5, for some reason the calendar is not loading so I can not pick any date. I do not know if I have done something wrong or the plugin is not compatible with the latest version of bootstrap.

If you click 'launch demo modal' you will see the date input field and datepicker is not working there.

enter image description here

This is the code for the input date field:

1<div class="col-12">
2    <label for="date" class="col-sm-1 col-form-label">Date</label>
3    <div class="input-group date" id="datepicker">
4        <input type="text" class="form-control">
5        <span class="input-group-append">
6        <span class="input-group-text bg-white d-block">
7        <i class="fa fa-calendar"></i>
8        </span>
9        </span>
10    </div>
11</div>    
12

JS (truncated):

1<div class="col-12">
2    <label for="date" class="col-sm-1 col-form-label">Date</label>
3    <div class="input-group date" id="datepicker">
4        <input type="text" class="form-control">
5        <span class="input-group-append">
6        <span class="input-group-text bg-white d-block">
7        <i class="fa fa-calendar"></i>
8        </span>
9        </span>
10    </div>
11</div>    
12<script type="text/javascript">
13    $(document).ready(function () {
14        $('#datepicker').datepicker();
15        ...
16    });
17</script>      
18

I also tried using $('.datepicker').datepicker(); according to the bootstrap-datepicker docs but nothing changed.

ANSWER

Answered 2021-Oct-29 at 06:00

Demo page

Stackoverflow source

You should put bootstrap-datepicker.min.js after jquery.js. It somehow make errors because of that.

1<div class="col-12">
2    <label for="date" class="col-sm-1 col-form-label">Date</label>
3    <div class="input-group date" id="datepicker">
4        <input type="text" class="form-control">
5        <span class="input-group-append">
6        <span class="input-group-text bg-white d-block">
7        <i class="fa fa-calendar"></i>
8        </span>
9        </span>
10    </div>
11</div>    
12<script type="text/javascript">
13    $(document).ready(function () {
14        $('#datepicker').datepicker();
15        ...
16    });
17</script>      
18<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.9.0/js/bootstrap-datepicker.min.js"></script>
19

Source https://stackoverflow.com/questions/69764102

QUESTION

The unauthenticated git protocol on port 9418 is no longer supported

Asked 2022-Mar-27 at 13:23

I have been using github actions for quite sometime but today my deployments started failing. Below is the error from github action logs

1Command: git
2Arguments: ls-remote --tags --heads git://github.com/adobe-webplatform/eve.git
3Directory: /home/runner/work/stackstream-fe/stackstream-fe
4Output:
5fatal: remote error: 
6  The unauthenticated git protocol on port 9418 is no longer supported.
7

Upon investigation, it appears that below section in my yml file is causing the issue.

1Command: git
2Arguments: ls-remote --tags --heads git://github.com/adobe-webplatform/eve.git
3Directory: /home/runner/work/stackstream-fe/stackstream-fe
4Output:
5fatal: remote error: 
6  The unauthenticated git protocol on port 9418 is no longer supported.
7    - name: Installing modules
8      run: yarn install
9

I have looked into this change log but can't seem to comprehend the issue.

Additional Details: Server: EC2 Instance Github actions steps:

1Command: git
2Arguments: ls-remote --tags --heads git://github.com/adobe-webplatform/eve.git
3Directory: /home/runner/work/stackstream-fe/stackstream-fe
4Output:
5fatal: remote error: 
6  The unauthenticated git protocol on port 9418 is no longer supported.
7    - name: Installing modules
8      run: yarn install
9  steps:
10  - name: Checkout
11    uses: actions/checkout@v2
12
13  - id: vars
14    run: |
15      if [ '${{ github.ref }}' == 'refs/heads/master' ]; then echo "::set-output name=environment::prod_stackstream" ; echo "::set-output name=api-url::api" ; elif [ '${{ github.ref }}' == 'refs/heads/staging' ]; then echo "::set-output name=environment::staging_stackstream"  ; echo "::set-output name=api-url::stagingapi" ; else echo "::set-output name=environment::dev_stackstream" ; echo "::set-output name=api-url::devapi" ; fi
16
17  - uses: pCYSl5EDgo/cat@master
18    id: slack
19    with:
20      path: .github/workflows/slack.txt
21
22  - name: Slack Start Notification
23    uses: 8398a7/action-slack@v3
24    env:
25      SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
26      ENVIRONMENT: '`${{ steps.vars.outputs.environment }}`'
27      COLOR: good
28      STATUS: '`Started`'
29    with:
30      status: custom
31      fields: workflow,job,commit,repo,ref,author,took
32      custom_payload: |
33        ${{ steps.slack.outputs.text }}
34
35  - name: Installing modules
36    env:
37      REACT_APP_API_URL: 'https://${{ steps.vars.outputs.api-url }}mergestack.com/api/v1'
38    run: yarn install
39
40  - name: Create Frontend Build
41    env:
42      REACT_APP_API_URL: 'https://${{ steps.vars.outputs.api-url }}mergestack.com/api/v1'
43    run: yarn build
44
45  - name: Deploy to Frontend Server DEV
46    if: ${{ contains(github.ref, 'dev') }}
47    uses: easingthemes/ssh-deploy@v2.1.5
48    env:
49      SSH_PRIVATE_KEY: ${{ secrets.DEV_KEY }}
50      ARGS: '-rltgoDzvO --delete'
51      SOURCE: 'deploy/'
52      REMOTE_HOST: ${{ secrets.DEV_HOST }}
53      REMOTE_USER: plyfolio-dev
54      TARGET: '/home/plyfolio-dev/${{ steps.vars.outputs.environment }}/fe/deploy'
55

package.json file

1Command: git
2Arguments: ls-remote --tags --heads git://github.com/adobe-webplatform/eve.git
3Directory: /home/runner/work/stackstream-fe/stackstream-fe
4Output:
5fatal: remote error: 
6  The unauthenticated git protocol on port 9418 is no longer supported.
7    - name: Installing modules
8      run: yarn install
9  steps:
10  - name: Checkout
11    uses: actions/checkout@v2
12
13  - id: vars
14    run: |
15      if [ '${{ github.ref }}' == 'refs/heads/master' ]; then echo "::set-output name=environment::prod_stackstream" ; echo "::set-output name=api-url::api" ; elif [ '${{ github.ref }}' == 'refs/heads/staging' ]; then echo "::set-output name=environment::staging_stackstream"  ; echo "::set-output name=api-url::stagingapi" ; else echo "::set-output name=environment::dev_stackstream" ; echo "::set-output name=api-url::devapi" ; fi
16
17  - uses: pCYSl5EDgo/cat@master
18    id: slack
19    with:
20      path: .github/workflows/slack.txt
21
22  - name: Slack Start Notification
23    uses: 8398a7/action-slack@v3
24    env:
25      SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
26      ENVIRONMENT: '`${{ steps.vars.outputs.environment }}`'
27      COLOR: good
28      STATUS: '`Started`'
29    with:
30      status: custom
31      fields: workflow,job,commit,repo,ref,author,took
32      custom_payload: |
33        ${{ steps.slack.outputs.text }}
34
35  - name: Installing modules
36    env:
37      REACT_APP_API_URL: 'https://${{ steps.vars.outputs.api-url }}mergestack.com/api/v1'
38    run: yarn install
39
40  - name: Create Frontend Build
41    env:
42      REACT_APP_API_URL: 'https://${{ steps.vars.outputs.api-url }}mergestack.com/api/v1'
43    run: yarn build
44
45  - name: Deploy to Frontend Server DEV
46    if: ${{ contains(github.ref, 'dev') }}
47    uses: easingthemes/ssh-deploy@v2.1.5
48    env:
49      SSH_PRIVATE_KEY: ${{ secrets.DEV_KEY }}
50      ARGS: '-rltgoDzvO --delete'
51      SOURCE: 'deploy/'
52      REMOTE_HOST: ${{ secrets.DEV_HOST }}
53      REMOTE_USER: plyfolio-dev
54      TARGET: '/home/plyfolio-dev/${{ steps.vars.outputs.environment }}/fe/deploy'
55   {
56  "name": "stackstream-fe",
57  "version": "1.0.0",
58  "authors": [
59    "fayyaznofal@gmail.com"
60  ],
61  "private": true,
62  "dependencies": {
63    "@fortawesome/fontawesome-svg-core": "^1.2.34",
64    "@fortawesome/free-solid-svg-icons": "^5.15.2",
65    "@fortawesome/react-fontawesome": "^0.1.14",
66    "@fullcalendar/bootstrap": "^5.5.0",
67    "@fullcalendar/core": "^5.5.0",
68    "@fullcalendar/daygrid": "^5.5.0",
69    "@fullcalendar/interaction": "^5.5.0",
70    "@fullcalendar/react": "^5.5.0",
71    "@lourenci/react-kanban": "^2.1.0",
72    "@redux-saga/simple-saga-monitor": "^1.1.2",
73    "@testing-library/jest-dom": "^5.11.9",
74    "@testing-library/react": "^11.2.3",
75    "@testing-library/user-event": "^12.6.0",
76    "@toast-ui/react-chart": "^1.0.2",
77    "@types/jest": "^26.0.14",
78    "@types/node": "^14.10.3",
79    "@types/react": "^16.9.49",
80    "@types/react-dom": "^16.9.8",
81    "@vtaits/react-color-picker": "^0.1.1",
82    "apexcharts": "^3.23.1",
83    "availity-reactstrap-validation": "^2.7.0",
84    "axios": "^0.21.1",
85    "axios-mock-adapter": "^1.19.0",
86    "axios-progress-bar": "^1.2.0",
87    "bootstrap": "^5.0.0-beta2",
88    "chart.js": "^2.9.4",
89    "chartist": "^0.11.4",
90    "classnames": "^2.2.6",
91    "components": "^0.1.0",
92    "dotenv": "^8.2.0",
93    "draft-js": "^0.11.7",
94    "echarts": "^4.9.0",
95    "echarts-for-react": "^2.0.16",
96    "firebase": "^8.2.3",
97    "google-maps-react": "^2.0.6",
98    "history": "^4.10.1",
99    "i": "^0.3.6",
100    "i18next": "^19.8.4",
101    "i18next-browser-languagedetector": "^6.0.1",
102    "jsonwebtoken": "^8.5.1",
103    "leaflet": "^1.7.1",
104    "lodash": "^4.17.21",
105    "lodash.clonedeep": "^4.5.0",
106    "lodash.get": "^4.4.2",
107    "metismenujs": "^1.2.1",
108    "mkdirp": "^1.0.4",
109    "moment": "2.29.1",
110    "moment-timezone": "^0.5.32",
111    "nouislider-react": "^3.3.9",
112    "npm": "^7.6.3",
113    "prop-types": "^15.7.2",
114    "query-string": "^6.14.0",
115    "react": "^16.13.1",
116    "react-apexcharts": "^1.3.7",
117    "react-auth-code-input": "^1.0.0",
118    "react-avatar": "^3.10.0",
119    "react-bootstrap": "^1.5.0",
120    "react-bootstrap-editable": "^0.8.2",
121    "react-bootstrap-sweetalert": "^5.2.0",
122    "react-bootstrap-table-next": "^4.0.3",
123    "react-bootstrap-table2-editor": "^1.4.0",
124    "react-bootstrap-table2-paginator": "^2.1.2",
125    "react-bootstrap-table2-toolkit": "^2.1.3",
126    "react-chartist": "^0.14.3",
127    "react-chartjs-2": "^2.11.1",
128    "react-color": "^2.19.3",
129    "react-confirm-alert": "^2.7.0",
130    "react-content-loader": "^6.0.1",
131    "react-countdown": "^2.3.1",
132    "react-countup": "^4.3.3",
133    "react-cropper": "^2.1.4",
134    "react-data-table-component": "^6.11.8",
135    "react-date-picker": "^8.0.6",
136    "react-datepicker": "^3.4.1",
137    "react-dom": "^16.13.1",
138    "react-draft-wysiwyg": "^1.14.5",
139    "react-drag-listview": "^0.1.8",
140    "react-drawer": "^1.3.4",
141    "react-dropzone": "^11.2.4",
142    "react-dual-listbox": "^2.0.0",
143    "react-facebook-login": "^4.1.1",
144    "react-flatpickr": "^3.10.6",
145    "react-google-login": "^5.2.2",
146    "react-hook-form": "^7.15.2",
147    "react-i18next": "^11.8.5",
148    "react-icons": "^4.2.0",
149    "react-image-lightbox": "^5.1.1",
150    "react-input-mask": "^2.0.4",
151    "react-jvectormap": "^0.0.16",
152    "react-leaflet": "^3.0.5",
153    "react-meta-tags": "^1.0.1",
154    "react-modal-video": "^1.2.6",
155    "react-notifications": "^1.7.2",
156    "react-number-format": "^4.7.3",
157    "react-perfect-scrollbar": "^1.5.8",
158    "react-rangeslider": "^2.2.0",
159    "react-rating": "^2.0.5",
160    "react-rating-tooltip": "^1.1.6",
161    "react-redux": "^7.2.1",
162    "react-responsive-carousel": "^3.2.11",
163    "react-router-dom": "^5.2.0",
164    "react-script": "^2.0.5",
165    "react-scripts": "3.4.3",
166    "react-select": "^4.3.1",
167    "react-sparklines": "^1.7.0",
168    "react-star-ratings": "^2.3.0",
169    "react-super-responsive-table": "^5.2.0",
170    "react-switch": "^6.0.0",
171    "react-table": "^7.6.3",
172    "react-toastify": "^7.0.3",
173    "react-toastr": "^3.0.0",
174    "react-twitter-auth": "0.0.13",
175    "reactstrap": "^8.8.1",
176    "recharts": "^2.0.8",
177    "redux": "^4.0.5",
178    "redux-saga": "^1.1.3",
179    "reselect": "^4.0.0",
180    "sass": "^1.37.5",
181    "simplebar-react": "^2.3.0",
182    "styled": "^1.0.0",
183    "styled-components": "^5.2.1",
184    "toastr": "^2.1.4",
185    "typescript": "^4.0.2",
186    "universal-cookie": "^4.0.4"
187  },
188  "devDependencies": {
189    "@typescript-eslint/eslint-plugin": "^2.27.0",
190    "@typescript-eslint/parser": "^2.27.0",
191    "@typescript-eslint/typescript-estree": "^4.15.2",
192    "eslint-config-prettier": "^6.10.1",
193    "eslint-plugin-prettier": "^3.1.2",
194    "husky": "^4.2.5",
195    "lint-staged": "^10.1.3",
196    "prettier": "^1.19.1",
197    "react-test-renderer": "^16.13.1",
198    "redux-devtools-extension": "^2.13.8",
199    "redux-mock-store": "^1.5.4"
200  },
201  "scripts": {
202    "start": "react-scripts start",
203    "build": "react-scripts build && mv build ./deploy/build",
204    "build-local": "react-scripts build",
205    "test": "react-scripts test",
206    "eject": "react-scripts eject"
207  },
208  "eslintConfig": {
209    "extends": "react-app"
210  },
211  "husky": {
212    "hooks": {
213      "pre-commit": "lint-staged"
214    }
215  },
216  "lint-staged": {
217    "*.{js,ts,tsx}": [
218      "eslint --fix"
219    ]
220  },
221  "browserslist": {
222    "production": [
223      ">0.2%",
224      "not dead",
225      "not op_mini all"
226    ],
227    "development": [
228      "last 1 chrome version",
229      "last 1 firefox version",
230      "last 1 safari version"
231    ]
232  }
233}
234

ANSWER

Answered 2022-Mar-16 at 07:01

First, this error message is indeed expected on Jan. 11th, 2022.
See "Improving Git protocol security on GitHub".

January 11, 2022 Final brownout.

This is the full brownout period where we’ll temporarily stop accepting the deprecated key and signature types, ciphers, and MACs, and the unencrypted Git protocol.
This will help clients discover any lingering use of older keys or old URLs.

Second, check your package.json dependencies for any git:// URL, as in this example, fixed in this PR.

As noted by Jörg W Mittag:

There was a 4-month warning.
The entire Internet has been moving away from unauthenticated, unencrypted protocols for a decade, it's not like this is a huge surprise.

Personally, I consider it less an "issue" and more "detecting unmaintained dependencies".

Plus, this is still only the brownout period, so the protocol will only be disabled for a short period of time, allowing developers to discover the problem.

The permanent shutdown is not until March 15th.


For GitHub Actions:

As in actions/checkout issue 14, you can add as a first step:

1Command: git
2Arguments: ls-remote --tags --heads git://github.com/adobe-webplatform/eve.git
3Directory: /home/runner/work/stackstream-fe/stackstream-fe
4Output:
5fatal: remote error: 
6  The unauthenticated git protocol on port 9418 is no longer supported.
7    - name: Installing modules
8      run: yarn install
9  steps:
10  - name: Checkout
11    uses: actions/checkout@v2
12
13  - id: vars
14    run: |
15      if [ '${{ github.ref }}' == 'refs/heads/master' ]; then echo "::set-output name=environment::prod_stackstream" ; echo "::set-output name=api-url::api" ; elif [ '${{ github.ref }}' == 'refs/heads/staging' ]; then echo "::set-output name=environment::staging_stackstream"  ; echo "::set-output name=api-url::stagingapi" ; else echo "::set-output name=environment::dev_stackstream" ; echo "::set-output name=api-url::devapi" ; fi
16
17  - uses: pCYSl5EDgo/cat@master
18    id: slack
19    with:
20      path: .github/workflows/slack.txt
21
22  - name: Slack Start Notification
23    uses: 8398a7/action-slack@v3
24    env:
25      SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
26      ENVIRONMENT: '`${{ steps.vars.outputs.environment }}`'
27      COLOR: good
28      STATUS: '`Started`'
29    with:
30      status: custom
31      fields: workflow,job,commit,repo,ref,author,took
32      custom_payload: |
33        ${{ steps.slack.outputs.text }}
34
35  - name: Installing modules
36    env:
37      REACT_APP_API_URL: 'https://${{ steps.vars.outputs.api-url }}mergestack.com/api/v1'
38    run: yarn install
39
40  - name: Create Frontend Build
41    env:
42      REACT_APP_API_URL: 'https://${{ steps.vars.outputs.api-url }}mergestack.com/api/v1'
43    run: yarn build
44
45  - name: Deploy to Frontend Server DEV
46    if: ${{ contains(github.ref, 'dev') }}
47    uses: easingthemes/ssh-deploy@v2.1.5
48    env:
49      SSH_PRIVATE_KEY: ${{ secrets.DEV_KEY }}
50      ARGS: '-rltgoDzvO --delete'
51      SOURCE: 'deploy/'
52      REMOTE_HOST: ${{ secrets.DEV_HOST }}
53      REMOTE_USER: plyfolio-dev
54      TARGET: '/home/plyfolio-dev/${{ steps.vars.outputs.environment }}/fe/deploy'
55   {
56  "name": "stackstream-fe",
57  "version": "1.0.0",
58  "authors": [
59    "fayyaznofal@gmail.com"
60  ],
61  "private": true,
62  "dependencies": {
63    "@fortawesome/fontawesome-svg-core": "^1.2.34",
64    "@fortawesome/free-solid-svg-icons": "^5.15.2",
65    "@fortawesome/react-fontawesome": "^0.1.14",
66    "@fullcalendar/bootstrap": "^5.5.0",
67    "@fullcalendar/core": "^5.5.0",
68    "@fullcalendar/daygrid": "^5.5.0",
69    "@fullcalendar/interaction": "^5.5.0",
70    "@fullcalendar/react": "^5.5.0",
71    "@lourenci/react-kanban": "^2.1.0",
72    "@redux-saga/simple-saga-monitor": "^1.1.2",
73    "@testing-library/jest-dom": "^5.11.9",
74    "@testing-library/react": "^11.2.3",
75    "@testing-library/user-event": "^12.6.0",
76    "@toast-ui/react-chart": "^1.0.2",
77    "@types/jest": "^26.0.14",
78    "@types/node": "^14.10.3",
79    "@types/react": "^16.9.49",
80    "@types/react-dom": "^16.9.8",
81    "@vtaits/react-color-picker": "^0.1.1",
82    "apexcharts": "^3.23.1",
83    "availity-reactstrap-validation": "^2.7.0",
84    "axios": "^0.21.1",
85    "axios-mock-adapter": "^1.19.0",
86    "axios-progress-bar": "^1.2.0",
87    "bootstrap": "^5.0.0-beta2",
88    "chart.js": "^2.9.4",
89    "chartist": "^0.11.4",
90    "classnames": "^2.2.6",
91    "components": "^0.1.0",
92    "dotenv": "^8.2.0",
93    "draft-js": "^0.11.7",
94    "echarts": "^4.9.0",
95    "echarts-for-react": "^2.0.16",
96    "firebase": "^8.2.3",
97    "google-maps-react": "^2.0.6",
98    "history": "^4.10.1",
99    "i": "^0.3.6",
100    "i18next": "^19.8.4",
101    "i18next-browser-languagedetector": "^6.0.1",
102    "jsonwebtoken": "^8.5.1",
103    "leaflet": "^1.7.1",
104    "lodash": "^4.17.21",
105    "lodash.clonedeep": "^4.5.0",
106    "lodash.get": "^4.4.2",
107    "metismenujs": "^1.2.1",
108    "mkdirp": "^1.0.4",
109    "moment": "2.29.1",
110    "moment-timezone": "^0.5.32",
111    "nouislider-react": "^3.3.9",
112    "npm": "^7.6.3",
113    "prop-types": "^15.7.2",
114    "query-string": "^6.14.0",
115    "react": "^16.13.1",
116    "react-apexcharts": "^1.3.7",
117    "react-auth-code-input": "^1.0.0",
118    "react-avatar": "^3.10.0",
119    "react-bootstrap": "^1.5.0",
120    "react-bootstrap-editable": "^0.8.2",
121    "react-bootstrap-sweetalert": "^5.2.0",
122    "react-bootstrap-table-next": "^4.0.3",
123    "react-bootstrap-table2-editor": "^1.4.0",
124    "react-bootstrap-table2-paginator": "^2.1.2",
125    "react-bootstrap-table2-toolkit": "^2.1.3",
126    "react-chartist": "^0.14.3",
127    "react-chartjs-2": "^2.11.1",
128    "react-color": "^2.19.3",
129    "react-confirm-alert": "^2.7.0",
130    "react-content-loader": "^6.0.1",
131    "react-countdown": "^2.3.1",
132    "react-countup": "^4.3.3",
133    "react-cropper": "^2.1.4",
134    "react-data-table-component": "^6.11.8",
135    "react-date-picker": "^8.0.6",
136    "react-datepicker": "^3.4.1",
137    "react-dom": "^16.13.1",
138    "react-draft-wysiwyg": "^1.14.5",
139    "react-drag-listview": "^0.1.8",
140    "react-drawer": "^1.3.4",
141    "react-dropzone": "^11.2.4",
142    "react-dual-listbox": "^2.0.0",
143    "react-facebook-login": "^4.1.1",
144    "react-flatpickr": "^3.10.6",
145    "react-google-login": "^5.2.2",
146    "react-hook-form": "^7.15.2",
147    "react-i18next": "^11.8.5",
148    "react-icons": "^4.2.0",
149    "react-image-lightbox": "^5.1.1",
150    "react-input-mask": "^2.0.4",
151    "react-jvectormap": "^0.0.16",
152    "react-leaflet": "^3.0.5",
153    "react-meta-tags": "^1.0.1",
154    "react-modal-video": "^1.2.6",
155    "react-notifications": "^1.7.2",
156    "react-number-format": "^4.7.3",
157    "react-perfect-scrollbar": "^1.5.8",
158    "react-rangeslider": "^2.2.0",
159    "react-rating": "^2.0.5",
160    "react-rating-tooltip": "^1.1.6",
161    "react-redux": "^7.2.1",
162    "react-responsive-carousel": "^3.2.11",
163    "react-router-dom": "^5.2.0",
164    "react-script": "^2.0.5",
165    "react-scripts": "3.4.3",
166    "react-select": "^4.3.1",
167    "react-sparklines": "^1.7.0",
168    "react-star-ratings": "^2.3.0",
169    "react-super-responsive-table": "^5.2.0",
170    "react-switch": "^6.0.0",
171    "react-table": "^7.6.3",
172    "react-toastify": "^7.0.3",
173    "react-toastr": "^3.0.0",
174    "react-twitter-auth": "0.0.13",
175    "reactstrap": "^8.8.1",
176    "recharts": "^2.0.8",
177    "redux": "^4.0.5",
178    "redux-saga": "^1.1.3",
179    "reselect": "^4.0.0",
180    "sass": "^1.37.5",
181    "simplebar-react": "^2.3.0",
182    "styled": "^1.0.0",
183    "styled-components": "^5.2.1",
184    "toastr": "^2.1.4",
185    "typescript": "^4.0.2",
186    "universal-cookie": "^4.0.4"
187  },
188  "devDependencies": {
189    "@typescript-eslint/eslint-plugin": "^2.27.0",
190    "@typescript-eslint/parser": "^2.27.0",
191    "@typescript-eslint/typescript-estree": "^4.15.2",
192    "eslint-config-prettier": "^6.10.1",
193    "eslint-plugin-prettier": "^3.1.2",
194    "husky": "^4.2.5",
195    "lint-staged": "^10.1.3",
196    "prettier": "^1.19.1",
197    "react-test-renderer": "^16.13.1",
198    "redux-devtools-extension": "^2.13.8",
199    "redux-mock-store": "^1.5.4"
200  },
201  "scripts": {
202    "start": "react-scripts start",
203    "build": "react-scripts build && mv build ./deploy/build",
204    "build-local": "react-scripts build",
205    "test": "react-scripts test",
206    "eject": "react-scripts eject"
207  },
208  "eslintConfig": {
209    "extends": "react-app"
210  },
211  "husky": {
212    "hooks": {
213      "pre-commit": "lint-staged"
214    }
215  },
216  "lint-staged": {
217    "*.{js,ts,tsx}": [
218      "eslint --fix"
219    ]
220  },
221  "browserslist": {
222    "production": [
223      ">0.2%",
224      "not dead",
225      "not op_mini all"
226    ],
227    "development": [
228      "last 1 chrome version",
229      "last 1 firefox version",
230      "last 1 safari version"
231    ]
232  }
233}
234    - name: Fix up git URLs
235      run: echo -e '[url "https://github.com/"]\n  insteadOf = "git://github.com/"' >> ~/.gitconfig
236

That will change any git://github.com/ into https://github.com/.

For local projects

For all your repositories, you can set:

1Command: git
2Arguments: ls-remote --tags --heads git://github.com/adobe-webplatform/eve.git
3Directory: /home/runner/work/stackstream-fe/stackstream-fe
4Output:
5fatal: remote error: 
6  The unauthenticated git protocol on port 9418 is no longer supported.
7    - name: Installing modules
8      run: yarn install
9  steps:
10  - name: Checkout
11    uses: actions/checkout@v2
12
13  - id: vars
14    run: |
15      if [ '${{ github.ref }}' == 'refs/heads/master' ]; then echo "::set-output name=environment::prod_stackstream" ; echo "::set-output name=api-url::api" ; elif [ '${{ github.ref }}' == 'refs/heads/staging' ]; then echo "::set-output name=environment::staging_stackstream"  ; echo "::set-output name=api-url::stagingapi" ; else echo "::set-output name=environment::dev_stackstream" ; echo "::set-output name=api-url::devapi" ; fi
16
17  - uses: pCYSl5EDgo/cat@master
18    id: slack
19    with:
20      path: .github/workflows/slack.txt
21
22  - name: Slack Start Notification
23    uses: 8398a7/action-slack@v3
24    env:
25      SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
26      ENVIRONMENT: '`${{ steps.vars.outputs.environment }}`'
27      COLOR: good
28      STATUS: '`Started`'
29    with:
30      status: custom
31      fields: workflow,job,commit,repo,ref,author,took
32      custom_payload: |
33        ${{ steps.slack.outputs.text }}
34
35  - name: Installing modules
36    env:
37      REACT_APP_API_URL: 'https://${{ steps.vars.outputs.api-url }}mergestack.com/api/v1'
38    run: yarn install
39
40  - name: Create Frontend Build
41    env:
42      REACT_APP_API_URL: 'https://${{ steps.vars.outputs.api-url }}mergestack.com/api/v1'
43    run: yarn build
44
45  - name: Deploy to Frontend Server DEV
46    if: ${{ contains(github.ref, 'dev') }}
47    uses: easingthemes/ssh-deploy@v2.1.5
48    env:
49      SSH_PRIVATE_KEY: ${{ secrets.DEV_KEY }}
50      ARGS: '-rltgoDzvO --delete'
51      SOURCE: 'deploy/'
52      REMOTE_HOST: ${{ secrets.DEV_HOST }}
53      REMOTE_USER: plyfolio-dev
54      TARGET: '/home/plyfolio-dev/${{ steps.vars.outputs.environment }}/fe/deploy'
55   {
56  "name": "stackstream-fe",
57  "version": "1.0.0",
58  "authors": [
59    "fayyaznofal@gmail.com"
60  ],
61  "private": true,
62  "dependencies": {
63    "@fortawesome/fontawesome-svg-core": "^1.2.34",
64    "@fortawesome/free-solid-svg-icons": "^5.15.2",
65    "@fortawesome/react-fontawesome": "^0.1.14",
66    "@fullcalendar/bootstrap": "^5.5.0",
67    "@fullcalendar/core": "^5.5.0",
68    "@fullcalendar/daygrid": "^5.5.0",
69    "@fullcalendar/interaction": "^5.5.0",
70    "@fullcalendar/react": "^5.5.0",
71    "@lourenci/react-kanban": "^2.1.0",
72    "@redux-saga/simple-saga-monitor": "^1.1.2",
73    "@testing-library/jest-dom": "^5.11.9",
74    "@testing-library/react": "^11.2.3",
75    "@testing-library/user-event": "^12.6.0",
76    "@toast-ui/react-chart": "^1.0.2",
77    "@types/jest": "^26.0.14",
78    "@types/node": "^14.10.3",
79    "@types/react": "^16.9.49",
80    "@types/react-dom": "^16.9.8",
81    "@vtaits/react-color-picker": "^0.1.1",
82    "apexcharts": "^3.23.1",
83    "availity-reactstrap-validation": "^2.7.0",
84    "axios": "^0.21.1",
85    "axios-mock-adapter": "^1.19.0",
86    "axios-progress-bar": "^1.2.0",
87    "bootstrap": "^5.0.0-beta2",
88    "chart.js": "^2.9.4",
89    "chartist": "^0.11.4",
90    "classnames": "^2.2.6",
91    "components": "^0.1.0",
92    "dotenv": "^8.2.0",
93    "draft-js": "^0.11.7",
94    "echarts": "^4.9.0",
95    "echarts-for-react": "^2.0.16",
96    "firebase": "^8.2.3",
97    "google-maps-react": "^2.0.6",
98    "history": "^4.10.1",
99    "i": "^0.3.6",
100    "i18next": "^19.8.4",
101    "i18next-browser-languagedetector": "^6.0.1",
102    "jsonwebtoken": "^8.5.1",
103    "leaflet": "^1.7.1",
104    "lodash": "^4.17.21",
105    "lodash.clonedeep": "^4.5.0",
106    "lodash.get": "^4.4.2",
107    "metismenujs": "^1.2.1",
108    "mkdirp": "^1.0.4",
109    "moment": "2.29.1",
110    "moment-timezone": "^0.5.32",
111    "nouislider-react": "^3.3.9",
112    "npm": "^7.6.3",
113    "prop-types": "^15.7.2",
114    "query-string": "^6.14.0",
115    "react": "^16.13.1",
116    "react-apexcharts": "^1.3.7",
117    "react-auth-code-input": "^1.0.0",
118    "react-avatar": "^3.10.0",
119    "react-bootstrap": "^1.5.0",
120    "react-bootstrap-editable": "^0.8.2",
121    "react-bootstrap-sweetalert": "^5.2.0",
122    "react-bootstrap-table-next": "^4.0.3",
123    "react-bootstrap-table2-editor": "^1.4.0",
124    "react-bootstrap-table2-paginator": "^2.1.2",
125    "react-bootstrap-table2-toolkit": "^2.1.3",
126    "react-chartist": "^0.14.3",
127    "react-chartjs-2": "^2.11.1",
128    "react-color": "^2.19.3",
129    "react-confirm-alert": "^2.7.0",
130    "react-content-loader": "^6.0.1",
131    "react-countdown": "^2.3.1",
132    "react-countup": "^4.3.3",
133    "react-cropper": "^2.1.4",
134    "react-data-table-component": "^6.11.8",
135    "react-date-picker": "^8.0.6",
136    "react-datepicker": "^3.4.1",
137    "react-dom": "^16.13.1",
138    "react-draft-wysiwyg": "^1.14.5",
139    "react-drag-listview": "^0.1.8",
140    "react-drawer": "^1.3.4",
141    "react-dropzone": "^11.2.4",
142    "react-dual-listbox": "^2.0.0",
143    "react-facebook-login": "^4.1.1",
144    "react-flatpickr": "^3.10.6",
145    "react-google-login": "^5.2.2",
146    "react-hook-form": "^7.15.2",
147    "react-i18next": "^11.8.5",
148    "react-icons": "^4.2.0",
149    "react-image-lightbox": "^5.1.1",
150    "react-input-mask": "^2.0.4",
151    "react-jvectormap": "^0.0.16",
152    "react-leaflet": "^3.0.5",
153    "react-meta-tags": "^1.0.1",
154    "react-modal-video": "^1.2.6",
155    "react-notifications": "^1.7.2",
156    "react-number-format": "^4.7.3",
157    "react-perfect-scrollbar": "^1.5.8",
158    "react-rangeslider": "^2.2.0",
159    "react-rating": "^2.0.5",
160    "react-rating-tooltip": "^1.1.6",
161    "react-redux": "^7.2.1",
162    "react-responsive-carousel": "^3.2.11",
163    "react-router-dom": "^5.2.0",
164    "react-script": "^2.0.5",
165    "react-scripts": "3.4.3",
166    "react-select": "^4.3.1",
167    "react-sparklines": "^1.7.0",
168    "react-star-ratings": "^2.3.0",
169    "react-super-responsive-table": "^5.2.0",
170    "react-switch": "^6.0.0",
171    "react-table": "^7.6.3",
172    "react-toastify": "^7.0.3",
173    "react-toastr": "^3.0.0",
174    "react-twitter-auth": "0.0.13",
175    "reactstrap": "^8.8.1",
176    "recharts": "^2.0.8",
177    "redux": "^4.0.5",
178    "redux-saga": "^1.1.3",
179    "reselect": "^4.0.0",
180    "sass": "^1.37.5",
181    "simplebar-react": "^2.3.0",
182    "styled": "^1.0.0",
183    "styled-components": "^5.2.1",
184    "toastr": "^2.1.4",
185    "typescript": "^4.0.2",
186    "universal-cookie": "^4.0.4"
187  },
188  "devDependencies": {
189    "@typescript-eslint/eslint-plugin": "^2.27.0",
190    "@typescript-eslint/parser": "^2.27.0",
191    "@typescript-eslint/typescript-estree": "^4.15.2",
192    "eslint-config-prettier": "^6.10.1",
193    "eslint-plugin-prettier": "^3.1.2",
194    "husky": "^4.2.5",
195    "lint-staged": "^10.1.3",
196    "prettier": "^1.19.1",
197    "react-test-renderer": "^16.13.1",
198    "redux-devtools-extension": "^2.13.8",
199    "redux-mock-store": "^1.5.4"
200  },
201  "scripts": {
202    "start": "react-scripts start",
203    "build": "react-scripts build && mv build ./deploy/build",
204    "build-local": "react-scripts build",
205    "test": "react-scripts test",
206    "eject": "react-scripts eject"
207  },
208  "eslintConfig": {
209    "extends": "react-app"
210  },
211  "husky": {
212    "hooks": {
213      "pre-commit": "lint-staged"
214    }
215  },
216  "lint-staged": {
217    "*.{js,ts,tsx}": [
218      "eslint --fix"
219    ]
220  },
221  "browserslist": {
222    "production": [
223      ">0.2%",
224      "not dead",
225      "not op_mini all"
226    ],
227    "development": [
228      "last 1 chrome version",
229      "last 1 firefox version",
230      "last 1 safari version"
231    ]
232  }
233}
234    - name: Fix up git URLs
235      run: echo -e '[url "https://github.com/"]\n  insteadOf = "git://github.com/"' >> ~/.gitconfig
236git config --global url."https://github.com/".insteadOf git://github.com/
237

You can also use SSH, but GitHub Security reminds us that, as of March 15th, 2022, GitHub stopped accepting DSA keys. RSA keys uploaded after Nov 2, 2021 will work only with SHA-2 signatures.
The deprecated MACs, ciphers, and unencrypted Git protocol are permanently disabled.

So this (with the right key) would work:

1Command: git
2Arguments: ls-remote --tags --heads git://github.com/adobe-webplatform/eve.git
3Directory: /home/runner/work/stackstream-fe/stackstream-fe
4Output:
5fatal: remote error: 
6  The unauthenticated git protocol on port 9418 is no longer supported.
7    - name: Installing modules
8      run: yarn install
9  steps:
10  - name: Checkout
11    uses: actions/checkout@v2
12
13  - id: vars
14    run: |
15      if [ '${{ github.ref }}' == 'refs/heads/master' ]; then echo "::set-output name=environment::prod_stackstream" ; echo "::set-output name=api-url::api" ; elif [ '${{ github.ref }}' == 'refs/heads/staging' ]; then echo "::set-output name=environment::staging_stackstream"  ; echo "::set-output name=api-url::stagingapi" ; else echo "::set-output name=environment::dev_stackstream" ; echo "::set-output name=api-url::devapi" ; fi
16
17  - uses: pCYSl5EDgo/cat@master
18    id: slack
19    with:
20      path: .github/workflows/slack.txt
21
22  - name: Slack Start Notification
23    uses: 8398a7/action-slack@v3
24    env:
25      SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
26      ENVIRONMENT: '`${{ steps.vars.outputs.environment }}`'
27      COLOR: good
28      STATUS: '`Started`'
29    with:
30      status: custom
31      fields: workflow,job,commit,repo,ref,author,took
32      custom_payload: |
33        ${{ steps.slack.outputs.text }}
34
35  - name: Installing modules
36    env:
37      REACT_APP_API_URL: 'https://${{ steps.vars.outputs.api-url }}mergestack.com/api/v1'
38    run: yarn install
39
40  - name: Create Frontend Build
41    env:
42      REACT_APP_API_URL: 'https://${{ steps.vars.outputs.api-url }}mergestack.com/api/v1'
43    run: yarn build
44
45  - name: Deploy to Frontend Server DEV
46    if: ${{ contains(github.ref, 'dev') }}
47    uses: easingthemes/ssh-deploy@v2.1.5
48    env:
49      SSH_PRIVATE_KEY: ${{ secrets.DEV_KEY }}
50      ARGS: '-rltgoDzvO --delete'
51      SOURCE: 'deploy/'
52      REMOTE_HOST: ${{ secrets.DEV_HOST }}
53      REMOTE_USER: plyfolio-dev
54      TARGET: '/home/plyfolio-dev/${{ steps.vars.outputs.environment }}/fe/deploy'
55   {
56  "name": "stackstream-fe",
57  "version": "1.0.0",
58  "authors": [
59    "fayyaznofal@gmail.com"
60  ],
61  "private": true,
62  "dependencies": {
63    "@fortawesome/fontawesome-svg-core": "^1.2.34",
64    "@fortawesome/free-solid-svg-icons": "^5.15.2",
65    "@fortawesome/react-fontawesome": "^0.1.14",
66    "@fullcalendar/bootstrap": "^5.5.0",
67    "@fullcalendar/core": "^5.5.0",
68    "@fullcalendar/daygrid": "^5.5.0",
69    "@fullcalendar/interaction": "^5.5.0",
70    "@fullcalendar/react": "^5.5.0",
71    "@lourenci/react-kanban": "^2.1.0",
72    "@redux-saga/simple-saga-monitor": "^1.1.2",
73    "@testing-library/jest-dom": "^5.11.9",
74    "@testing-library/react": "^11.2.3",
75    "@testing-library/user-event": "^12.6.0",
76    "@toast-ui/react-chart": "^1.0.2",
77    "@types/jest": "^26.0.14",
78    "@types/node": "^14.10.3",
79    "@types/react": "^16.9.49",
80    "@types/react-dom": "^16.9.8",
81    "@vtaits/react-color-picker": "^0.1.1",
82    "apexcharts": "^3.23.1",
83    "availity-reactstrap-validation": "^2.7.0",
84    "axios": "^0.21.1",
85    "axios-mock-adapter": "^1.19.0",
86    "axios-progress-bar": "^1.2.0",
87    "bootstrap": "^5.0.0-beta2",
88    "chart.js": "^2.9.4",
89    "chartist": "^0.11.4",
90    "classnames": "^2.2.6",
91    "components": "^0.1.0",
92    "dotenv": "^8.2.0",
93    "draft-js": "^0.11.7",
94    "echarts": "^4.9.0",
95    "echarts-for-react": "^2.0.16",
96    "firebase": "^8.2.3",
97    "google-maps-react": "^2.0.6",
98    "history": "^4.10.1",
99    "i": "^0.3.6",
100    "i18next": "^19.8.4",
101    "i18next-browser-languagedetector": "^6.0.1",
102    "jsonwebtoken": "^8.5.1",
103    "leaflet": "^1.7.1",
104    "lodash": "^4.17.21",
105    "lodash.clonedeep": "^4.5.0",
106    "lodash.get": "^4.4.2",
107    "metismenujs": "^1.2.1",
108    "mkdirp": "^1.0.4",
109    "moment": "2.29.1",
110    "moment-timezone": "^0.5.32",
111    "nouislider-react": "^3.3.9",
112    "npm": "^7.6.3",
113    "prop-types": "^15.7.2",
114    "query-string": "^6.14.0",
115    "react": "^16.13.1",
116    "react-apexcharts": "^1.3.7",
117    "react-auth-code-input": "^1.0.0",
118    "react-avatar": "^3.10.0",
119    "react-bootstrap": "^1.5.0",
120    "react-bootstrap-editable": "^0.8.2",
121    "react-bootstrap-sweetalert": "^5.2.0",
122    "react-bootstrap-table-next": "^4.0.3",
123    "react-bootstrap-table2-editor": "^1.4.0",
124    "react-bootstrap-table2-paginator": "^2.1.2",
125    "react-bootstrap-table2-toolkit": "^2.1.3",
126    "react-chartist": "^0.14.3",
127    "react-chartjs-2": "^2.11.1",
128    "react-color": "^2.19.3",
129    "react-confirm-alert": "^2.7.0",
130    "react-content-loader": "^6.0.1",
131    "react-countdown": "^2.3.1",
132    "react-countup": "^4.3.3",
133    "react-cropper": "^2.1.4",
134    "react-data-table-component": "^6.11.8",
135    "react-date-picker": "^8.0.6",
136    "react-datepicker": "^3.4.1",
137    "react-dom": "^16.13.1",
138    "react-draft-wysiwyg": "^1.14.5",
139    "react-drag-listview": "^0.1.8",
140    "react-drawer": "^1.3.4",
141    "react-dropzone": "^11.2.4",
142    "react-dual-listbox": "^2.0.0",
143    "react-facebook-login": "^4.1.1",
144    "react-flatpickr": "^3.10.6",
145    "react-google-login": "^5.2.2",
146    "react-hook-form": "^7.15.2",
147    "react-i18next": "^11.8.5",
148    "react-icons": "^4.2.0",
149    "react-image-lightbox": "^5.1.1",
150    "react-input-mask": "^2.0.4",
151    "react-jvectormap": "^0.0.16",
152    "react-leaflet": "^3.0.5",
153    "react-meta-tags": "^1.0.1",
154    "react-modal-video": "^1.2.6",
155    "react-notifications": "^1.7.2",
156    "react-number-format": "^4.7.3",
157    "react-perfect-scrollbar": "^1.5.8",
158    "react-rangeslider": "^2.2.0",
159    "react-rating": "^2.0.5",
160    "react-rating-tooltip": "^1.1.6",
161    "react-redux": "^7.2.1",
162    "react-responsive-carousel": "^3.2.11",
163    "react-router-dom": "^5.2.0",
164    "react-script": "^2.0.5",
165    "react-scripts": "3.4.3",
166    "react-select": "^4.3.1",
167    "react-sparklines": "^1.7.0",
168    "react-star-ratings": "^2.3.0",
169    "react-super-responsive-table": "^5.2.0",
170    "react-switch": "^6.0.0",
171    "react-table": "^7.6.3",
172    "react-toastify": "^7.0.3",
173    "react-toastr": "^3.0.0",
174    "react-twitter-auth": "0.0.13",
175    "reactstrap": "^8.8.1",
176    "recharts": "^2.0.8",
177    "redux": "^4.0.5",
178    "redux-saga": "^1.1.3",
179    "reselect": "^4.0.0",
180    "sass": "^1.37.5",
181    "simplebar-react": "^2.3.0",
182    "styled": "^1.0.0",
183    "styled-components": "^5.2.1",
184    "toastr": "^2.1.4",
185    "typescript": "^4.0.2",
186    "universal-cookie": "^4.0.4"
187  },
188  "devDependencies": {
189    "@typescript-eslint/eslint-plugin": "^2.27.0",
190    "@typescript-eslint/parser": "^2.27.0",
191    "@typescript-eslint/typescript-estree": "^4.15.2",
192    "eslint-config-prettier": "^6.10.1",
193    "eslint-plugin-prettier": "^3.1.2",
194    "husky": "^4.2.5",
195    "lint-staged": "^10.1.3",
196    "prettier": "^1.19.1",
197    "react-test-renderer": "^16.13.1",
198    "redux-devtools-extension": "^2.13.8",
199    "redux-mock-store": "^1.5.4"
200  },
201  "scripts": {
202    "start": "react-scripts start",
203    "build": "react-scripts build && mv build ./deploy/build",
204    "build-local": "react-scripts build",
205    "test": "react-scripts test",
206    "eject": "react-scripts eject"
207  },
208  "eslintConfig": {
209    "extends": "react-app"
210  },
211  "husky": {
212    "hooks": {
213      "pre-commit": "lint-staged"
214    }
215  },
216  "lint-staged": {
217    "*.{js,ts,tsx}": [
218      "eslint --fix"
219    ]
220  },
221  "browserslist": {
222    "production": [
223      ">0.2%",
224      "not dead",
225      "not op_mini all"
226    ],
227    "development": [
228      "last 1 chrome version",
229      "last 1 firefox version",
230      "last 1 safari version"
231    ]
232  }
233}
234    - name: Fix up git URLs
235      run: echo -e '[url "https://github.com/"]\n  insteadOf = "git://github.com/"' >> ~/.gitconfig
236git config --global url."https://github.com/".insteadOf git://github.com/
237git config --global url."git@github.com:".insteadOf git://github.com/
238

That will change any git://github.com/ (unencrypted Git protocol) into git@github.com: (SSH URL).

Source https://stackoverflow.com/questions/70663523

QUESTION

How to change the date picker from spinner to calendar dialogue in Android Kotlin

Asked 2022-Mar-16 at 10:31

How to change my spinner date picker to normal calendar with an option to keyboard entry as shown in the attached picture

Here is the code.

1 private val datePickerDialog by lazy {
2            DatePickerDialog(requireActivity(), R.style.SpinnerDatePickerDialog).apply {
3                setTitle(R.string.select_date)
4                datePicker.maxDate = LocalDate.now().minusDays(1).toMillis()
5                setOnDateSetListener { _, year, month, dayOfMonth ->
6                    viewModel.onDateSelected(year, month, dayOfMonth)
7                }
8            }
9        }
10

enter image description here

ANSWER

Answered 2022-Mar-16 at 10:31

Follow the below code to achieve a material calendar view.

(1) Add the below dependency in your app Gradle.

implementation 'com.google.android.material:material:1.5.0'

(2) Use the below style for your activity.

1 private val datePickerDialog by lazy {
2            DatePickerDialog(requireActivity(), R.style.SpinnerDatePickerDialog).apply {
3                setTitle(R.string.select_date)
4                datePicker.maxDate = LocalDate.now().minusDays(1).toMillis()
5                setOnDateSetListener { _, year, month, dayOfMonth ->
6                    viewModel.onDateSelected(year, month, dayOfMonth)
7                }
8            }
9        }
10    <!-- Base application theme. -->
11<style name="ScreenTheme" parent="Theme.MaterialComponents.Light.NoActionBar.Bridge">
12    <!-- Customize your theme here. -->
13    <item name="colorPrimary">@color/colorPrimary</item>
14    <item name="colorPrimaryDark">@color/colorPrimary</item>
15    <item name="colorAccent">@color/colorAccent</item>
16
17    <item name="materialCalendarStyle">@style/Widget.MaterialComponents.MaterialCalendar</item>
18    <item name="materialCalendarFullscreenTheme">@style/ThemeOverlay.MaterialComponents.MaterialCalendar.Fullscreen</item>
19    <item name="materialCalendarTheme">@style/ThemeOverlay.MaterialComponents.MaterialCalendar</item>
20</style>
21

(3) Set above style in Manifest.xml file with activity.

1 private val datePickerDialog by lazy {
2            DatePickerDialog(requireActivity(), R.style.SpinnerDatePickerDialog).apply {
3                setTitle(R.string.select_date)
4                datePicker.maxDate = LocalDate.now().minusDays(1).toMillis()
5                setOnDateSetListener { _, year, month, dayOfMonth ->
6                    viewModel.onDateSelected(year, month, dayOfMonth)
7                }
8            }
9        }
10    <!-- Base application theme. -->
11<style name="ScreenTheme" parent="Theme.MaterialComponents.Light.NoActionBar.Bridge">
12    <!-- Customize your theme here. -->
13    <item name="colorPrimary">@color/colorPrimary</item>
14    <item name="colorPrimaryDark">@color/colorPrimary</item>
15    <item name="colorAccent">@color/colorAccent</item>
16
17    <item name="materialCalendarStyle">@style/Widget.MaterialComponents.MaterialCalendar</item>
18    <item name="materialCalendarFullscreenTheme">@style/ThemeOverlay.MaterialComponents.MaterialCalendar.Fullscreen</item>
19    <item name="materialCalendarTheme">@style/ThemeOverlay.MaterialComponents.MaterialCalendar</item>
20</style>
21<activity
22        android:name=".DashboardActivity"
23        android:screenOrientation="portrait"
24        android:theme="@style/ScreenTheme"
25        android:windowSoftInputMode="stateAlwaysHidden" />
26

(4) Add the below code with a button click.

1 private val datePickerDialog by lazy {
2            DatePickerDialog(requireActivity(), R.style.SpinnerDatePickerDialog).apply {
3                setTitle(R.string.select_date)
4                datePicker.maxDate = LocalDate.now().minusDays(1).toMillis()
5                setOnDateSetListener { _, year, month, dayOfMonth ->
6                    viewModel.onDateSelected(year, month, dayOfMonth)
7                }
8            }
9        }
10    <!-- Base application theme. -->
11<style name="ScreenTheme" parent="Theme.MaterialComponents.Light.NoActionBar.Bridge">
12    <!-- Customize your theme here. -->
13    <item name="colorPrimary">@color/colorPrimary</item>
14    <item name="colorPrimaryDark">@color/colorPrimary</item>
15    <item name="colorAccent">@color/colorAccent</item>
16
17    <item name="materialCalendarStyle">@style/Widget.MaterialComponents.MaterialCalendar</item>
18    <item name="materialCalendarFullscreenTheme">@style/ThemeOverlay.MaterialComponents.MaterialCalendar.Fullscreen</item>
19    <item name="materialCalendarTheme">@style/ThemeOverlay.MaterialComponents.MaterialCalendar</item>
20</style>
21<activity
22        android:name=".DashboardActivity"
23        android:screenOrientation="portrait"
24        android:theme="@style/ScreenTheme"
25        android:windowSoftInputMode="stateAlwaysHidden" />
26val datePicker =
27                        MaterialDatePicker.Builder.datePicker()
28                                .setTitleText("Select date")
29                                .setSelection(MaterialDatePicker.todayInUtcMilliseconds())
30                                .build()
31
32                datePicker.show(childFragmentManager,"")
33
  • Use childFragmentManager if you want a calendar with fragment otherwise use supportFragmentManager with activity.

Output: enter image description here

Source https://stackoverflow.com/questions/71494291

QUESTION

Use selected element when selector allow for multiple options

Asked 2022-Mar-08 at 00:34

Sorry if my title is difficult to understand.

I've multiple fields named date1, date2... On Change of those fields, I want a full script to run. Today, I have simply copied the code for each dateN I have.

I would like to have a cleaner code and use the next JQuery selector:

1$("input[id^=date]")
2

The problem I face is that I don't know how to reuse the selected element into the subsequent code. I've tried with $(this) but it doesn't work, as it seems to be undefined.

Edit: as requested I show an example with $(this). The variable day stays empty. It works if I use the same selector as for month and year. The full example doesn't use $(this) yet but it's to show that my $(this) doesn't work.

1$("input[id^=date]")
2$("#date1").on("change", () => {
3      // Check validity of the date
4      const regexDate = /\d{2}\/\d{2}\/\d{4}/gm;
5      if (regexDate.test($("#date1").val()) == false) {
6        // Date format not valid, we quit the function
7        $("#info1").removeAttr("title");
8        $("#info1").hide();
9        return;
10      }
11
12      //Slice date
13      var day = $(this).val().substring(0, 2);
14      var month = $("#date1").val().substring(3, 5);
15      var year = $("#date1").val().substring(6, 10);
16
17      $.get("http://192.168.1.6:3000/getDateHistory/" + day + "/" + month + "/" + year, (data) => {
18        data = JSON.parse(data);
19        // Only display if not empty
20        if (data.length > 0) {
21          historyOfSameDate = "Other records exist at the same date: ";
22          for (var i = 0; i < data.length; i++) {
23            historyOfSameDate += data[i].desc + " - " + data[i].amount;
24            if (i < data.length - 1) {
25              historyOfSameDate += " | "
26            };
27          }
28          $("#info1").attr({
29            "title": historyOfSameDate
30          });
31          $("#info1").show();
32        } else {
33          $("#info1").removeAttr("title");
34          $("#info1").hide();
35
36        }
37      });
1$("input[id^=date]")
2$("#date1").on("change", () => {
3      // Check validity of the date
4      const regexDate = /\d{2}\/\d{2}\/\d{4}/gm;
5      if (regexDate.test($("#date1").val()) == false) {
6        // Date format not valid, we quit the function
7        $("#info1").removeAttr("title");
8        $("#info1").hide();
9        return;
10      }
11
12      //Slice date
13      var day = $(this).val().substring(0, 2);
14      var month = $("#date1").val().substring(3, 5);
15      var year = $("#date1").val().substring(6, 10);
16
17      $.get("http://192.168.1.6:3000/getDateHistory/" + day + "/" + month + "/" + year, (data) => {
18        data = JSON.parse(data);
19        // Only display if not empty
20        if (data.length > 0) {
21          historyOfSameDate = "Other records exist at the same date: ";
22          for (var i = 0; i < data.length; i++) {
23            historyOfSameDate += data[i].desc + " - " + data[i].amount;
24            if (i < data.length - 1) {
25              historyOfSameDate += " | "
26            };
27          }
28          $("#info1").attr({
29            "title": historyOfSameDate
30          });
31          $("#info1").show();
32        } else {
33          $("#info1").removeAttr("title");
34          $("#info1").hide();
35
36        }
37      });<tr>
38  <td><input class="form-control datepicker" id="date1" placeholder="Enter date"></td>
39  <td style="vertical-align:middle;"><i id="info1" class="bi bi-info-square-fill"></i></td>
40  <td>
41    <select class="form-control" id="type1" placeholder="Enter type">
42      <option value=""></option>
43    </select>
44  </td>
45  <!-- Options dynamically created -->
46  <td><input class="form-control" id="desc1" placeholder="Enter description"></td>
47  <td><input class="form-control" id="amount1" placeholder="Enter amount"></td>
48  <td>
49    <select class="form-control" id="payer1" placeholder="Enter type">
50      <option value=""></option>
51    </select>
52  </td>
53  <!-- Options dynamically created -->
54  <td>
55    <select class="form-control" id="paymentsource1" placeholder="Enter type">
56      <option value=""></option>
57    </select>
58  </td>
59  <!-- Options dynamically created -->
60  <td style="vertical-align:middle; color:orange;"><i id="warning1" class="bi bi-exclamation-triangle-fill" title="This record will be ignored because it either doesn't contain enough information or contains error(s)."></i></td>
61</tr>
62<tr>
63  <td><input class="form-control datepicker" id="date2" placeholder="Enter date"></td>
64  <td style="vertical-align:middle;"><i id="info2" class="bi bi-info-square-fill"></i></td>
65  <td>
66    <select class="form-control" id="type2" placeholder="Enter type">
67      <option value=""></option>
68    </select>
69  </td>
70  <!-- Options dynamically created -->
71  <td><input class="form-control" id="desc2" placeholder="Enter description"></td>
72  <td><input class="form-control" id="amount2" placeholder="Enter amount"></td>
73  <td>
74    <select class="form-control" id="payer2" placeholder="Enter type">
75      <option value=""></option>
76    </select>
77  </td>
78  <!-- Options dynamically created -->
79  <td>
80    <select class="form-control" id="paymentsource2" placeholder="Enter type">
81      <option value=""></option>
82    </select>
83  </td>
84  <!-- Options dynamically created -->
85  <td>

Thank you

ANSWER

Answered 2022-Feb-27 at 11:42

Use it like this:

1$("input[id^=date]")
2$("#date1").on("change", () => {
3      // Check validity of the date
4      const regexDate = /\d{2}\/\d{2}\/\d{4}/gm;
5      if (regexDate.test($("#date1").val()) == false) {
6        // Date format not valid, we quit the function
7        $("#info1").removeAttr("title");
8        $("#info1").hide();
9        return;
10      }
11
12      //Slice date
13      var day = $(this).val().substring(0, 2);
14      var month = $("#date1").val().substring(3, 5);
15      var year = $("#date1").val().substring(6, 10);
16
17      $.get("http://192.168.1.6:3000/getDateHistory/" + day + "/" + month + "/" + year, (data) => {
18        data = JSON.parse(data);
19        // Only display if not empty
20        if (data.length > 0) {
21          historyOfSameDate = "Other records exist at the same date: ";
22          for (var i = 0; i < data.length; i++) {
23            historyOfSameDate += data[i].desc + " - " + data[i].amount;
24            if (i < data.length - 1) {
25              historyOfSameDate += " | "
26            };
27          }
28          $("#info1").attr({
29            "title": historyOfSameDate
30          });
31          $("#info1").show();
32        } else {
33          $("#info1").removeAttr("title");
34          $("#info1").hide();
35
36        }
37      });<tr>
38  <td><input class="form-control datepicker" id="date1" placeholder="Enter date"></td>
39  <td style="vertical-align:middle;"><i id="info1" class="bi bi-info-square-fill"></i></td>
40  <td>
41    <select class="form-control" id="type1" placeholder="Enter type">
42      <option value=""></option>
43    </select>
44  </td>
45  <!-- Options dynamically created -->
46  <td><input class="form-control" id="desc1" placeholder="Enter description"></td>
47  <td><input class="form-control" id="amount1" placeholder="Enter amount"></td>
48  <td>
49    <select class="form-control" id="payer1" placeholder="Enter type">
50      <option value=""></option>
51    </select>
52  </td>
53  <!-- Options dynamically created -->
54  <td>
55    <select class="form-control" id="paymentsource1" placeholder="Enter type">
56      <option value=""></option>
57    </select>
58  </td>
59  <!-- Options dynamically created -->
60  <td style="vertical-align:middle; color:orange;"><i id="warning1" class="bi bi-exclamation-triangle-fill" title="This record will be ignored because it either doesn't contain enough information or contains error(s)."></i></td>
61</tr>
62<tr>
63  <td><input class="form-control datepicker" id="date2" placeholder="Enter date"></td>
64  <td style="vertical-align:middle;"><i id="info2" class="bi bi-info-square-fill"></i></td>
65  <td>
66    <select class="form-control" id="type2" placeholder="Enter type">
67      <option value=""></option>
68    </select>
69  </td>
70  <!-- Options dynamically created -->
71  <td><input class="form-control" id="desc2" placeholder="Enter description"></td>
72  <td><input class="form-control" id="amount2" placeholder="Enter amount"></td>
73  <td>
74    <select class="form-control" id="payer2" placeholder="Enter type">
75      <option value=""></option>
76    </select>
77  </td>
78  <!-- Options dynamically created -->
79  <td>
80    <select class="form-control" id="paymentsource2" placeholder="Enter type">
81      <option value=""></option>
82    </select>
83  </td>
84  <!-- Options dynamically created -->
85  <td>$('input[type=date]').click(function() {
86    var fields = $(this);
87    // do something with it
88    return false;
89});
90

Source https://stackoverflow.com/questions/71272202

QUESTION

Dynamic form returns the same value for the first and second input

Asked 2022-Feb-25 at 09:47

I'm creating a custom dynamic form using Material UI https://mui.com/ library as the component for my React Js app.

Here is the initial state of the dynamic form component. enter image description here

As we can see that the dynamic form component starts only with one delivery point form. We could add another delivery point form by clicking the "Add Delivery" button. Here is the example after clicking the "Add Delivery" button.

enter image description here

The problem is: the first form and the second form have the same values (if there are more than 1 form) after we gave input to one of the first or second forms as seen in the screenshot below. This is not the condition I want.

enter image description here

But the rest (third, fourth, and so on) forms are unique as seen in the screenshot below. This is the condition I want.

enter image description here

Here is the simple working code:

DeliveryPoint.jsx

1const DeliveryPoint = (props) => {
2  const {
3    initialFormObject,
4    formObject,
5    setFormObject,
6    collapseObject,
7    setCollapseObject
8  } = props;
9
10  const classes = useStyles();
11
12  const deliveryPointBaseObject = initialFormObject.deliveryPointList[0];
13
14  const handleFormObjectChange = (inputEvent, inputIndex) => {
15    let deliveryPointListData = [...formObject.deliveryPointList];
16    deliveryPointListData[inputIndex][inputEvent.target.name] =
17      inputEvent.target.value;
18
19    setFormObject((current) => ({
20      ...current,
21      deliveryPointList: deliveryPointListData
22    }));
23  };
24
25  const handleDatePickerChange = (inputNewValue, inputIndex) => {
26    let deliveryPointListData = [...formObject.deliveryPointList];
27    deliveryPointListData[inputIndex].deliveryDate = inputNewValue;
28
29    setFormObject((current) => ({
30      ...current,
31      deliveryPointList: deliveryPointListData
32    }));
33  };
34
35  const handleCollapseChange = (inputIndex) => {
36    let deliveryPointListData = [...collapseObject.deliveryPointList];
37    deliveryPointListData[inputIndex] = !deliveryPointListData[inputIndex];
38
39    setCollapseObject((current) => ({
40      ...current,
41      deliveryPointList: deliveryPointListData
42    }));
43  };
44
45  const handleAddFormItemButtonClick = () => {
46    let deliveryPointListData = [...formObject.deliveryPointList];
47    deliveryPointListData.push(deliveryPointBaseObject);
48
49    setFormObject((current) => ({
50      ...current,
51      deliveryPointList: deliveryPointListData
52    }));
53
54    deliveryPointListData = [...collapseObject.deliveryPointList];
55    deliveryPointListData.push(false);
56
57    setCollapseObject((current) => ({
58      ...current,
59      deliveryPointList: deliveryPointListData
60    }));
61  };
62
63  const handleDeleteFormItemButtonClick = (inputIndex) => {
64    let deliveryPointListData = [...formObject.deliveryPointList];
65    deliveryPointListData.splice(inputIndex, 1);
66
67    setFormObject((current) => ({
68      ...current,
69      deliveryPointList: deliveryPointListData
70    }));
71
72    deliveryPointListData = [...collapseObject.deliveryPointList];
73    deliveryPointListData.splice(inputIndex, 1);
74
75    setCollapseObject((current) => ({
76      ...current,
77      deliveryPointList: deliveryPointListData
78    }));
79  };
80
81  return (
82    <>
83      {formObject.deliveryPointList.map((item, index) => (
84        <Box key={index} className={classes.formItemContainer}>
85          <Box className={classes.formItemTitleContainer}>
86            {/* TITLE */}
87            <Typography variant="h6">
88              {index === 0 ? `Delivery point` : `#${index + 1} Delivery point`}
89            </Typography>
90
91            {/* ADD OR DELETE BUTTON */}
92            {index === 0 ? (
93              <Button
94                className={classes.formItemTitleButton}
95                variant="outlined"
96                startIcon={<IconAdd />}
97                onClick={handleAddFormItemButtonClick}
98              >
99                Add Delivery
100              </Button>
101            ) : (
102              <Button
103                className={classes.formItemTitleButton}
104                variant="outlined"
105                startIcon={<IconRemove />}
106                color="error"
107                onClick={() => handleDeleteFormItemButtonClick(index)}
108              >
109                Remove Delivery
110              </Button>
111            )}
112          </Box>
113
114          {/* CONSIGNEE */}
115          <FormControl
116            required
117            variant="outlined"
118            className={classes.formItemInput}
119          >
120            <InputLabel>Consignee</InputLabel>
121
122            <OutlinedInput
123              label="Consignee"
124              type="text"
125              name="consignee"
126              value={item.consignee}
127              onChange={(event) => handleFormObjectChange(event, index)}
128            />
129
130            <FormHelperText>
131              Search for name, street, city, or state by typing in the box.
132            </FormHelperText>
133          </FormControl>
134
135          {/* DELIVERY DATE */}
136          <LocalizationProvider dateAdapter={AdapterDateFns}>
137            <DatePicker
138              disableFuture
139              label="Select Delivery Date"
140              openTo="year"
141              views={["year", "month", "day"]}
142              value={item.deliveryDate}
143              onChange={(newValue) => handleDatePickerChange(newValue, index)}
144              renderInput={(params) => (
145                <TextField
146                  required
147                  className={classes.formItemInput}
148                  {...params}
149                />
150              )}
151            />
152          </LocalizationProvider>
153
154          {/* COLLAPSE */}
155          <Collapse
156            in={collapseObject.deliveryPointList[index]}
157            timeout="auto"
158            unmountOnExit
159            className={classes.formItemCollapse}
160          >
161            {/* DELIVERY INSTRUCTION */}
162            <FormControl variant="outlined" className={classes.formItemInput}>
163              <InputLabel>Delivery Instructions</InputLabel>
164
165              <OutlinedInput
166                label="Delivery Instructions"
167                type="text"
168                name="deliveryInstruction"
169                value={item.deliveryInstruction}
170                onChange={(event) => handleFormObjectChange(event, index)}
171              />
172            </FormControl>
173          </Collapse>
174
175          {/* EXPAND BUTTON */}
176          <Button
177            variant="contained"
178            disableElevation
179            startIcon={
180              collapseObject.deliveryPoint ? (
181                <IconArrowDropUp />
182              ) : (
183                <IconArrowDropDown />
184              )
185            }
186            className={classes.formItemButtonExpand}
187            onClick={() => handleCollapseChange(index)}
188          >
189            {collapseObject.deliveryPoint
190              ? "Hide full data entry"
191              : "Fill in more complete data?"}
192          </Button>
193        </Box>
194      ))}
195    </>
196  );
197};
198
199export default DeliveryPoint;
200

App.jsx

1const DeliveryPoint = (props) => {
2  const {
3    initialFormObject,
4    formObject,
5    setFormObject,
6    collapseObject,
7    setCollapseObject
8  } = props;
9
10  const classes = useStyles();
11
12  const deliveryPointBaseObject = initialFormObject.deliveryPointList[0];
13
14  const handleFormObjectChange = (inputEvent, inputIndex) => {
15    let deliveryPointListData = [...formObject.deliveryPointList];
16    deliveryPointListData[inputIndex][inputEvent.target.name] =
17      inputEvent.target.value;
18
19    setFormObject((current) => ({
20      ...current,
21      deliveryPointList: deliveryPointListData
22    }));
23  };
24
25  const handleDatePickerChange = (inputNewValue, inputIndex) => {
26    let deliveryPointListData = [...formObject.deliveryPointList];
27    deliveryPointListData[inputIndex].deliveryDate = inputNewValue;
28
29    setFormObject((current) => ({
30      ...current,
31      deliveryPointList: deliveryPointListData
32    }));
33  };
34
35  const handleCollapseChange = (inputIndex) => {
36    let deliveryPointListData = [...collapseObject.deliveryPointList];
37    deliveryPointListData[inputIndex] = !deliveryPointListData[inputIndex];
38
39    setCollapseObject((current) => ({
40      ...current,
41      deliveryPointList: deliveryPointListData
42    }));
43  };
44
45  const handleAddFormItemButtonClick = () => {
46    let deliveryPointListData = [...formObject.deliveryPointList];
47    deliveryPointListData.push(deliveryPointBaseObject);
48
49    setFormObject((current) => ({
50      ...current,
51      deliveryPointList: deliveryPointListData
52    }));
53
54    deliveryPointListData = [...collapseObject.deliveryPointList];
55    deliveryPointListData.push(false);
56
57    setCollapseObject((current) => ({
58      ...current,
59      deliveryPointList: deliveryPointListData
60    }));
61  };
62
63  const handleDeleteFormItemButtonClick = (inputIndex) => {
64    let deliveryPointListData = [...formObject.deliveryPointList];
65    deliveryPointListData.splice(inputIndex, 1);
66
67    setFormObject((current) => ({
68      ...current,
69      deliveryPointList: deliveryPointListData
70    }));
71
72    deliveryPointListData = [...collapseObject.deliveryPointList];
73    deliveryPointListData.splice(inputIndex, 1);
74
75    setCollapseObject((current) => ({
76      ...current,
77      deliveryPointList: deliveryPointListData
78    }));
79  };
80
81  return (
82    <>
83      {formObject.deliveryPointList.map((item, index) => (
84        <Box key={index} className={classes.formItemContainer}>
85          <Box className={classes.formItemTitleContainer}>
86            {/* TITLE */}
87            <Typography variant="h6">
88              {index === 0 ? `Delivery point` : `#${index + 1} Delivery point`}
89            </Typography>
90
91            {/* ADD OR DELETE BUTTON */}
92            {index === 0 ? (
93              <Button
94                className={classes.formItemTitleButton}
95                variant="outlined"
96                startIcon={<IconAdd />}
97                onClick={handleAddFormItemButtonClick}
98              >
99                Add Delivery
100              </Button>
101            ) : (
102              <Button
103                className={classes.formItemTitleButton}
104                variant="outlined"
105                startIcon={<IconRemove />}
106                color="error"
107                onClick={() => handleDeleteFormItemButtonClick(index)}
108              >
109                Remove Delivery
110              </Button>
111            )}
112          </Box>
113
114          {/* CONSIGNEE */}
115          <FormControl
116            required
117            variant="outlined"
118            className={classes.formItemInput}
119          >
120            <InputLabel>Consignee</InputLabel>
121
122            <OutlinedInput
123              label="Consignee"
124              type="text"
125              name="consignee"
126              value={item.consignee}
127              onChange={(event) => handleFormObjectChange(event, index)}
128            />
129
130            <FormHelperText>
131              Search for name, street, city, or state by typing in the box.
132            </FormHelperText>
133          </FormControl>
134
135          {/* DELIVERY DATE */}
136          <LocalizationProvider dateAdapter={AdapterDateFns}>
137            <DatePicker
138              disableFuture
139              label="Select Delivery Date"
140              openTo="year"
141              views={["year", "month", "day"]}
142              value={item.deliveryDate}
143              onChange={(newValue) => handleDatePickerChange(newValue, index)}
144              renderInput={(params) => (
145                <TextField
146                  required
147                  className={classes.formItemInput}
148                  {...params}
149                />
150              )}
151            />
152          </LocalizationProvider>
153
154          {/* COLLAPSE */}
155          <Collapse
156            in={collapseObject.deliveryPointList[index]}
157            timeout="auto"
158            unmountOnExit
159            className={classes.formItemCollapse}
160          >
161            {/* DELIVERY INSTRUCTION */}
162            <FormControl variant="outlined" className={classes.formItemInput}>
163              <InputLabel>Delivery Instructions</InputLabel>
164
165              <OutlinedInput
166                label="Delivery Instructions"
167                type="text"
168                name="deliveryInstruction"
169                value={item.deliveryInstruction}
170                onChange={(event) => handleFormObjectChange(event, index)}
171              />
172            </FormControl>
173          </Collapse>
174
175          {/* EXPAND BUTTON */}
176          <Button
177            variant="contained"
178            disableElevation
179            startIcon={
180              collapseObject.deliveryPoint ? (
181                <IconArrowDropUp />
182              ) : (
183                <IconArrowDropDown />
184              )
185            }
186            className={classes.formItemButtonExpand}
187            onClick={() => handleCollapseChange(index)}
188          >
189            {collapseObject.deliveryPoint
190              ? "Hide full data entry"
191              : "Fill in more complete data?"}
192          </Button>
193        </Box>
194      ))}
195    </>
196  );
197};
198
199export default DeliveryPoint;
200const App = () => {
201  const classes = useStyles();
202
203  const initialFormObject = {
204    // DELIVERY POINT
205    deliveryPointList: [
206      {
207        consignee: "",
208        deliveryDate: new Date(),
209        deliveryInstruction: ""
210      }
211    ]
212    // OTHER OBJECT ITEMS HERE
213  };
214
215  const initialCollapseObject = {
216    deliveryPointList: [false]
217    // OTHER LIST ITEMS HERE
218  };
219
220  const [formObject, setFormObject] = useState(initialFormObject);
221  const [collapseObject, setCollapseObject] = useState(initialCollapseObject);
222
223  return (
224    <Box className={classes.pageRoot}>
225      {/* FORM */}
226      <Box className={classes.formContainer}>
227        {/* DELIVERY POINT */}
228        <DeliveryPoint
229          initialFormObject={initialFormObject}
230          formObject={formObject}
231          setFormObject={setFormObject}
232          collapseObject={collapseObject}
233          setCollapseObject={setCollapseObject}
234        />
235      </Box>
236    </Box>
237  );
238};
239
240export default App;
241

Here is the full demo https://codesandbox.io/s/stackoverflow-dynamic-form-wxrmd0

Steps to reproduce:

  1. Click the "Add Delivery" button twice. So there will be 3 delivery point forms.
  2. Change the "consignee" or the "delivery date" in the first delivery point form. Therefore, the second delivery point form will have the same value as the first form.

What's wrong with my state management and what's the solution for this?

Note: you can assume the OultinedInput component from Material UI as an HTML input element.

ANSWER

Answered 2022-Feb-25 at 09:40
Issue

You are mutating the state in your handleFormObjectChange and handleDatePickerChange handlers.

1const DeliveryPoint = (props) => {
2  const {
3    initialFormObject,
4    formObject,
5    setFormObject,
6    collapseObject,
7    setCollapseObject
8  } = props;
9
10  const classes = useStyles();
11
12  const deliveryPointBaseObject = initialFormObject.deliveryPointList[0];
13
14  const handleFormObjectChange = (inputEvent, inputIndex) => {
15    let deliveryPointListData = [...formObject.deliveryPointList];
16    deliveryPointListData[inputIndex][inputEvent.target.name] =
17      inputEvent.target.value;
18
19    setFormObject((current) => ({
20      ...current,
21      deliveryPointList: deliveryPointListData
22    }));
23  };
24
25  const handleDatePickerChange = (inputNewValue, inputIndex) => {
26    let deliveryPointListData = [...formObject.deliveryPointList];
27    deliveryPointListData[inputIndex].deliveryDate = inputNewValue;
28
29    setFormObject((current) => ({
30      ...current,
31      deliveryPointList: deliveryPointListData
32    }));
33  };
34
35  const handleCollapseChange = (inputIndex) => {
36    let deliveryPointListData = [...collapseObject.deliveryPointList];
37    deliveryPointListData[inputIndex] = !deliveryPointListData[inputIndex];
38
39    setCollapseObject((current) => ({
40      ...current,
41      deliveryPointList: deliveryPointListData
42    }));
43  };
44
45  const handleAddFormItemButtonClick = () => {
46    let deliveryPointListData = [...formObject.deliveryPointList];
47    deliveryPointListData.push(deliveryPointBaseObject);
48
49    setFormObject((current) => ({
50      ...current,
51      deliveryPointList: deliveryPointListData
52    }));
53
54    deliveryPointListData = [...collapseObject.deliveryPointList];
55    deliveryPointListData.push(false);
56
57    setCollapseObject((current) => ({
58      ...current,
59      deliveryPointList: deliveryPointListData
60    }));
61  };
62
63  const handleDeleteFormItemButtonClick = (inputIndex) => {
64    let deliveryPointListData = [...formObject.deliveryPointList];
65    deliveryPointListData.splice(inputIndex, 1);
66
67    setFormObject((current) => ({
68      ...current,
69      deliveryPointList: deliveryPointListData
70    }));
71
72    deliveryPointListData = [...collapseObject.deliveryPointList];
73    deliveryPointListData.splice(inputIndex, 1);
74
75    setCollapseObject((current) => ({
76      ...current,
77      deliveryPointList: deliveryPointListData
78    }));
79  };
80
81  return (
82    <>
83      {formObject.deliveryPointList.map((item, index) => (
84        <Box key={index} className={classes.formItemContainer}>
85          <Box className={classes.formItemTitleContainer}>
86            {/* TITLE */}
87            <Typography variant="h6">
88              {index === 0 ? `Delivery point` : `#${index + 1} Delivery point`}
89            </Typography>
90
91            {/* ADD OR DELETE BUTTON */}
92            {index === 0 ? (
93              <Button
94                className={classes.formItemTitleButton}
95                variant="outlined"
96                startIcon={<IconAdd />}
97                onClick={handleAddFormItemButtonClick}
98              >
99                Add Delivery
100              </Button>
101            ) : (
102              <Button
103                className={classes.formItemTitleButton}
104                variant="outlined"
105                startIcon={<IconRemove />}
106                color="error"
107                onClick={() => handleDeleteFormItemButtonClick(index)}
108              >
109                Remove Delivery
110              </Button>
111            )}
112          </Box>
113
114          {/* CONSIGNEE */}
115          <FormControl
116            required
117            variant="outlined"
118            className={classes.formItemInput}
119          >
120            <InputLabel>Consignee</InputLabel>
121
122            <OutlinedInput
123              label="Consignee"
124              type="text"
125              name="consignee"
126              value={item.consignee}
127              onChange={(event) => handleFormObjectChange(event, index)}
128            />
129
130            <FormHelperText>
131              Search for name, street, city, or state by typing in the box.
132            </FormHelperText>
133          </FormControl>
134
135          {/* DELIVERY DATE */}
136          <LocalizationProvider dateAdapter={AdapterDateFns}>
137            <DatePicker
138              disableFuture
139              label="Select Delivery Date"
140              openTo="year"
141              views={["year", "month", "day"]}
142              value={item.deliveryDate}
143              onChange={(newValue) => handleDatePickerChange(newValue, index)}
144              renderInput={(params) => (
145                <TextField
146                  required
147                  className={classes.formItemInput}
148                  {...params}
149                />
150              )}
151            />
152          </LocalizationProvider>
153
154          {/* COLLAPSE */}
155          <Collapse
156            in={collapseObject.deliveryPointList[index]}
157            timeout="auto"
158            unmountOnExit
159            className={classes.formItemCollapse}
160          >
161            {/* DELIVERY INSTRUCTION */}
162            <FormControl variant="outlined" className={classes.formItemInput}>
163              <InputLabel>Delivery Instructions</InputLabel>
164
165              <OutlinedInput
166                label="Delivery Instructions"
167                type="text"
168                name="deliveryInstruction"
169                value={item.deliveryInstruction}
170                onChange={(event) => handleFormObjectChange(event, index)}
171              />
172            </FormControl>
173          </Collapse>
174
175          {/* EXPAND BUTTON */}
176          <Button
177            variant="contained"
178            disableElevation
179            startIcon={
180              collapseObject.deliveryPoint ? (
181                <IconArrowDropUp />
182              ) : (
183                <IconArrowDropDown />
184              )
185            }
186            className={classes.formItemButtonExpand}
187            onClick={() => handleCollapseChange(index)}
188          >
189            {collapseObject.deliveryPoint
190              ? "Hide full data entry"
191              : "Fill in more complete data?"}
192          </Button>
193        </Box>
194      ))}
195    </>
196  );
197};
198
199export default DeliveryPoint;
200const App = () => {
201  const classes = useStyles();
202
203  const initialFormObject = {
204    // DELIVERY POINT
205    deliveryPointList: [
206      {
207        consignee: "",
208        deliveryDate: new Date(),
209        deliveryInstruction: ""
210      }
211    ]
212    // OTHER OBJECT ITEMS HERE
213  };
214
215  const initialCollapseObject = {
216    deliveryPointList: [false]
217    // OTHER LIST ITEMS HERE
218  };
219
220  const [formObject, setFormObject] = useState(initialFormObject);
221  const [collapseObject, setCollapseObject] = useState(initialCollapseObject);
222
223  return (
224    <Box className={classes.pageRoot}>
225      {/* FORM */}
226      <Box className={classes.formContainer}>
227        {/* DELIVERY POINT */}
228        <DeliveryPoint
229          initialFormObject={initialFormObject}
230          formObject={formObject}
231          setFormObject={setFormObject}
232          collapseObject={collapseObject}
233          setCollapseObject={setCollapseObject}
234        />
235      </Box>
236    </Box>
237  );
238};
239
240export default App;
241const handleFormObjectChange = (inputEvent, inputIndex) => {
242  let deliveryPointListData = [...formObject.deliveryPointList];
243
244  // Mutates the nested property!!
245  deliveryPointListData[inputIndex][inputEvent.target.name] =
246    inputEvent.target.value;
247
248  setFormObject((current) => ({
249    ...current,
250    deliveryPointList: deliveryPointListData
251  }));
252};
253
254const handleDatePickerChange = (inputNewValue, inputIndex) => {
255  let deliveryPointListData = [...formObject.deliveryPointList];
256
257  // Mutates the nested property!!
258  deliveryPointListData[inputIndex].deliveryDate = inputNewValue;
259
260  setFormObject((current) => ({
261    ...current,
262    deliveryPointList: deliveryPointListData
263  }));
264};
265
Solution

Ensure you are shallow copying all properties and nested properties that are being updated. This ensures all updates create new object references.

1const DeliveryPoint = (props) => {
2  const {
3    initialFormObject,
4    formObject,
5    setFormObject,
6    collapseObject,
7    setCollapseObject
8  } = props;
9
10  const classes = useStyles();
11
12  const deliveryPointBaseObject = initialFormObject.deliveryPointList[0];
13
14  const handleFormObjectChange = (inputEvent, inputIndex) => {
15    let deliveryPointListData = [...formObject.deliveryPointList];
16    deliveryPointListData[inputIndex][inputEvent.target.name] =
17      inputEvent.target.value;
18
19    setFormObject((current) => ({
20      ...current,
21      deliveryPointList: deliveryPointListData
22    }));
23  };
24
25  const handleDatePickerChange = (inputNewValue, inputIndex) => {
26    let deliveryPointListData = [...formObject.deliveryPointList];
27    deliveryPointListData[inputIndex].deliveryDate = inputNewValue;
28
29    setFormObject((current) => ({
30      ...current,
31      deliveryPointList: deliveryPointListData
32    }));
33  };
34
35  const handleCollapseChange = (inputIndex) => {
36    let deliveryPointListData = [...collapseObject.deliveryPointList];
37    deliveryPointListData[inputIndex] = !deliveryPointListData[inputIndex];
38
39    setCollapseObject((current) => ({
40      ...current,
41      deliveryPointList: deliveryPointListData
42    }));
43  };
44
45  const handleAddFormItemButtonClick = () => {
46    let deliveryPointListData = [...formObject.deliveryPointList];
47    deliveryPointListData.push(deliveryPointBaseObject);
48
49    setFormObject((current) => ({
50      ...current,
51      deliveryPointList: deliveryPointListData
52    }));
53
54    deliveryPointListData = [...collapseObject.deliveryPointList];
55    deliveryPointListData.push(false);
56
57    setCollapseObject((current) => ({
58      ...current,
59      deliveryPointList: deliveryPointListData
60    }));
61  };
62
63  const handleDeleteFormItemButtonClick = (inputIndex) => {
64    let deliveryPointListData = [...formObject.deliveryPointList];
65    deliveryPointListData.splice(inputIndex, 1);
66
67    setFormObject((current) => ({
68      ...current,
69      deliveryPointList: deliveryPointListData
70    }));
71
72    deliveryPointListData = [...collapseObject.deliveryPointList];
73    deliveryPointListData.splice(inputIndex, 1);
74
75    setCollapseObject((current) => ({
76      ...current,
77      deliveryPointList: deliveryPointListData
78    }));
79  };
80
81  return (
82    <>
83      {formObject.deliveryPointList.map((item, index) => (
84        <Box key={index} className={classes.formItemContainer}>
85          <Box className={classes.formItemTitleContainer}>
86            {/* TITLE */}
87            <Typography variant="h6">
88              {index === 0 ? `Delivery point` : `#${index + 1} Delivery point`}
89            </Typography>
90
91            {/* ADD OR DELETE BUTTON */}
92            {index === 0 ? (
93              <Button
94                className={classes.formItemTitleButton}
95                variant="outlined"
96                startIcon={<IconAdd />}
97                onClick={handleAddFormItemButtonClick}
98              >
99                Add Delivery
100              </Button>
101            ) : (
102              <Button
103                className={classes.formItemTitleButton}
104                variant="outlined"
105                startIcon={<IconRemove />}
106                color="error"
107                onClick={() => handleDeleteFormItemButtonClick(index)}
108              >
109                Remove Delivery
110              </Button>
111            )}
112          </Box>
113
114          {/* CONSIGNEE */}
115          <FormControl
116            required
117            variant="outlined"
118            className={classes.formItemInput}
119          >
120            <InputLabel>Consignee</InputLabel>
121
122            <OutlinedInput
123              label="Consignee"
124              type="text"
125              name="consignee"
126              value={item.consignee}
127              onChange={(event) => handleFormObjectChange(event, index)}
128            />
129
130            <FormHelperText>
131              Search for name, street, city, or state by typing in the box.
132            </FormHelperText>
133          </FormControl>
134
135          {/* DELIVERY DATE */}
136          <LocalizationProvider dateAdapter={AdapterDateFns}>
137            <DatePicker
138              disableFuture
139              label="Select Delivery Date"
140              openTo="year"
141              views={["year", "month", "day"]}
142              value={item.deliveryDate}
143              onChange={(newValue) => handleDatePickerChange(newValue, index)}
144              renderInput={(params) => (
145                <TextField
146                  required
147                  className={classes.formItemInput}
148                  {...params}
149                />
150              )}
151            />
152          </LocalizationProvider>
153
154          {/* COLLAPSE */}
155          <Collapse
156            in={collapseObject.deliveryPointList[index]}
157            timeout="auto"
158            unmountOnExit
159            className={classes.formItemCollapse}
160          >
161            {/* DELIVERY INSTRUCTION */}
162            <FormControl variant="outlined" className={classes.formItemInput}>
163              <InputLabel>Delivery Instructions</InputLabel>
164
165              <OutlinedInput
166                label="Delivery Instructions"
167                type="text"
168                name="deliveryInstruction"
169                value={item.deliveryInstruction}
170                onChange={(event) => handleFormObjectChange(event, index)}
171              />
172            </FormControl>
173          </Collapse>
174
175          {/* EXPAND BUTTON */}
176          <Button
177            variant="contained"
178            disableElevation
179            startIcon={
180              collapseObject.deliveryPoint ? (
181                <IconArrowDropUp />
182              ) : (
183                <IconArrowDropDown />
184              )
185            }
186            className={classes.formItemButtonExpand}
187            onClick={() => handleCollapseChange(index)}
188          >
189            {collapseObject.deliveryPoint
190              ? "Hide full data entry"
191              : "Fill in more complete data?"}
192          </Button>
193        </Box>
194      ))}
195    </>
196  );
197};
198
199export default DeliveryPoint;
200const App = () => {
201  const classes = useStyles();
202
203  const initialFormObject = {
204    // DELIVERY POINT
205    deliveryPointList: [
206      {
207        consignee: "",
208        deliveryDate: new Date(),
209        deliveryInstruction: ""
210      }
211    ]
212    // OTHER OBJECT ITEMS HERE
213  };
214
215  const initialCollapseObject = {
216    deliveryPointList: [false]
217    // OTHER LIST ITEMS HERE
218  };
219
220  const [formObject, setFormObject] = useState(initialFormObject);
221  const [collapseObject, setCollapseObject] = useState(initialCollapseObject);
222
223  return (
224    <Box className={classes.pageRoot}>
225      {/* FORM */}
226      <Box className={classes.formContainer}>
227        {/* DELIVERY POINT */}
228        <DeliveryPoint
229          initialFormObject={initialFormObject}
230          formObject={formObject}
231          setFormObject={setFormObject}
232          collapseObject={collapseObject}
233          setCollapseObject={setCollapseObject}
234        />
235      </Box>
236    </Box>
237  );
238};
239
240export default App;
241const handleFormObjectChange = (inputEvent, inputIndex) => {
242  let deliveryPointListData = [...formObject.deliveryPointList];
243
244  // Mutates the nested property!!
245  deliveryPointListData[inputIndex][inputEvent.target.name] =
246    inputEvent.target.value;
247
248  setFormObject((current) => ({
249    ...current,
250    deliveryPointList: deliveryPointListData
251  }));
252};
253
254const handleDatePickerChange = (inputNewValue, inputIndex) => {
255  let deliveryPointListData = [...formObject.deliveryPointList];
256
257  // Mutates the nested property!!
258  deliveryPointListData[inputIndex].deliveryDate = inputNewValue;
259
260  setFormObject((current) => ({
261    ...current,
262    deliveryPointList: deliveryPointListData
263  }));
264};
265const handleFormObjectChange = (inputEvent, inputIndex) => {
266  let deliveryPointListData = [...formObject.deliveryPointList];
267
268  deliveryPointListData[inputIndex] = {
269    ...deliveryPointListData[inputIndex], // <-- shallow copy
270    [inputEvent.target.name]: inputEvent.target.value
271  };
272
273  setFormObject((current) => ({
274    ...current,
275    deliveryPointList: deliveryPointListData
276  }));
277};
278
279const handleDatePickerChange = (inputNewValue, inputIndex) => {
280  let deliveryPointListData = [...formObject.deliveryPointList];
281
282  deliveryPointListData[inputIndex] = {
283    ...deliveryPointListData[inputIndex], // <-- shallow copy
284    deliveryDate: inputNewValue,
285  };
286
287  setFormObject((current) => ({
288    ...current,
289    deliveryPointList: deliveryPointListData
290  }));
291};
292

Edit dynamic-form-returns-the-same-value-for-the-first-and-second-input

Source https://stackoverflow.com/questions/71263503

QUESTION

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

Asked 2022-Feb-23 at 16:12

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

1<?php
2
3namespace common\models;
4
5use yii\behaviors\TimestampBehavior;
6use yii\db\ActiveRecord;
7use yii\db\Expression;
8
9class WorkHours extends _source_WorkHours
10{
11    public const WEEK_DAY_MON = 'Mon';
12    public const WEEK_DAY_TUE = 'Tue';
13    public const WEEK_DAY_WED = 'Wed';
14    public const WEEK_DAY_THU = 'Thu';
15    public const WEEK_DAY_FRI = 'Fri';
16    public const WEEK_DAY_SAT = 'Sat';
17    public const WEEK_DAY_SUN = 'Sun';
18
19
20    /**
21     * {@inheritdoc}
22     */
23    public function behaviors(): array
24    {
25        return [
26            'timestamp' => [
27                'class'      => TimestampBehavior::class,
28                'attributes' => [
29                    ActiveRecord::EVENT_BEFORE_INSERT => ['created_at'],
30                ],
31                'value'      => new Expression('NOW()'),
32            ],
33        ];
34    }
35
36    public static function weekDays(): array
37    {
38        return [
39            self::WEEK_DAY_MON => 'Monday',
40            self::WEEK_DAY_TUE => 'Tuesday',
41            self::WEEK_DAY_WED => 'Wednesday',
42            self::WEEK_DAY_THU => 'Thursday',
43            self::WEEK_DAY_FRI => 'Friday',
44            self::WEEK_DAY_SAT => 'Saturday',
45            self::WEEK_DAY_SUN => 'Sunday',
46        ];
47    }
48
49    public static function getWeekDay(string $val): string
50    {
51        $ar = self::weekDays();
52
53        return $ar[$val] ?? $val;
54    }
55
56    public static function hoursList(): array
57    {
58        $list = [];
59        for ($i = 0; $i < 24; $i++) {
60            $A = 'AM';
61            $n = $i;
62            if ($i >= 12) {
63                $A = 'PM';
64                $n = $i - 12;
65            }
66
67            $n = $n < 10 ? '0' . $n : $n;
68            $_A = ($i === 12 ? 'AM' : $A);
69            $list[$i . '.00'] = $n . '.00 ' . ($i === 0 ? 'PM' : $_A);
70            $list[$i . '.30'] = $n . '.30 ' . $A;
71        }
72        return $list;
73    }
74}
75

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

1<?php
2
3namespace common\models;
4
5use yii\behaviors\TimestampBehavior;
6use yii\db\ActiveRecord;
7use yii\db\Expression;
8
9class WorkHours extends _source_WorkHours
10{
11    public const WEEK_DAY_MON = 'Mon';
12    public const WEEK_DAY_TUE = 'Tue';
13    public const WEEK_DAY_WED = 'Wed';
14    public const WEEK_DAY_THU = 'Thu';
15    public const WEEK_DAY_FRI = 'Fri';
16    public const WEEK_DAY_SAT = 'Sat';
17    public const WEEK_DAY_SUN = 'Sun';
18
19
20    /**
21     * {@inheritdoc}
22     */
23    public function behaviors(): array
24    {
25        return [
26            'timestamp' => [
27                'class'      => TimestampBehavior::class,
28                'attributes' => [
29                    ActiveRecord::EVENT_BEFORE_INSERT => ['created_at'],
30                ],
31                'value'      => new Expression('NOW()'),
32            ],
33        ];
34    }
35
36    public static function weekDays(): array
37    {
38        return [
39            self::WEEK_DAY_MON => 'Monday',
40            self::WEEK_DAY_TUE => 'Tuesday',
41            self::WEEK_DAY_WED => 'Wednesday',
42            self::WEEK_DAY_THU => 'Thursday',
43            self::WEEK_DAY_FRI => 'Friday',
44            self::WEEK_DAY_SAT => 'Saturday',
45            self::WEEK_DAY_SUN => 'Sunday',
46        ];
47    }
48
49    public static function getWeekDay(string $val): string
50    {
51        $ar = self::weekDays();
52
53        return $ar[$val] ?? $val;
54    }
55
56    public static function hoursList(): array
57    {
58        $list = [];
59        for ($i = 0; $i < 24; $i++) {
60            $A = 'AM';
61            $n = $i;
62            if ($i >= 12) {
63                $A = 'PM';
64                $n = $i - 12;
65            }
66
67            $n = $n < 10 ? '0' . $n : $n;
68            $_A = ($i === 12 ? 'AM' : $A);
69            $list[$i . '.00'] = $n . '.00 ' . ($i === 0 ? 'PM' : $_A);
70            $list[$i . '.30'] = $n . '.30 ' . $A;
71        }
72        return $list;
73    }
74}
75$this->registerJsFile('/js/restaurant-reserve.js', ['depends' => [JqueryAsset::class]]);
76$this->registerJs('restaurantReserve.init()');
77
78<a class="btn btn-fourth <?= $restaurantReservationForm->getErrors('date') ? 'btn-error' : '' ?>" id="reservation-date" data-date="<?= $restaurantReservationForm->getDate()
79                   ? $restaurantReservationForm->getDate()->format('m/d/Y') : '' ?>>">
80  <span class="icon br-calender"></span> <span class="js-value">
81                    <?= $restaurantReservationForm->date
82                        ? (new DateTime($restaurantReservationForm->date))->format('d M') : '-- ---' ?>
83                </span>
84</a>
85<a class="btn btn-fourth <?= $restaurantReservationForm->getErrors('time') ? 'btn-error' : '' ?>" id="reservation-time" role="button" data-bs-toggle="dropdown" aria-expanded="false">
86  <span class="icon br-clock"></span> <span class="js-value">
87                    <?= $restaurantReservationForm->time
88                        ? WorkHours::hoursList()[$restaurantReservationForm->time] : '-- : --' ?>
89                </span>
90</a>
91<ul class="dropdown-menu dropdown-menu-height-fixed" aria-labelledby="reservation-time">
92  <?php foreach (WorkHours::hoursList() as $k => $v) { ?>
93    <li>
94      <a class="dropdown-item <?= $restaurantReservationForm->time === $k ? 'active' : ''
95                        ?>" href="#" data-value="<?= $k ?>">
96        <?= $v ?>
97      </a>
98    </li>
99    <?php } ?>
100</ul>
101

Here is the script

1<?php
2
3namespace common\models;
4
5use yii\behaviors\TimestampBehavior;
6use yii\db\ActiveRecord;
7use yii\db\Expression;
8
9class WorkHours extends _source_WorkHours
10{
11    public const WEEK_DAY_MON = 'Mon';
12    public const WEEK_DAY_TUE = 'Tue';
13    public const WEEK_DAY_WED = 'Wed';
14    public const WEEK_DAY_THU = 'Thu';
15    public const WEEK_DAY_FRI = 'Fri';
16    public const WEEK_DAY_SAT = 'Sat';
17    public const WEEK_DAY_SUN = 'Sun';
18
19
20    /**
21     * {@inheritdoc}
22     */
23    public function behaviors(): array
24    {
25        return [
26            'timestamp' => [
27                'class'      => TimestampBehavior::class,
28                'attributes' => [
29                    ActiveRecord::EVENT_BEFORE_INSERT => ['created_at'],
30                ],
31                'value'      => new Expression('NOW()'),
32            ],
33        ];
34    }
35
36    public static function weekDays(): array
37    {
38        return [
39            self::WEEK_DAY_MON => 'Monday',
40            self::WEEK_DAY_TUE => 'Tuesday',
41            self::WEEK_DAY_WED => 'Wednesday',
42            self::WEEK_DAY_THU => 'Thursday',
43            self::WEEK_DAY_FRI => 'Friday',
44            self::WEEK_DAY_SAT => 'Saturday',
45            self::WEEK_DAY_SUN => 'Sunday',
46        ];
47    }
48
49    public static function getWeekDay(string $val): string
50    {
51        $ar = self::weekDays();
52
53        return $ar[$val] ?? $val;
54    }
55
56    public static function hoursList(): array
57    {
58        $list = [];
59        for ($i = 0; $i < 24; $i++) {
60            $A = 'AM';
61            $n = $i;
62            if ($i >= 12) {
63                $A = 'PM';
64                $n = $i - 12;
65            }
66
67            $n = $n < 10 ? '0' . $n : $n;
68            $_A = ($i === 12 ? 'AM' : $A);
69            $list[$i . '.00'] = $n . '.00 ' . ($i === 0 ? 'PM' : $_A);
70            $list[$i . '.30'] = $n . '.30 ' . $A;
71        }
72        return $list;
73    }
74}
75$this->registerJsFile('/js/restaurant-reserve.js', ['depends' => [JqueryAsset::class]]);
76$this->registerJs('restaurantReserve.init()');
77
78<a class="btn btn-fourth <?= $restaurantReservationForm->getErrors('date') ? 'btn-error' : '' ?>" id="reservation-date" data-date="<?= $restaurantReservationForm->getDate()
79                   ? $restaurantReservationForm->getDate()->format('m/d/Y') : '' ?>>">
80  <span class="icon br-calender"></span> <span class="js-value">
81                    <?= $restaurantReservationForm->date
82                        ? (new DateTime($restaurantReservationForm->date))->format('d M') : '-- ---' ?>
83                </span>
84</a>
85<a class="btn btn-fourth <?= $restaurantReservationForm->getErrors('time') ? 'btn-error' : '' ?>" id="reservation-time" role="button" data-bs-toggle="dropdown" aria-expanded="false">
86  <span class="icon br-clock"></span> <span class="js-value">
87                    <?= $restaurantReservationForm->time
88                        ? WorkHours::hoursList()[$restaurantReservationForm->time] : '-- : --' ?>
89                </span>
90</a>
91<ul class="dropdown-menu dropdown-menu-height-fixed" aria-labelledby="reservation-time">
92  <?php foreach (WorkHours::hoursList() as $k => $v) { ?>
93    <li>
94      <a class="dropdown-item <?= $restaurantReservationForm->time === $k ? 'active' : ''
95                        ?>" href="#" data-value="<?= $k ?>">
96        <?= $v ?>
97      </a>
98    </li>
99    <?php } ?>
100</ul>
101let restaurantReserve = {
102    init: function () {
103        let _self = this;
104
105        $('#reservation-date').datepicker({startDate: '+0d'}).on('changeDate', function (e) {
106            const arDate = e.date.toString().split(' ');
107            let input = $('[name="RestaurantReservationForm[date]"]');
108            input.val(arDate[3] + '-' + (e.date.getMonth() + 1) + '-' + arDate[2]);
109            _self.unSetError(input);
110            $('#reservation-date .js-value').text(arDate[2] + ' ' + arDate[1]);
111        });
112
113        $('[aria-labelledby="reservation-time"] li a').click(function () {
114            $(this).closest('ul').find('a').removeClass('active');
115            $(this).addClass('active');
116            let input = $('[name="RestaurantReservationForm[time]"]');
117            input.val($(this).data('value'));
118            _self.unSetError(input);
119            $('#reservation-time .js-value').text($(this).text());
120        });
121
122        $('[aria-labelledby="reservation-person"] li a').click(function () {
123            $(this).closest('ul').find('a').removeClass('active');
124            $(this).addClass('active');
125            let input = $('[name="RestaurantReservationForm[personCount]"]');
126            input.val($(this).data('value'));
127            _self.unSetError(input);
128            $('#reservation-person .js-value').text($(this).data('value'));
129        });
130    },
131    setError: function (ob) {
132        $('#' + ob.data('btnId')).addClass('btn-error');
133    },
134    unSetError: function (ob) {
135        $('#' + ob.data('btnId')).removeClass('btn-error');
136    }
137}
138

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

1<?php
2
3namespace common\models;
4
5use yii\behaviors\TimestampBehavior;
6use yii\db\ActiveRecord;
7use yii\db\Expression;
8
9class WorkHours extends _source_WorkHours
10{
11    public const WEEK_DAY_MON = 'Mon';
12    public const WEEK_DAY_TUE = 'Tue';
13    public const WEEK_DAY_WED = 'Wed';
14    public const WEEK_DAY_THU = 'Thu';
15    public const WEEK_DAY_FRI = 'Fri';
16    public const WEEK_DAY_SAT = 'Sat';
17    public const WEEK_DAY_SUN = 'Sun';
18
19
20    /**
21     * {@inheritdoc}
22     */
23    public function behaviors(): array
24    {
25        return [
26            'timestamp' => [
27                'class'      => TimestampBehavior::class,
28                'attributes' => [
29                    ActiveRecord::EVENT_BEFORE_INSERT => ['created_at'],
30                ],
31                'value'      => new Expression('NOW()'),
32            ],
33        ];
34    }
35
36    public static function weekDays(): array
37    {
38        return [
39            self::WEEK_DAY_MON => 'Monday',
40            self::WEEK_DAY_TUE => 'Tuesday',
41            self::WEEK_DAY_WED => 'Wednesday',
42            self::WEEK_DAY_THU => 'Thursday',
43            self::WEEK_DAY_FRI => 'Friday',
44            self::WEEK_DAY_SAT => 'Saturday',
45            self::WEEK_DAY_SUN => 'Sunday',
46        ];
47    }
48
49    public static function getWeekDay(string $val): string
50    {
51        $ar = self::weekDays();
52
53        return $ar[$val] ?? $val;
54    }
55
56    public static function hoursList(): array
57    {
58        $list = [];
59        for ($i = 0; $i < 24; $i++) {
60            $A = 'AM';
61            $n = $i;
62            if ($i >= 12) {
63                $A = 'PM';
64                $n = $i - 12;
65            }
66
67            $n = $n < 10 ? '0' . $n : $n;
68            $_A = ($i === 12 ? 'AM' : $A);
69            $list[$i . '.00'] = $n . '.00 ' . ($i === 0 ? 'PM' : $_A);
70            $list[$i . '.30'] = $n . '.30 ' . $A;
71        }
72        return $list;
73    }
74}
75$this->registerJsFile('/js/restaurant-reserve.js', ['depends' => [JqueryAsset::class]]);
76$this->registerJs('restaurantReserve.init()');
77
78<a class="btn btn-fourth <?= $restaurantReservationForm->getErrors('date') ? 'btn-error' : '' ?>" id="reservation-date" data-date="<?= $restaurantReservationForm->getDate()
79                   ? $restaurantReservationForm->getDate()->format('m/d/Y') : '' ?>>">
80  <span class="icon br-calender"></span> <span class="js-value">
81                    <?= $restaurantReservationForm->date
82                        ? (new DateTime($restaurantReservationForm->date))->format('d M') : '-- ---' ?>
83                </span>
84</a>
85<a class="btn btn-fourth <?= $restaurantReservationForm->getErrors('time') ? 'btn-error' : '' ?>" id="reservation-time" role="button" data-bs-toggle="dropdown" aria-expanded="false">
86  <span class="icon br-clock"></span> <span class="js-value">
87                    <?= $restaurantReservationForm->time
88                        ? WorkHours::hoursList()[$restaurantReservationForm->time] : '-- : --' ?>
89                </span>
90</a>
91<ul class="dropdown-menu dropdown-menu-height-fixed" aria-labelledby="reservation-time">
92  <?php foreach (WorkHours::hoursList() as $k => $v) { ?>
93    <li>
94      <a class="dropdown-item <?= $restaurantReservationForm->time === $k ? 'active' : ''
95                        ?>" href="#" data-value="<?= $k ?>">
96        <?= $v ?>
97      </a>
98    </li>
99    <?php } ?>
100</ul>
101let restaurantReserve = {
102    init: function () {
103        let _self = this;
104
105        $('#reservation-date').datepicker({startDate: '+0d'}).on('changeDate', function (e) {
106            const arDate = e.date.toString().split(' ');
107            let input = $('[name="RestaurantReservationForm[date]"]');
108            input.val(arDate[3] + '-' + (e.date.getMonth() + 1) + '-' + arDate[2]);
109            _self.unSetError(input);
110            $('#reservation-date .js-value').text(arDate[2] + ' ' + arDate[1]);
111        });
112
113        $('[aria-labelledby="reservation-time"] li a').click(function () {
114            $(this).closest('ul').find('a').removeClass('active');
115            $(this).addClass('active');
116            let input = $('[name="RestaurantReservationForm[time]"]');
117            input.val($(this).data('value'));
118            _self.unSetError(input);
119            $('#reservation-time .js-value').text($(this).text());
120        });
121
122        $('[aria-labelledby="reservation-person"] li a').click(function () {
123            $(this).closest('ul').find('a').removeClass('active');
124            $(this).addClass('active');
125            let input = $('[name="RestaurantReservationForm[personCount]"]');
126            input.val($(this).data('value'));
127            _self.unSetError(input);
128            $('#reservation-person .js-value').text($(this).data('value'));
129        });
130    },
131    setError: function (ob) {
132        $('#' + ob.data('btnId')).addClass('btn-error');
133    },
134    unSetError: function (ob) {
135        $('#' + ob.data('btnId')).removeClass('btn-error');
136    }
137}
138$this->registerJs('restaurantReserve.init('. Json::encode($restaurant->workHours) .')');
139

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

1<?php
2
3namespace common\models;
4
5use yii\behaviors\TimestampBehavior;
6use yii\db\ActiveRecord;
7use yii\db\Expression;
8
9class WorkHours extends _source_WorkHours
10{
11    public const WEEK_DAY_MON = 'Mon';
12    public const WEEK_DAY_TUE = 'Tue';
13    public const WEEK_DAY_WED = 'Wed';
14    public const WEEK_DAY_THU = 'Thu';
15    public const WEEK_DAY_FRI = 'Fri';
16    public const WEEK_DAY_SAT = 'Sat';
17    public const WEEK_DAY_SUN = 'Sun';
18
19
20    /**
21     * {@inheritdoc}
22     */
23    public function behaviors(): array
24    {
25        return [
26            'timestamp' => [
27                'class'      => TimestampBehavior::class,
28                'attributes' => [
29                    ActiveRecord::EVENT_BEFORE_INSERT => ['created_at'],
30                ],
31                'value'      => new Expression('NOW()'),
32            ],
33        ];
34    }
35
36    public static function weekDays(): array
37    {
38        return [
39            self::WEEK_DAY_MON => 'Monday',
40            self::WEEK_DAY_TUE => 'Tuesday',
41            self::WEEK_DAY_WED => 'Wednesday',
42            self::WEEK_DAY_THU => 'Thursday',
43            self::WEEK_DAY_FRI => 'Friday',
44            self::WEEK_DAY_SAT => 'Saturday',
45            self::WEEK_DAY_SUN => 'Sunday',
46        ];
47    }
48
49    public static function getWeekDay(string $val): string
50    {
51        $ar = self::weekDays();
52
53        return $ar[$val] ?? $val;
54    }
55
56    public static function hoursList(): array
57    {
58        $list = [];
59        for ($i = 0; $i < 24; $i++) {
60            $A = 'AM';
61            $n = $i;
62            if ($i >= 12) {
63                $A = 'PM';
64                $n = $i - 12;
65            }
66
67            $n = $n < 10 ? '0' . $n : $n;
68            $_A = ($i === 12 ? 'AM' : $A);
69            $list[$i . '.00'] = $n . '.00 ' . ($i === 0 ? 'PM' : $_A);
70            $list[$i . '.30'] = $n . '.30 ' . $A;
71        }
72        return $list;
73    }
74}
75$this->registerJsFile('/js/restaurant-reserve.js', ['depends' => [JqueryAsset::class]]);
76$this->registerJs('restaurantReserve.init()');
77
78<a class="btn btn-fourth <?= $restaurantReservationForm->getErrors('date') ? 'btn-error' : '' ?>" id="reservation-date" data-date="<?= $restaurantReservationForm->getDate()
79                   ? $restaurantReservationForm->getDate()->format('m/d/Y') : '' ?>>">
80  <span class="icon br-calender"></span> <span class="js-value">
81                    <?= $restaurantReservationForm->date
82                        ? (new DateTime($restaurantReservationForm->date))->format('d M') : '-- ---' ?>
83                </span>
84</a>
85<a class="btn btn-fourth <?= $restaurantReservationForm->getErrors('time') ? 'btn-error' : '' ?>" id="reservation-time" role="button" data-bs-toggle="dropdown" aria-expanded="false">
86  <span class="icon br-clock"></span> <span class="js-value">
87                    <?= $restaurantReservationForm->time
88                        ? WorkHours::hoursList()[$restaurantReservationForm->time] : '-- : --' ?>
89                </span>
90</a>
91<ul class="dropdown-menu dropdown-menu-height-fixed" aria-labelledby="reservation-time">
92  <?php foreach (WorkHours::hoursList() as $k => $v) { ?>
93    <li>
94      <a class="dropdown-item <?= $restaurantReservationForm->time === $k ? 'active' : ''
95                        ?>" href="#" data-value="<?= $k ?>">
96        <?= $v ?>
97      </a>
98    </li>
99    <?php } ?>
100</ul>
101let restaurantReserve = {
102    init: function () {
103        let _self = this;
104
105        $('#reservation-date').datepicker({startDate: '+0d'}).on('changeDate', function (e) {
106            const arDate = e.date.toString().split(' ');
107            let input = $('[name="RestaurantReservationForm[date]"]');
108            input.val(arDate[3] + '-' + (e.date.getMonth() + 1) + '-' + arDate[2]);
109            _self.unSetError(input);
110            $('#reservation-date .js-value').text(arDate[2] + ' ' + arDate[1]);
111        });
112
113        $('[aria-labelledby="reservation-time"] li a').click(function () {
114            $(this).closest('ul').find('a').removeClass('active');
115            $(this).addClass('active');
116            let input = $('[name="RestaurantReservationForm[time]"]');
117            input.val($(this).data('value'));
118            _self.unSetError(input);
119            $('#reservation-time .js-value').text($(this).text());
120        });
121
122        $('[aria-labelledby="reservation-person"] li a').click(function () {
123            $(this).closest('ul').find('a').removeClass('active');
124            $(this).addClass('active');
125            let input = $('[name="RestaurantReservationForm[personCount]"]');
126            input.val($(this).data('value'));
127            _self.unSetError(input);
128            $('#reservation-person .js-value').text($(this).data('value'));
129        });
130    },
131    setError: function (ob) {
132        $('#' + ob.data('btnId')).addClass('btn-error');
133    },
134    unSetError: function (ob) {
135        $('#' + ob.data('btnId')).removeClass('btn-error');
136    }
137}
138$this->registerJs('restaurantReserve.init('. Json::encode($restaurant->workHours) .')');
139restaurantDate: function (e) {
140        ...
141    }
142

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

Here is a snippet of how everything should look like, now you can choose any time here, but i need to have a time interval for each day that will be transmitted from json

1<?php
2
3namespace common\models;
4
5use yii\behaviors\TimestampBehavior;
6use yii\db\ActiveRecord;
7use yii\db\Expression;
8
9class WorkHours extends _source_WorkHours
10{
11    public const WEEK_DAY_MON = 'Mon';
12    public const WEEK_DAY_TUE = 'Tue';
13    public const WEEK_DAY_WED = 'Wed';
14    public const WEEK_DAY_THU = 'Thu';
15    public const WEEK_DAY_FRI = 'Fri';
16    public const WEEK_DAY_SAT = 'Sat';
17    public const WEEK_DAY_SUN = 'Sun';
18
19
20    /**
21     * {@inheritdoc}
22     */
23    public function behaviors(): array
24    {
25        return [
26            'timestamp' => [
27                'class'      => TimestampBehavior::class,
28                'attributes' => [
29                    ActiveRecord::EVENT_BEFORE_INSERT => ['created_at'],
30                ],
31                'value'      => new Expression('NOW()'),
32            ],
33        ];
34    }
35
36    public static function weekDays(): array
37    {
38        return [
39            self::WEEK_DAY_MON => 'Monday',
40            self::WEEK_DAY_TUE => 'Tuesday',
41            self::WEEK_DAY_WED => 'Wednesday',
42            self::WEEK_DAY_THU => 'Thursday',
43            self::WEEK_DAY_FRI => 'Friday',
44            self::WEEK_DAY_SAT => 'Saturday',
45            self::WEEK_DAY_SUN => 'Sunday',
46        ];
47    }
48
49    public static function getWeekDay(string $val): string
50    {
51        $ar = self::weekDays();
52
53        return $ar[$val] ?? $val;
54    }
55
56    public static function hoursList(): array
57    {
58        $list = [];
59        for ($i = 0; $i < 24; $i++) {
60            $A = 'AM';
61            $n = $i;
62            if ($i >= 12) {
63                $A = 'PM';
64                $n = $i - 12;
65            }
66
67            $n = $n < 10 ? '0' . $n : $n;
68            $_A = ($i === 12 ? 'AM' : $A);
69            $list[$i . '.00'] = $n . '.00 ' . ($i === 0 ? 'PM' : $_A);
70            $list[$i . '.30'] = $n . '.30 ' . $A;
71        }
72        return $list;
73    }
74}
75$this->registerJsFile('/js/restaurant-reserve.js', ['depends' => [JqueryAsset::class]]);
76$this->registerJs('restaurantReserve.init()');
77
78<a class="btn btn-fourth <?= $restaurantReservationForm->getErrors('date') ? 'btn-error' : '' ?>" id="reservation-date" data-date="<?= $restaurantReservationForm->getDate()
79                   ? $restaurantReservationForm->getDate()->format('m/d/Y') : '' ?>>">
80  <span class="icon br-calender"></span> <span class="js-value">
81                    <?= $restaurantReservationForm->date
82                        ? (new DateTime($restaurantReservationForm->date))->format('d M') : '-- ---' ?>
83                </span>
84</a>
85<a class="btn btn-fourth <?= $restaurantReservationForm->getErrors('time') ? 'btn-error' : '' ?>" id="reservation-time" role="button" data-bs-toggle="dropdown" aria-expanded="false">
86  <span class="icon br-clock"></span> <span class="js-value">
87                    <?= $restaurantReservationForm->time
88                        ? WorkHours::hoursList()[$restaurantReservationForm->time] : '-- : --' ?>
89                </span>
90</a>
91<ul class="dropdown-menu dropdown-menu-height-fixed" aria-labelledby="reservation-time">
92  <?php foreach (WorkHours::hoursList() as $k => $v) { ?>
93    <li>
94      <a class="dropdown-item <?= $restaurantReservationForm->time === $k ? 'active' : ''
95                        ?>" href="#" data-value="<?= $k ?>">
96        <?= $v ?>
97      </a>
98    </li>
99    <?php } ?>
100</ul>
101let restaurantReserve = {
102    init: function () {
103        let _self = this;
104
105        $('#reservation-date').datepicker({startDate: '+0d'}).on('changeDate', function (e) {
106            const arDate = e.date.toString().split(' ');
107            let input = $('[name="RestaurantReservationForm[date]"]');
108            input.val(arDate[3] + '-' + (e.date.getMonth() + 1) + '-' + arDate[2]);
109            _self.unSetError(input);
110            $('#reservation-date .js-value').text(arDate[2] + ' ' + arDate[1]);
111        });
112
113        $('[aria-labelledby="reservation-time"] li a').click(function () {
114            $(this).closest('ul').find('a').removeClass('active');
115            $(this).addClass('active');
116            let input = $('[name="RestaurantReservationForm[time]"]');
117            input.val($(this).data('value'));
118            _self.unSetError(input);
119            $('#reservation-time .js-value').text($(this).text());
120        });
121
122        $('[aria-labelledby="reservation-person"] li a').click(function () {
123            $(this).closest('ul').find('a').removeClass('active');
124            $(this).addClass('active');
125            let input = $('[name="RestaurantReservationForm[personCount]"]');
126            input.val($(this).data('value'));
127            _self.unSetError(input);
128            $('#reservation-person .js-value').text($(this).data('value'));
129        });
130    },
131    setError: function (ob) {
132        $('#' + ob.data('btnId')).addClass('btn-error');
133    },
134    unSetError: function (ob) {
135        $('#' + ob.data('btnId')).removeClass('btn-error');
136    }
137}
138$this->registerJs('restaurantReserve.init('. Json::encode($restaurant->workHours) .')');
139restaurantDate: function (e) {
140        ...
141    }
142let restaurantReserve = {
143    init: function () {
144        let _self = this;
145        
146        $('#reservation-date').datepicker({startDate: '+0d'}).on('changeDate', function (e) {
147            const arDate = e.date.toString().split(' ');
148            let input = $('[name="RestaurantReservationForm[date]"]');
149            input.val(arDate[3] + '-' + (e.date.getMonth() + 1) + '-' + arDate[2]);
150            _self.unSetError(input);
151            $('#reservation-date .js-value').text(arDate[2] + ' ' + arDate[1]);
152        });
153
154        $('[aria-labelledby="reservation-time"] li a').click(function () {
155            $(this).closest('ul').find('a').removeClass('active');
156            $(this).addClass('active');
157            let input = $('[name="RestaurantReservationForm[time]"]');
158            input.val($(this).data('value'));
159            _self.unSetError(input);
160            $('#reservation-time .js-value').text($(this).text());
161        });
162    },
163    setError: function (ob) {
164        $('#' + ob.data('btnId')).addClass('btn-error');
165    },
166    unSetError: function (ob) {
167        $('#' + ob.data('btnId')).removeClass('btn-error');
168    }
169}
170
171restaurantReserve.init();
1<?php
2
3namespace common\models;
4
5use yii\behaviors\TimestampBehavior;
6use yii\db\ActiveRecord;
7use yii\db\Expression;
8
9class WorkHours extends _source_WorkHours
10{
11    public const WEEK_DAY_MON = 'Mon';
12    public const WEEK_DAY_TUE = 'Tue';
13    public const WEEK_DAY_WED = 'Wed';
14    public const WEEK_DAY_THU = 'Thu';
15    public const WEEK_DAY_FRI = 'Fri';
16    public const WEEK_DAY_SAT = 'Sat';
17    public const WEEK_DAY_SUN = 'Sun';
18
19
20    /**
21     * {@inheritdoc}
22     */
23    public function behaviors(): array
24    {
25        return [
26            'timestamp' => [
27                'class'      => TimestampBehavior::class,
28                'attributes' => [
29                    ActiveRecord::EVENT_BEFORE_INSERT => ['created_at'],
30                ],
31                'value'      => new Expression('NOW()'),
32            ],
33        ];
34    }
35
36    public static function weekDays(): array
37    {
38        return [
39            self::WEEK_DAY_MON => 'Monday',
40            self::WEEK_DAY_TUE => 'Tuesday',
41            self::WEEK_DAY_WED => 'Wednesday',
42            self::WEEK_DAY_THU => 'Thursday',
43            self::WEEK_DAY_FRI => 'Friday',
44            self::WEEK_DAY_SAT => 'Saturday',
45            self::WEEK_DAY_SUN => 'Sunday',
46        ];
47    }
48
49    public static function getWeekDay(string $val): string
50    {
51        $ar = self::weekDays();
52
53        return $ar[$val] ?? $val;
54    }
55
56    public static function hoursList(): array
57    {
58        $list = [];
59        for ($i = 0; $i < 24; $i++) {
60            $A = 'AM';
61            $n = $i;
62            if ($i >= 12) {
63                $A = 'PM';
64                $n = $i - 12;
65            }
66
67            $n = $n < 10 ? '0' . $n : $n;
68            $_A = ($i === 12 ? 'AM' : $A);
69            $list[$i . '.00'] = $n . '.00 ' . ($i === 0 ? 'PM' : $_A);
70            $list[$i . '.30'] = $n . '.30 ' . $A;
71        }
72        return $list;
73    }
74}
75$this->registerJsFile('/js/restaurant-reserve.js', ['depends' => [JqueryAsset::class]]);
76$this->registerJs('restaurantReserve.init()');
77
78<a class="btn btn-fourth <?= $restaurantReservationForm->getErrors('date') ? 'btn-error' : '' ?>" id="reservation-date" data-date="<?= $restaurantReservationForm->getDate()
79                   ? $restaurantReservationForm->getDate()->format('m/d/Y') : '' ?>>">
80  <span class="icon br-calender"></span> <span class="js-value">
81                    <?= $restaurantReservationForm->date
82                        ? (new DateTime($restaurantReservationForm->date))->format('d M') : '-- ---' ?>
83                </span>
84</a>
85<a class="btn btn-fourth <?= $restaurantReservationForm->getErrors('time') ? 'btn-error' : '' ?>" id="reservation-time" role="button" data-bs-toggle="dropdown" aria-expanded="false">
86  <span class="icon br-clock"></span> <span class="js-value">
87                    <?= $restaurantReservationForm->time
88                        ? WorkHours::hoursList()[$restaurantReservationForm->time] : '-- : --' ?>
89                </span>
90</a>
91<ul class="dropdown-menu dropdown-menu-height-fixed" aria-labelledby="reservation-time">
92  <?php foreach (WorkHours::hoursList() as $k => $v) { ?>
93    <li>
94      <a class="dropdown-item <?= $restaurantReservationForm->time === $k ? 'active' : ''
95                        ?>" href="#" data-value="<?= $k ?>">
96        <?= $v ?>
97      </a>
98    </li>
99    <?php } ?>
100</ul>
101let restaurantReserve = {
102    init: function () {
103        let _self = this;
104
105        $('#reservation-date').datepicker({startDate: '+0d'}).on('changeDate', function (e) {
106            const arDate = e.date.toString().split(' ');
107            let input = $('[name="RestaurantReservationForm[date]"]');
108            input.val(arDate[3] + '-' + (e.date.getMonth() + 1) + '-' + arDate[2]);
109            _self.unSetError(input);
110            $('#reservation-date .js-value').text(arDate[2] + ' ' + arDate[1]);
111        });
112
113        $('[aria-labelledby="reservation-time"] li a').click(function () {
114            $(this).closest('ul').find('a').removeClass('active');
115            $(this).addClass('active');
116            let input = $('[name="RestaurantReservationForm[time]"]');
117            input.val($(this).data('value'));
118            _self.unSetError(input);
119            $('#reservation-time .js-value').text($(this).text());
120        });
121
122        $('[aria-labelledby="reservation-person"] li a').click(function () {
123            $(this).closest('ul').find('a').removeClass('active');
124            $(this).addClass('active');
125            let input = $('[name="RestaurantReservationForm[personCount]"]');
126            input.val($(this).data('value'));
127            _self.unSetError(input);
128            $('#reservation-person .js-value').text($(this).data('value'));
129        });
130    },
131    setError: function (ob) {
132        $('#' + ob.data('btnId')).addClass('btn-error');
133    },
134    unSetError: function (ob) {
135        $('#' + ob.data('btnId')).removeClass('btn-error');
136    }
137}
138$this->registerJs('restaurantReserve.init('. Json::encode($restaurant->workHours) .')');
139restaurantDate: function (e) {
140        ...
141    }
142let restaurantReserve = {
143    init: function () {
144        let _self = this;
145        
146        $('#reservation-date').datepicker({startDate: '+0d'}).on('changeDate', function (e) {
147            const arDate = e.date.toString().split(' ');
148            let input = $('[name="RestaurantReservationForm[date]"]');
149            input.val(arDate[3] + '-' + (e.date.getMonth() + 1) + '-' + arDate[2]);
150            _self.unSetError(input);
151            $('#reservation-date .js-value').text(arDate[2] + ' ' + arDate[1]);
152        });
153
154        $('[aria-labelledby="reservation-time"] li a').click(function () {
155            $(this).closest('ul').find('a').removeClass('active');
156            $(this).addClass('active');
157            let input = $('[name="RestaurantReservationForm[time]"]');
158            input.val($(this).data('value'));
159            _self.unSetError(input);
160            $('#reservation-time .js-value').text($(this).text());
161        });
162    },
163    setError: function (ob) {
164        $('#' + ob.data('btnId')).addClass('btn-error');
165    },
166    unSetError: function (ob) {
167        $('#' + ob.data('btnId')).removeClass('btn-error');
168    }
169}
170
171restaurantReserve.init();.btn {
172    border: none;
173    border-radius: 8px;
174    height: 40px;
175    padding: 10px 15px;
176    font-weight: 800;
177    font-size: 14px;
178    margin-right: 10px;
179    cursor: pointer;
180}
181
182.btn-fourth {
183    text-decoration: none;
184    background: #e3e5e8;
185    color: #747b8b;
186}
187
188ul.with-out > li:before, .dropdown-menu li:before, ul.whithout > li:before {display:none;}
189
190.dropdown-menu li {padding:0;}
191
192.dropdown-menu-height-fixed {max-height:200px;overflow-y:auto;}
193
194.dropdown-item.active, .dropdown-item:active {background:red;}
195
196.block-shadow {box-shadow:0 2px 8px 0 rgba(32,35,44,0.05);}
197.block-white {background:#fff;border-radius:8px;padding:20px;}
1<?php
2
3namespace common\models;
4
5use yii\behaviors\TimestampBehavior;
6use yii\db\ActiveRecord;
7use yii\db\Expression;
8
9class WorkHours extends _source_WorkHours
10{
11    public const WEEK_DAY_MON = 'Mon';
12    public const WEEK_DAY_TUE = 'Tue';
13    public const WEEK_DAY_WED = 'Wed';
14    public const WEEK_DAY_THU = 'Thu';
15    public const WEEK_DAY_FRI = 'Fri';
16    public const WEEK_DAY_SAT = 'Sat';
17    public const WEEK_DAY_SUN = 'Sun';
18
19
20    /**
21     * {@inheritdoc}
22     */
23    public function behaviors(): array
24    {
25        return [
26            'timestamp' => [
27                'class'      => TimestampBehavior::class,
28                'attributes' => [
29                    ActiveRecord::EVENT_BEFORE_INSERT => ['created_at'],
30                ],
31                'value'      => new Expression('NOW()'),
32            ],
33        ];
34    }
35
36    public static function weekDays(): array
37    {
38        return [
39            self::WEEK_DAY_MON => 'Monday',
40            self::WEEK_DAY_TUE => 'Tuesday',
41            self::WEEK_DAY_WED => 'Wednesday',
42            self::WEEK_DAY_THU => 'Thursday',
43            self::WEEK_DAY_FRI => 'Friday',
44            self::WEEK_DAY_SAT => 'Saturday',
45            self::WEEK_DAY_SUN => 'Sunday',
46        ];
47    }
48
49    public static function getWeekDay(string $val): string
50    {
51        $ar = self::weekDays();
52
53        return $ar[$val] ?? $val;
54    }
55
56    public static function hoursList(): array
57    {
58        $list = [];
59        for ($i = 0; $i < 24; $i++) {
60            $A = 'AM';
61            $n = $i;
62            if ($i >= 12) {
63                $A = 'PM';
64                $n = $i - 12;
65            }
66
67            $n = $n < 10 ? '0' . $n : $n;
68            $_A = ($i === 12 ? 'AM' : $A);
69            $list[$i . '.00'] = $n . '.00 ' . ($i === 0 ? 'PM' : $_A);
70            $list[$i . '.30'] = $n . '.30 ' . $A;
71        }
72        return $list;
73    }
74}
75$this->registerJsFile('/js/restaurant-reserve.js', ['depends' => [JqueryAsset::class]]);
76$this->registerJs('restaurantReserve.init()');
77
78<a class="btn btn-fourth <?= $restaurantReservationForm->getErrors('date') ? 'btn-error' : '' ?>" id="reservation-date" data-date="<?= $restaurantReservationForm->getDate()
79                   ? $restaurantReservationForm->getDate()->format('m/d/Y') : '' ?>>">
80  <span class="icon br-calender"></span> <span class="js-value">
81                    <?= $restaurantReservationForm->date
82                        ? (new DateTime($restaurantReservationForm->date))->format('d M') : '-- ---' ?>
83                </span>
84</a>
85<a class="btn btn-fourth <?= $restaurantReservationForm->getErrors('time') ? 'btn-error' : '' ?>" id="reservation-time" role="button" data-bs-toggle="dropdown" aria-expanded="false">
86  <span class="icon br-clock"></span> <span class="js-value">
87                    <?= $restaurantReservationForm->time
88                        ? WorkHours::hoursList()[$restaurantReservationForm->time] : '-- : --' ?>
89                </span>
90</a>
91<ul class="dropdown-menu dropdown-menu-height-fixed" aria-labelledby="reservation-time">
92  <?php foreach (WorkHours::hoursList() as $k => $v) { ?>
93    <li>
94      <a class="dropdown-item <?= $restaurantReservationForm->time === $k ? 'active' : ''
95                        ?>" href="#" data-value="<?= $k ?>">
96        <?= $v ?>
97      </a>
98    </li>
99    <?php } ?>
100</ul>
101let restaurantReserve = {
102    init: function () {
103        let _self = this;
104
105        $('#reservation-date').datepicker({startDate: '+0d'}).on('changeDate', function (e) {
106            const arDate = e.date.toString().split(' ');
107            let input = $('[name="RestaurantReservationForm[date]"]');
108            input.val(arDate[3] + '-' + (e.date.getMonth() + 1) + '-' + arDate[2]);
109            _self.unSetError(input);
110            $('#reservation-date .js-value').text(arDate[2] + ' ' + arDate[1]);
111        });
112
113        $('[aria-labelledby="reservation-time"] li a').click(function () {
114            $(this).closest('ul').find('a').removeClass('active');
115            $(this).addClass('active');
116            let input = $('[name="RestaurantReservationForm[time]"]');
117            input.val($(this).data('value'));
118            _self.unSetError(input);
119            $('#reservation-time .js-value').text($(this).text());
120        });
121
122        $('[aria-labelledby="reservation-person"] li a').click(function () {
123            $(this).closest('ul').find('a').removeClass('active');
124            $(this).addClass('active');
125            let input = $('[name="RestaurantReservationForm[personCount]"]');
126            input.val($(this).data('value'));
127            _self.unSetError(input);
128            $('#reservation-person .js-value').text($(this).data('value'));
129        });
130    },
131    setError: function (ob) {
132        $('#' + ob.data('btnId')).addClass('btn-error');
133    },
134    unSetError: function (ob) {
135        $('#' + ob.data('btnId')).removeClass('btn-error');
136    }
137}
138$this->registerJs('restaurantReserve.init('. Json::encode($restaurant->workHours) .')');
139restaurantDate: function (e) {
140        ...
141    }
142let restaurantReserve = {
143    init: function () {
144        let _self = this;
145        
146        $('#reservation-date').datepicker({startDate: '+0d'}).on('changeDate', function (e) {
147            const arDate = e.date.toString().split(' ');
148            let input = $('[name="RestaurantReservationForm[date]"]');
149            input.val(arDate[3] + '-' + (e.date.getMonth() + 1) + '-' + arDate[2]);
150            _self.unSetError(input);
151            $('#reservation-date .js-value').text(arDate[2] + ' ' + arDate[1]);
152        });
153
154        $('[aria-labelledby="reservation-time"] li a').click(function () {
155            $(this).closest('ul').find('a').removeClass('active');
156            $(this).addClass('active');
157            let input = $('[name="RestaurantReservationForm[time]"]');
158            input.val($(this).data('value'));
159            _self.unSetError(input);
160            $('#reservation-time .js-value').text($(this).text());
161        });
162    },
163    setError: function (ob) {
164        $('#' + ob.data('btnId')).addClass('btn-error');
165    },
166    unSetError: function (ob) {
167        $('#' + ob.data('btnId')).removeClass('btn-error');
168    }
169}
170
171restaurantReserve.init();.btn {
172    border: none;
173    border-radius: 8px;
174    height: 40px;
175    padding: 10px 15px;
176    font-weight: 800;
177    font-size: 14px;
178    margin-right: 10px;
179    cursor: pointer;
180}
181
182.btn-fourth {
183    text-decoration: none;
184    background: #e3e5e8;
185    color: #747b8b;
186}
187
188ul.with-out > li:before, .dropdown-menu li:before, ul.whithout > li:before {display:none;}
189
190.dropdown-menu li {padding:0;}
191
192.dropdown-menu-height-fixed {max-height:200px;overflow-y:auto;}
193
194.dropdown-item.active, .dropdown-item:active {background:red;}
195
196.block-shadow {box-shadow:0 2px 8px 0 rgba(32,35,44,0.05);}
197.block-white {background:#fff;border-radius:8px;padding:20px;}<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
198<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.9.0/css/bootstrap-datepicker.min.css" rel="stylesheet">
199<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.9.0/js/bootstrap-datepicker.min.js"></script>
200
201<form id="reservation" action="/restaurants/123/" method="post">
202   <div class="block-shadow block-white mb-4">
203        <h5 class="fw-bold mb-3">Reserve a table</h5>
204        <div class="btn-s">
205            <a class="btn btn-fourth "
206               id="reservation-date"
207               data-date=">">
208                <span class="icon br-calender"></span> <span class="js-value">
209                    -- ---                </span>
210            </a>
211            <a class="btn btn-fourth "
212               id="reservation-time" role="button" data-bs-toggle="dropdown" aria-expanded="false">
213                <span class="icon br-clock"></span> <span class="js-value">
214                    -- : --                </span>
215            </a>
216            <ul class="dropdown-menu dropdown-menu-height-fixed" aria-labelledby="reservation-time">
217                                    <li><a class="dropdown-item " href="#" data-value="0.00">00.00 PM</a></li>
218                                    <li><a class="dropdown-item " href="#" data-value="0.30">00.30 AM</a></li>
219                                    <li><a class="dropdown-item " href="#" data-value="1.00">01.00 AM</a></li>
220                                    <li><a class="dropdown-item " href="#" data-value="1.30">01.30 AM</a></li>
221                                    <li><a class="dropdown-item " href="#" data-value="2.00">02.00 AM</a></li>
222                                    <li><a class="dropdown-item " href="#" data-value="2.30">02.30 AM</a></li>
223                                    <li><a class="dropdown-item " href="#" data-value="3.00">03.00 AM</a></li>
224                                    <li><a class="dropdown-item " href="#" data-value="3.30">03.30 AM</a></li>
225                                    <li><a class="dropdown-item " href="#" data-value="4.00">04.00 AM</a></li>
226                                    <li><a class="dropdown-item " href="#" data-value="4.30">04.30 AM</a></li>
227                                    <li><a class="dropdown-item " href="#" data-value="5.00">05.00 AM</a></li>
228                                    <li><a class="dropdown-item " href="#" data-value="5.30">05.30 AM</a></li>
229                                    <li><a class="dropdown-item " href="#" data-value="6.00">06.00 AM</a></li>
230                                    <li><a class="dropdown-item " href="#" data-value="6.30">06.30 AM</a></li>
231                                    <li><a class="dropdown-item " href="#" data-value="7.00">07.00 AM</a></li>
232                                    <li><a class="dropdown-item " href="#" data-value="7.30">07.30 AM</a></li>
233                                    <li><a class="dropdown-item " href="#" data-value="8.00">08.00 AM</a></li>
234                                    <li><a class="dropdown-item " href="#" data-value="8.30">08.30 AM</a></li>
235                                    <li><a class="dropdown-item " href="#" data-value="9.00">09.00 AM</a></li>
236                                    <li><a class="dropdown-item " href="#" data-value="9.30">09.30 AM</a></li>
237                                    <li><a class="dropdown-item " href="#" data-value="10.00">10.00 AM</a></li>
238                                    <li><a class="dropdown-item " href="#" data-value="10.30">10.30 AM</a></li>
239                                    <li><a class="dropdown-item " href="#" data-value="11.00">11.00 AM</a></li>
240                                    <li><a class="dropdown-item " href="#" data-value="11.30">11.30 AM</a></li>
241                                    <li><a class="dropdown-item " href="#" data-value="12.00">00.00 AM</a></li>
242                                    <li><a class="dropdown-item " href="#" data-value="12.30">00.30 PM</a></li>
243                                    <li><a class="dropdown-item " href="#" data-value="13.00">01.00 PM</a></li>
244                                    <li><a class="dropdown-item " href="#" data-value="13.30">01.30 PM</a></li>
245                                    <li><a class="dropdown-item " href="#" data-value="14.00">02.00 PM</a></li>
246                                    <li><a class="dropdown-item " href="#" data-value="14.30">02.30 PM</a></li>
247                                    <li><a class="dropdown-item " href="#" data-value="15.00">03.00 PM</a></li>
248                                    <li><a class="dropdown-item " href="#" data-value="15.30">03.30 PM</a></li>
249                                    <li><a class="dropdown-item " href="#" data-value="16.00">04.00 PM</a></li>
250                                    <li><a class="dropdown-item " href="#" data-value="16.30">04.30 PM</a></li>
251                                    <li><a class="dropdown-item " href="#" data-value="17.00">05.00 PM</a></li>
252                                    <li><a class="dropdown-item " href="#" data-value="17.30">05.30 PM</a></li>
253                                    <li><a class="dropdown-item " href="#" data-value="18.00">06.00 PM</a></li>
254                                    <li><a class="dropdown-item " href="#" data-value="18.30">06.30 PM</a></li>
255                                    <li><a class="dropdown-item " href="#" data-value="19.00">07.00 PM</a></li>
256                                    <li><a class="dropdown-item " href="#" data-value="19.30">07.30 PM</a></li>
257                                    <li><a class="dropdown-item " href="#" data-value="20.00">08.00 PM</a></li>
258                                    <li><a class="dropdown-item " href="#" data-value="20.30">08.30 PM</a></li>
259                                    <li><a class="dropdown-item " href="#" data-value="21.00">09.00 PM</a></li>
260                                    <li><a class="dropdown-item " href="#" data-value="21.30">09.30 PM</a></li>
261                                    <li><a class="dropdown-item " href="#" data-value="22.00">10.00 PM</a></li>
262                                    <li><a class="dropdown-item " href="#" data-value="22.30">10.30 PM</a></li>
263                                    <li><a class="dropdown-item " href="#" data-value="23.00">11.00 PM</a></li>
264                                    <li><a class="dropdown-item " href="#" data-value="23.30">11.30 PM</a></li>
265                            </ul>
266        </div>
267        <div class="form-group field-restaurantreservationform-personcount">
268<input type="hidden" id="restaurantreservationform-personcount" class="form-control" name="RestaurantReservationForm[personCount]" data-btn-id="reservation-person">
269</div>        <div class="form-group field-restaurantreservationform-date required">
270<input type="hidden" id="restaurantreservationform-date" class="form-control" name="RestaurantReservationForm[date]" data-btn-id="reservation-date">
271</div>        <div class="form-group field-restaurantreservationform-time">
272<input type="hidden" id="restaurantreservationform-time" class="form-control" name="RestaurantReservationForm[time]" data-btn-id="reservation-time">
273</div>
1<?php
2
3namespace common\models;
4
5use yii\behaviors\TimestampBehavior;
6use yii\db\ActiveRecord;
7use yii\db\Expression;
8
9class WorkHours extends _source_WorkHours
10{
11    public const WEEK_DAY_MON = 'Mon';
12    public const WEEK_DAY_TUE = 'Tue';
13    public const WEEK_DAY_WED = 'Wed';
14    public const WEEK_DAY_THU = 'Thu';
15    public const WEEK_DAY_FRI = 'Fri';
16    public const WEEK_DAY_SAT = 'Sat';
17    public const WEEK_DAY_SUN = 'Sun';
18
19
20    /**
21     * {@inheritdoc}
22     */
23    public function behaviors(): array
24    {
25        return [
26            'timestamp' => [
27                'class'      => TimestampBehavior::class,
28                'attributes' => [
29                    ActiveRecord::EVENT_BEFORE_INSERT => ['created_at'],
30                ],
31                'value'      => new Expression('NOW()'),
32            ],
33        ];
34    }
35
36    public static function weekDays(): array
37    {
38        return [
39            self::WEEK_DAY_MON => 'Monday',
40            self::WEEK_DAY_TUE => 'Tuesday',
41            self::WEEK_DAY_WED => 'Wednesday',
42            self::WEEK_DAY_THU => 'Thursday',
43            self::WEEK_DAY_FRI => 'Friday',
44            self::WEEK_DAY_SAT => 'Saturday',
45            self::WEEK_DAY_SUN => 'Sunday',
46        ];
47    }
48
49    public static function getWeekDay(string $val): string
50    {
51        $ar = self::weekDays();
52
53        return $ar[$val] ?? $val;
54    }
55
56    public static function hoursList(): array
57    {
58        $list = [];
59        for ($i = 0; $i < 24; $i++) {
60            $A = 'AM';
61            $n = $i;
62            if ($i >= 12) {
63                $A = 'PM';
64                $n = $i - 12;
65            }
66
67            $n = $n < 10 ? '0' . $n : $n;
68            $_A = ($i === 12 ? 'AM' : $A);
69            $list[$i . '.00'] = $n . '.00 ' . ($i === 0 ? 'PM' : $_A);
70            $list[$i . '.30'] = $n . '.30 ' . $A;
71        }
72        return $list;
73    }
74}
75$this->registerJsFile('/js/restaurant-reserve.js', ['depends' => [JqueryAsset::class]]);
76$this->registerJs('restaurantReserve.init()');
77
78<a class="btn btn-fourth <?= $restaurantReservationForm->getErrors('date') ? 'btn-error' : '' ?>" id="reservation-date" data-date="<?= $restaurantReservationForm->getDate()
79                   ? $restaurantReservationForm->getDate()->format('m/d/Y') : '' ?>>">
80  <span class="icon br-calender"></span> <span class="js-value">
81                    <?= $restaurantReservationForm->date
82                        ? (new DateTime($restaurantReservationForm->date))->format('d M') : '-- ---' ?>
83                </span>
84</a>
85<a class="btn btn-fourth <?= $restaurantReservationForm->getErrors('time') ? 'btn-error' : '' ?>" id="reservation-time" role="button" data-bs-toggle="dropdown" aria-expanded="false">
86  <span class="icon br-clock"></span> <span class="js-value">
87                    <?= $restaurantReservationForm->time
88                        ? WorkHours::hoursList()[$restaurantReservationForm->time] : '-- : --' ?>
89                </span>
90</a>
91<ul class="dropdown-menu dropdown-menu-height-fixed" aria-labelledby="reservation-time">
92  <?php foreach (WorkHours::hoursList() as $k => $v) { ?>
93    <li>
94      <a class="dropdown-item <?= $restaurantReservationForm->time === $k ? 'active' : ''
95                        ?>" href="#" data-value="<?= $k ?>">
96        <?= $v ?>
97      </a>
98    </li>
99    <?php } ?>
100</ul>
101let restaurantReserve = {
102    init: function () {
103        let _self = this;
104
105        $('#reservation-date').datepicker({startDate: '+0d'}).on('changeDate', function (e) {
106            const arDate = e.date.toString().split(' ');
107            let input = $('[name="RestaurantReservationForm[date]"]');
108            input.val(arDate[3] + '-' + (e.date.getMonth() + 1) + '-' + arDate[2]);
109            _self.unSetError(input);
110            $('#reservation-date .js-value').text(arDate[2] + ' ' + arDate[1]);
111        });
112
113        $('[aria-labelledby="reservation-time"] li a').click(function () {
114            $(this).closest('ul').find('a').removeClass('active');
115            $(this).addClass('active');
116            let input = $('[name="RestaurantReservationForm[time]"]');
117            input.val($(this).data('value'));
118            _self.unSetError(input);
119            $('#reservation-time .js-value').text($(this).text());
120        });
121
122        $('[aria-labelledby="reservation-person"] li a').click(function () {
123            $(this).closest('ul').find('a').removeClass('active');
124            $(this).addClass('active');
125            let input = $('[name="RestaurantReservationForm[personCount]"]');
126            input.val($(this).data('value'));
127            _self.unSetError(input);
128            $('#reservation-person .js-value').text($(this).data('value'));
129        });
130    },
131    setError: function (ob) {
132        $('#' + ob.data('btnId')).addClass('btn-error');
133    },
134    unSetError: function (ob) {
135        $('#' + ob.data('btnId')).removeClass('btn-error');
136    }
137}
138$this->registerJs('restaurantReserve.init('. Json::encode($restaurant->workHours) .')');
139restaurantDate: function (e) {
140        ...
141    }
142let restaurantReserve = {
143    init: function () {
144        let _self = this;
145        
146        $('#reservation-date').datepicker({startDate: '+0d'}).on('changeDate', function (e) {
147            const arDate = e.date.toString().split(' ');
148            let input = $('[name="RestaurantReservationForm[date]"]');
149            input.val(arDate[3] + '-' + (e.date.getMonth() + 1) + '-' + arDate[2]);
150            _self.unSetError(input);
151            $('#reservation-date .js-value').text(arDate[2] + ' ' + arDate[1]);
152        });
153
154        $('[aria-labelledby="reservation-time"] li a').click(function () {
155            $(this).closest('ul').find('a').removeClass('active');
156            $(this).addClass('active');
157            let input = $('[name="RestaurantReservationForm[time]"]');
158            input.val($(this).data('value'));
159            _self.unSetError(input);
160            $('#reservation-time .js-value').text($(this).text());
161        });
162    },
163    setError: function (ob) {
164        $('#' + ob.data('btnId')).addClass('btn-error');
165    },
166    unSetError: function (ob) {
167        $('#' + ob.data('btnId')).removeClass('btn-error');
168    }
169}
170
171restaurantReserve.init();.btn {
172    border: none;
173    border-radius: 8px;
174    height: 40px;
175    padding: 10px 15px;
176    font-weight: 800;
177    font-size: 14px;
178    margin-right: 10px;
179    cursor: pointer;
180}
181
182.btn-fourth {
183    text-decoration: none;
184    background: #e3e5e8;
185    color: #747b8b;
186}
187
188ul.with-out > li:before, .dropdown-menu li:before, ul.whithout > li:before {display:none;}
189
190.dropdown-menu li {padding:0;}
191
192.dropdown-menu-height-fixed {max-height:200px;overflow-y:auto;}
193
194.dropdown-item.active, .dropdown-item:active {background:red;}
195
196.block-shadow {box-shadow:0 2px 8px 0 rgba(32,35,44,0.05);}
197.block-white {background:#fff;border-radius:8px;padding:20px;}<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
198<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.9.0/css/bootstrap-datepicker.min.css" rel="stylesheet">
199<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.9.0/js/bootstrap-datepicker.min.js"></script>
200
201<form id="reservation" action="/restaurants/123/" method="post">
202   <div class="block-shadow block-white mb-4">
203        <h5 class="fw-bold mb-3">Reserve a table</h5>
204        <div class="btn-s">
205            <a class="btn btn-fourth "
206               id="reservation-date"
207               data-date=">">
208                <span class="icon br-calender"></span> <span class="js-value">
209                    -- ---                </span>
210            </a>
211            <a class="btn btn-fourth "
212               id="reservation-time" role="button" data-bs-toggle="dropdown" aria-expanded="false">
213                <span class="icon br-clock"></span> <span class="js-value">
214                    -- : --                </span>
215            </a>
216            <ul class="dropdown-menu dropdown-menu-height-fixed" aria-labelledby="reservation-time">
217                                    <li><a class="dropdown-item " href="#" data-value="0.00">00.00 PM</a></li>
218                                    <li><a class="dropdown-item " href="#" data-value="0.30">00.30 AM</a></li>
219                                    <li><a class="dropdown-item " href="#" data-value="1.00">01.00 AM</a></li>
220                                    <li><a class="dropdown-item " href="#" data-value="1.30">01.30 AM</a></li>
221                                    <li><a class="dropdown-item " href="#" data-value="2.00">02.00 AM</a></li>
222                                    <li><a class="dropdown-item " href="#" data-value="2.30">02.30 AM</a></li>
223                                    <li><a class="dropdown-item " href="#" data-value="3.00">03.00 AM</a></li>
224                                    <li><a class="dropdown-item " href="#" data-value="3.30">03.30 AM</a></li>
225                                    <li><a class="dropdown-item " href="#" data-value="4.00">04.00 AM</a></li>
226                                    <li><a class="dropdown-item " href="#" data-value="4.30">04.30 AM</a></li>
227                                    <li><a class="dropdown-item " href="#" data-value="5.00">05.00 AM</a></li>
228                                    <li><a class="dropdown-item " href="#" data-value="5.30">05.30 AM</a></li>
229                                    <li><a class="dropdown-item " href="#" data-value="6.00">06.00 AM</a></li>
230                                    <li><a class="dropdown-item " href="#" data-value="6.30">06.30 AM</a></li>
231                                    <li><a class="dropdown-item " href="#" data-value="7.00">07.00 AM</a></li>
232                                    <li><a class="dropdown-item " href="#" data-value="7.30">07.30 AM</a></li>
233                                    <li><a class="dropdown-item " href="#" data-value="8.00">08.00 AM</a></li>
234                                    <li><a class="dropdown-item " href="#" data-value="8.30">08.30 AM</a></li>
235                                    <li><a class="dropdown-item " href="#" data-value="9.00">09.00 AM</a></li>
236                                    <li><a class="dropdown-item " href="#" data-value="9.30">09.30 AM</a></li>
237                                    <li><a class="dropdown-item " href="#" data-value="10.00">10.00 AM</a></li>
238                                    <li><a class="dropdown-item " href="#" data-value="10.30">10.30 AM</a></li>
239                                    <li><a class="dropdown-item " href="#" data-value="11.00">11.00 AM</a></li>
240                                    <li><a class="dropdown-item " href="#" data-value="11.30">11.30 AM</a></li>
241                                    <li><a class="dropdown-item " href="#" data-value="12.00">00.00 AM</a></li>
242                                    <li><a class="dropdown-item " href="#" data-value="12.30">00.30 PM</a></li>
243                                    <li><a class="dropdown-item " href="#" data-value="13.00">01.00 PM</a></li>
244                                    <li><a class="dropdown-item " href="#" data-value="13.30">01.30 PM</a></li>
245                                    <li><a class="dropdown-item " href="#" data-value="14.00">02.00 PM</a></li>
246                                    <li><a class="dropdown-item " href="#" data-value="14.30">02.30 PM</a></li>
247                                    <li><a class="dropdown-item " href="#" data-value="15.00">03.00 PM</a></li>
248                                    <li><a class="dropdown-item " href="#" data-value="15.30">03.30 PM</a></li>
249                                    <li><a class="dropdown-item " href="#" data-value="16.00">04.00 PM</a></li>
250                                    <li><a class="dropdown-item " href="#" data-value="16.30">04.30 PM</a></li>
251                                    <li><a class="dropdown-item " href="#" data-value="17.00">05.00 PM</a></li>
252                                    <li><a class="dropdown-item " href="#" data-value="17.30">05.30 PM</a></li>
253                                    <li><a class="dropdown-item " href="#" data-value="18.00">06.00 PM</a></li>
254                                    <li><a class="dropdown-item " href="#" data-value="18.30">06.30 PM</a></li>
255                                    <li><a class="dropdown-item " href="#" data-value="19.00">07.00 PM</a></li>
256                                    <li><a class="dropdown-item " href="#" data-value="19.30">07.30 PM</a></li>
257                                    <li><a class="dropdown-item " href="#" data-value="20.00">08.00 PM</a></li>
258                                    <li><a class="dropdown-item " href="#" data-value="20.30">08.30 PM</a></li>
259                                    <li><a class="dropdown-item " href="#" data-value="21.00">09.00 PM</a></li>
260                                    <li><a class="dropdown-item " href="#" data-value="21.30">09.30 PM</a></li>
261                                    <li><a class="dropdown-item " href="#" data-value="22.00">10.00 PM</a></li>
262                                    <li><a class="dropdown-item " href="#" data-value="22.30">10.30 PM</a></li>
263                                    <li><a class="dropdown-item " href="#" data-value="23.00">11.00 PM</a></li>
264                                    <li><a class="dropdown-item " href="#" data-value="23.30">11.30 PM</a></li>
265                            </ul>
266        </div>
267        <div class="form-group field-restaurantreservationform-personcount">
268<input type="hidden" id="restaurantreservationform-personcount" class="form-control" name="RestaurantReservationForm[personCount]" data-btn-id="reservation-person">
269</div>        <div class="form-group field-restaurantreservationform-date required">
270<input type="hidden" id="restaurantreservationform-date" class="form-control" name="RestaurantReservationForm[date]" data-btn-id="reservation-date">
271</div>        <div class="form-group field-restaurantreservationform-time">
272<input type="hidden" id="restaurantreservationform-time" class="form-control" name="RestaurantReservationForm[time]" data-btn-id="reservation-time">
273</div>[{"id":86,"restaurant_id":1,"day":"Mon","open":"9.30","close":"14.30","created_at":"2022-02-22 10:56:15"},{"id":87,"restaurant_id":1,"day":"Tue","open":"3.00","close":"21.00","created_at":"2022-02-22 10:56:15"},{"id":88,"restaurant_id":1,"day":"Wed","open":"4.30","close":"6.30","created_at":"2022-02-22 10:56:15"},{"id":89,"restaurant_id":1,"day":"Thu","open":"2.30","close":"7.00","created_at":"2022-02-22 10:56:15"},{"id":90,"restaurant_id":1,"day":"Fri","open":"3.00","close":"22.00","created_at":"2022-02-22 10:56:15"},{"id":91,"restaurant_id":1,"day":"Sat","open":"1.30","close":"4.30","created_at":"2022-02-22 10:56:15"},{"id":92,"restaurant_id":1,"day":"Sun","open":"3.00","close":"20.30","created_at":"2022-02-22 10:56:15"}]
274
1<?php
2
3namespace common\models;
4
5use yii\behaviors\TimestampBehavior;
6use yii\db\ActiveRecord;
7use yii\db\Expression;
8
9class WorkHours extends _source_WorkHours
10{
11    public const WEEK_DAY_MON = 'Mon';
12    public const WEEK_DAY_TUE = 'Tue';
13    public const WEEK_DAY_WED = 'Wed';
14    public const WEEK_DAY_THU = 'Thu';
15    public const WEEK_DAY_FRI = 'Fri';
16    public const WEEK_DAY_SAT = 'Sat';
17    public const WEEK_DAY_SUN = 'Sun';
18
19
20    /**
21     * {@inheritdoc}
22     */
23    public function behaviors(): array
24    {
25        return [
26            'timestamp' => [
27                'class'      => TimestampBehavior::class,
28                'attributes' => [
29                    ActiveRecord::EVENT_BEFORE_INSERT => ['created_at'],
30                ],
31                'value'      => new Expression('NOW()'),
32            ],
33        ];
34    }
35
36    public static function weekDays(): array
37    {
38        return [
39            self::WEEK_DAY_MON => 'Monday',
40            self::WEEK_DAY_TUE => 'Tuesday',
41            self::WEEK_DAY_WED => 'Wednesday',
42            self::WEEK_DAY_THU => 'Thursday',
43            self::WEEK_DAY_FRI => 'Friday',
44            self::WEEK_DAY_SAT => 'Saturday',
45            self::WEEK_DAY_SUN => 'Sunday',
46        ];
47    }
48
49    public static function getWeekDay(string $val): string
50    {
51        $ar = self::weekDays();
52
53        return $ar[$val] ?? $val;
54    }
55
56    public static function hoursList(): array
57    {
58        $list = [];
59        for ($i = 0; $i < 24; $i++) {
60            $A = 'AM';
61            $n = $i;
62            if ($i >= 12) {
63                $A = 'PM';
64                $n = $i - 12;
65            }
66
67            $n = $n < 10 ? '0' . $n : $n;
68            $_A = ($i === 12 ? 'AM' : $A);
69            $list[$i . '.00'] = $n . '.00 ' . ($i === 0 ? 'PM' : $_A);
70            $list[$i . '.30'] = $n . '.30 ' . $A;
71        }
72        return $list;
73    }
74}
75$this->registerJsFile('/js/restaurant-reserve.js', ['depends' => [JqueryAsset::class]]);
76$this->registerJs('restaurantReserve.init()');
77
78<a class="btn btn-fourth <?= $restaurantReservationForm->getErrors('date') ? 'btn-error' : '' ?>" id="reservation-date" data-date="<?= $restaurantReservationForm->getDate()
79                   ? $restaurantReservationForm->getDate()->format('m/d/Y') : '' ?>>">
80  <span class="icon br-calender"></span> <span class="js-value">
81                    <?= $restaurantReservationForm->date
82                        ? (new DateTime($restaurantReservationForm->date))->format('d M') : '-- ---' ?>
83                </span>
84</a>
85<a class="btn btn-fourth <?= $restaurantReservationForm->getErrors('time') ? 'btn-error' : '' ?>" id="reservation-time" role="button" data-bs-toggle="dropdown" aria-expanded="false">
86  <span class="icon br-clock"></span> <span class="js-value">
87                    <?= $restaurantReservationForm->time
88                        ? WorkHours::hoursList()[$restaurantReservationForm->time] : '-- : --' ?>
89                </span>
90</a>
91<ul class="dropdown-menu dropdown-menu-height-fixed" aria-labelledby="reservation-time">
92  <?php foreach (WorkHours::hoursList() as $k => $v) { ?>
93    <li>
94      <a class="dropdown-item <?= $restaurantReservationForm->time === $k ? 'active' : ''
95                        ?>" href="#" data-value="<?= $k ?>">
96        <?= $v ?>
97      </a>
98    </li>
99    <?php } ?>
100</ul>
101let restaurantReserve = {
102    init: function () {
103        let _self = this;
104
105        $('#reservation-date').datepicker({startDate: '+0d'}).on('changeDate', function (e) {
106            const arDate = e.date.toString().split(' ');
107            let input = $('[name="RestaurantReservationForm[date]"]');
108            input.val(arDate[3] + '-' + (e.date.getMonth() + 1) + '-' + arDate[2]);
109            _self.unSetError(input);
110            $('#reservation-date .js-value').text(arDate[2] + ' ' + arDate[1]);
111        });
112
113        $('[aria-labelledby="reservation-time"] li a').click(function () {
114            $(this).closest('ul').find('a').removeClass('active');
115            $(this).addClass('active');
116            let input = $('[name="RestaurantReservationForm[time]"]');
117            input.val($(this).data('value'));
118            _self.unSetError(input);
119            $('#reservation-time .js-value').text($(this).text());
120        });
121
122        $('[aria-labelledby="reservation-person"] li a').click(function () {
123            $(this).closest('ul').find('a').removeClass('active');
124            $(this).addClass('active');
125            let input = $('[name="RestaurantReservationForm[personCount]"]');
126            input.val($(this).data('value'));
127            _self.unSetError(input);
128            $('#reservation-person .js-value').text($(this).data('value'));
129        });
130    },
131    setError: function (ob) {
132        $('#' + ob.data('btnId')).addClass('btn-error');
133    },
134    unSetError: function (ob) {
135        $('#' + ob.data('btnId')).removeClass('btn-error');
136    }
137}
138$this->registerJs('restaurantReserve.init('. Json::encode($restaurant->workHours) .')');
139restaurantDate: function (e) {
140        ...
141    }
142let restaurantReserve = {
143    init: function () {
144        let _self = this;
145        
146        $('#reservation-date').datepicker({startDate: '+0d'}).on('changeDate', function (e) {
147            const arDate = e.date.toString().split(' ');
148            let input = $('[name="RestaurantReservationForm[date]"]');
149            input.val(arDate[3] + '-' + (e.date.getMonth() + 1) + '-' + arDate[2]);
150            _self.unSetError(input);
151            $('#reservation-date .js-value').text(arDate[2] + ' ' + arDate[1]);
152        });
153
154        $('[aria-labelledby="reservation-time"] li a').click(function () {
155            $(this).closest('ul').find('a').removeClass('active');
156            $(this).addClass('active');
157            let input = $('[name="RestaurantReservationForm[time]"]');
158            input.val($(this).data('value'));
159            _self.unSetError(input);
160            $('#reservation-time .js-value').text($(this).text());
161        });
162    },
163    setError: function (ob) {
164        $('#' + ob.data('btnId')).addClass('btn-error');
165    },
166    unSetError: function (ob) {
167        $('#' + ob.data('btnId')).removeClass('btn-error');
168    }
169}
170
171restaurantReserve.init();.btn {
172    border: none;
173    border-radius: 8px;
174    height: 40px;
175    padding: 10px 15px;
176    font-weight: 800;
177    font-size: 14px;
178    margin-right: 10px;
179    cursor: pointer;
180}
181
182.btn-fourth {
183    text-decoration: none;
184    background: #e3e5e8;
185    color: #747b8b;
186}
187
188ul.with-out > li:before, .dropdown-menu li:before, ul.whithout > li:before {display:none;}
189
190.dropdown-menu li {padding:0;}
191
192.dropdown-menu-height-fixed {max-height:200px;overflow-y:auto;}
193
194.dropdown-item.active, .dropdown-item:active {background:red;}
195
196.block-shadow {box-shadow:0 2px 8px 0 rgba(32,35,44,0.05);}
197.block-white {background:#fff;border-radius:8px;padding:20px;}<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
198<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.9.0/css/bootstrap-datepicker.min.css" rel="stylesheet">
199<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.9.0/js/bootstrap-datepicker.min.js"></script>
200
201<form id="reservation" action="/restaurants/123/" method="post">
202   <div class="block-shadow block-white mb-4">
203        <h5 class="fw-bold mb-3">Reserve a table</h5>
204        <div class="btn-s">
205            <a class="btn btn-fourth "
206               id="reservation-date"
207               data-date=">">
208                <span class="icon br-calender"></span> <span class="js-value">
209                    -- ---                </span>
210            </a>
211            <a class="btn btn-fourth "
212               id="reservation-time" role="button" data-bs-toggle="dropdown" aria-expanded="false">
213                <span class="icon br-clock"></span> <span class="js-value">
214                    -- : --                </span>
215            </a>
216            <ul class="dropdown-menu dropdown-menu-height-fixed" aria-labelledby="reservation-time">
217                                    <li><a class="dropdown-item " href="#" data-value="0.00">00.00 PM</a></li>
218                                    <li><a class="dropdown-item " href="#" data-value="0.30">00.30 AM</a></li>
219                                    <li><a class="dropdown-item " href="#" data-value="1.00">01.00 AM</a></li>
220                                    <li><a class="dropdown-item " href="#" data-value="1.30">01.30 AM</a></li>
221                                    <li><a class="dropdown-item " href="#" data-value="2.00">02.00 AM</a></li>
222                                    <li><a class="dropdown-item " href="#" data-value="2.30">02.30 AM</a></li>
223                                    <li><a class="dropdown-item " href="#" data-value="3.00">03.00 AM</a></li>
224                                    <li><a class="dropdown-item " href="#" data-value="3.30">03.30 AM</a></li>
225                                    <li><a class="dropdown-item " href="#" data-value="4.00">04.00 AM</a></li>
226                                    <li><a class="dropdown-item " href="#" data-value="4.30">04.30 AM</a></li>
227                                    <li><a class="dropdown-item " href="#" data-value="5.00">05.00 AM</a></li>
228                                    <li><a class="dropdown-item " href="#" data-value="5.30">05.30 AM</a></li>
229                                    <li><a class="dropdown-item " href="#" data-value="6.00">06.00 AM</a></li>
230                                    <li><a class="dropdown-item " href="#" data-value="6.30">06.30 AM</a></li>
231                                    <li><a class="dropdown-item " href="#" data-value="7.00">07.00 AM</a></li>
232                                    <li><a class="dropdown-item " href="#" data-value="7.30">07.30 AM</a></li>
233                                    <li><a class="dropdown-item " href="#" data-value="8.00">08.00 AM</a></li>
234                                    <li><a class="dropdown-item " href="#" data-value="8.30">08.30 AM</a></li>
235                                    <li><a class="dropdown-item " href="#" data-value="9.00">09.00 AM</a></li>
236                                    <li><a class="dropdown-item " href="#" data-value="9.30">09.30 AM</a></li>
237                                    <li><a class="dropdown-item " href="#" data-value="10.00">10.00 AM</a></li>
238                                    <li><a class="dropdown-item " href="#" data-value="10.30">10.30 AM</a></li>
239                                    <li><a class="dropdown-item " href="#" data-value="11.00">11.00 AM</a></li>
240                                    <li><a class="dropdown-item " href="#" data-value="11.30">11.30 AM</a></li>
241                                    <li><a class="dropdown-item " href="#" data-value="12.00">00.00 AM</a></li>
242                                    <li><a class="dropdown-item " href="#" data-value="12.30">00.30 PM</a></li>
243                                    <li><a class="dropdown-item " href="#" data-value="13.00">01.00 PM</a></li>
244                                    <li><a class="dropdown-item " href="#" data-value="13.30">01.30 PM</a></li>
245                                    <li><a class="dropdown-item " href="#" data-value="14.00">02.00 PM</a></li>
246                                    <li><a class="dropdown-item " href="#" data-value="14.30">02.30 PM</a></li>
247                                    <li><a class="dropdown-item " href="#" data-value="15.00">03.00 PM</a></li>
248                                    <li><a class="dropdown-item " href="#" data-value="15.30">03.30 PM</a></li>
249                                    <li><a class="dropdown-item " href="#" data-value="16.00">04.00 PM</a></li>
250                                    <li><a class="dropdown-item " href="#" data-value="16.30">04.30 PM</a></li>
251                                    <li><a class="dropdown-item " href="#" data-value="17.00">05.00 PM</a></li>
252                                    <li><a class="dropdown-item " href="#" data-value="17.30">05.30 PM</a></li>
253                                    <li><a class="dropdown-item " href="#" data-value="18.00">06.00 PM</a></li>
254                                    <li><a class="dropdown-item " href="#" data-value="18.30">06.30 PM</a></li>
255                                    <li><a class="dropdown-item " href="#" data-value="19.00">07.00 PM</a></li>
256                                    <li><a class="dropdown-item " href="#" data-value="19.30">07.30 PM</a></li>
257                                    <li><a class="dropdown-item " href="#" data-value="20.00">08.00 PM</a></li>
258                                    <li><a class="dropdown-item " href="#" data-value="20.30">08.30 PM</a></li>
259                                    <li><a class="dropdown-item " href="#" data-value="21.00">09.00 PM</a></li>
260                                    <li><a class="dropdown-item " href="#" data-value="21.30">09.30 PM</a></li>
261                                    <li><a class="dropdown-item " href="#" data-value="22.00">10.00 PM</a></li>
262                                    <li><a class="dropdown-item " href="#" data-value="22.30">10.30 PM</a></li>
263                                    <li><a class="dropdown-item " href="#" data-value="23.00">11.00 PM</a></li>
264                                    <li><a class="dropdown-item " href="#" data-value="23.30">11.30 PM</a></li>
265                            </ul>
266        </div>
267        <div class="form-group field-restaurantreservationform-personcount">
268<input type="hidden" id="restaurantreservationform-personcount" class="form-control" name="RestaurantReservationForm[personCount]" data-btn-id="reservation-person">
269</div>        <div class="form-group field-restaurantreservationform-date required">
270<input type="hidden" id="restaurantreservationform-date" class="form-control" name="RestaurantReservationForm[date]" data-btn-id="reservation-date">
271</div>        <div class="form-group field-restaurantreservationform-time">
272<input type="hidden" id="restaurantreservationform-time" class="form-control" name="RestaurantReservationForm[time]" data-btn-id="reservation-time">
273</div>[{"id":86,"restaurant_id":1,"day":"Mon","open":"9.30","close":"14.30","created_at":"2022-02-22 10:56:15"},{"id":87,"restaurant_id":1,"day":"Tue","open":"3.00","close":"21.00","created_at":"2022-02-22 10:56:15"},{"id":88,"restaurant_id":1,"day":"Wed","open":"4.30","close":"6.30","created_at":"2022-02-22 10:56:15"},{"id":89,"restaurant_id":1,"day":"Thu","open":"2.30","close":"7.00","created_at":"2022-02-22 10:56:15"},{"id":90,"restaurant_id":1,"day":"Fri","open":"3.00","close":"22.00","created_at":"2022-02-22 10:56:15"},{"id":91,"restaurant_id":1,"day":"Sat","open":"1.30","close":"4.30","created_at":"2022-02-22 10:56:15"},{"id":92,"restaurant_id":1,"day":"Sun","open":"3.00","close":"20.30","created_at":"2022-02-22 10:56:15"}]
274[{"id":107,"restaurant_id":3,"day":"Mon","open":"1.30","close":"19.00","created_at":"2022-02-22 10:58:59"},{"id":108,"restaurant_id":3,"day":"Tue","open":"5.30","close":"8.00","created_at":"2022-02-22 10:58:59"},{"id":109,"restaurant_id":3,"day":"Wed","open":"3.00","close":"20.30","created_at":"2022-02-22 10:58:59"},{"id":110,"restaurant_id":3,"day":"Thu","open":"1.00","close":"12.30","created_at":"2022-02-22 10:58:59"},{"id":111,"restaurant_id":3,"day":"Fri","open":"2.30","close":"12.30","created_at":"2022-02-22 10:58:59"},{"id":112,"restaurant_id":3,"day":"Sat","open":"4.00","close":"22.00","created_at":"2022-02-22 10:58:59"},{"id":113,"restaurant_id":3,"day":"Sun","open":"4.00","close":"22.30","created_at":"2022-02-22 10:58:59"}]
275

ANSWER

Answered 2022-Feb-23 at 16:12

Since your code is not a runnable snippet to reproduce the behavior, I will refrain from providing a full solution and, instead, I provide the means to solve the issue. Your JSON of

1<?php
2
3namespace common\models;
4
5use yii\behaviors\TimestampBehavior;
6use yii\db\ActiveRecord;
7use yii\db\Expression;
8
9class WorkHours extends _source_WorkHours
10{
11    public const WEEK_DAY_MON = 'Mon';
12    public const WEEK_DAY_TUE = 'Tue';
13    public const WEEK_DAY_WED = 'Wed';
14    public const WEEK_DAY_THU = 'Thu';
15    public const WEEK_DAY_FRI = 'Fri';
16    public const WEEK_DAY_SAT = 'Sat';
17    public const WEEK_DAY_SUN = 'Sun';
18
19
20    /**
21     * {@inheritdoc}
22     */
23    public function behaviors(): array
24    {
25        return [
26            'timestamp' => [
27                'class'      => TimestampBehavior::class,
28                'attributes' => [
29                    ActiveRecord::EVENT_BEFORE_INSERT => ['created_at'],
30                ],
31                'value'      => new Expression('NOW()'),
32            ],
33        ];
34    }
35
36    public static function weekDays(): array
37    {
38        return [
39            self::WEEK_DAY_MON => 'Monday',
40            self::WEEK_DAY_TUE => 'Tuesday',
41            self::WEEK_DAY_WED => 'Wednesday',
42            self::WEEK_DAY_THU => 'Thursday',
43            self::WEEK_DAY_FRI => 'Friday',
44            self::WEEK_DAY_SAT => 'Saturday',
45            self::WEEK_DAY_SUN => 'Sunday',
46        ];
47    }
48
49    public static function getWeekDay(string $val): string
50    {
51        $ar = self::weekDays();
52
53        return $ar[$val] ?? $val;
54    }
55
56    public static function hoursList(): array
57    {
58        $list = [];
59        for ($i = 0; $i < 24; $i++) {
60            $A = 'AM';
61            $n = $i;
62            if ($i >= 12) {
63                $A = 'PM';
64                $n = $i - 12;
65            }
66
67            $n = $n < 10 ? '0' . $n : $n;
68            $_A = ($i === 12 ? 'AM' : $A);
69            $list[$i . '.00'] = $n . '.00 ' . ($i === 0 ? 'PM' : $_A);
70            $list[$i . '.30'] = $n . '.30 ' . $A;
71        }
72        return $list;
73    }
74}
75$this->registerJsFile('/js/restaurant-reserve.js', ['depends' => [JqueryAsset::class]]);
76$this->registerJs('restaurantReserve.init()');
77
78<a class="btn btn-fourth <?= $restaurantReservationForm->getErrors('date') ? 'btn-error' : '' ?>" id="reservation-date" data-date="<?= $restaurantReservationForm->getDate()
79                   ? $restaurantReservationForm->getDate()->format('m/d/Y') : '' ?>>">
80  <span class="icon br-calender"></span> <span class="js-value">
81                    <?= $restaurantReservationForm->date
82                        ? (new DateTime($restaurantReservationForm->date))->format('d M') : '-- ---' ?>
83                </span>
84</a>
85<a class="btn btn-fourth <?= $restaurantReservationForm->getErrors('time') ? 'btn-error' : '' ?>" id="reservation-time" role="button" data-bs-toggle="dropdown" aria-expanded="false">
86  <span class="icon br-clock"></span> <span class="js-value">
87                    <?= $restaurantReservationForm->time
88                        ? WorkHours::hoursList()[$restaurantReservationForm->time] : '-- : --' ?>
89                </span>
90</a>
91<ul class="dropdown-menu dropdown-menu-height-fixed" aria-labelledby="reservation-time">
92  <?php foreach (WorkHours::hoursList() as $k => $v) { ?>
93    <li>
94      <a class="dropdown-item <?= $restaurantReservationForm->time === $k ? 'active' : ''
95                        ?>" href="#" data-value="<?= $k ?>">
96        <?= $v ?>
97      </a>
98    </li>
99    <?php } ?>
100</ul>
101let restaurantReserve = {
102    init: function () {
103        let _self = this;
104
105        $('#reservation-date').datepicker({startDate: '+0d'}).on('changeDate', function (e) {
106            const arDate = e.date.toString().split(' ');
107            let input = $('[name="RestaurantReservationForm[date]"]');
108            input.val(arDate[3] + '-' + (e.date.getMonth() + 1) + '-' + arDate[2]);
109            _self.unSetError(input);
110            $('#reservation-date .js-value').text(arDate[2] + ' ' + arDate[1]);
111        });
112
113        $('[aria-labelledby="reservation-time"] li a').click(function () {
114            $(this).closest('ul').find('a').removeClass('active');
115            $(this).addClass('active');
116            let input = $('[name="RestaurantReservationForm[time]"]');
117            input.val($(this).data('value'));
118            _self.unSetError(input);
119            $('#reservation-time .js-value').text($(this).text());
120        });
121
122        $('[aria-labelledby="reservation-person"] li a').click(function () {
123            $(this).closest('ul').find('a').removeClass('active');
124            $(this).addClass('active');
125            let input = $('[name="RestaurantReservationForm[personCount]"]');
126            input.val($(this).data('value'));
127            _self.unSetError(input);
128            $('#reservation-person .js-value').text($(this).data('value'));
129        });
130    },
131    setError: function (ob) {
132        $('#' + ob.data('btnId')).addClass('btn-error');
133    },
134    unSetError: function (ob) {
135        $('#' + ob.data('btnId')).removeClass('btn-error');
136    }
137}
138$this->registerJs('restaurantReserve.init('. Json::encode($restaurant->workHours) .')');
139restaurantDate: function (e) {
140        ...
141    }
142let restaurantReserve = {
143    init: function () {
144        let _self = this;
145        
146        $('#reservation-date').datepicker({startDate: '+0d'}).on('changeDate', function (e) {
147            const arDate = e.date.toString().split(' ');
148            let input = $('[name="RestaurantReservationForm[date]"]');
149            input.val(arDate[3] + '-' + (e.date.getMonth() + 1) + '-' + arDate[2]);
150            _self.unSetError(input);
151            $('#reservation-date .js-value').text(arDate[2] + ' ' + arDate[1]);
152        });
153
154        $('[aria-labelledby="reservation-time"] li a').click(function () {
155            $(this).closest('ul').find('a').removeClass('active');
156            $(this).addClass('active');
157            let input = $('[name="RestaurantReservationForm[time]"]');
158            input.val($(this).data('value'));
159            _self.unSetError(input);
160            $('#reservation-time .js-value').text($(this).text());
161        });
162    },
163    setError: function (ob) {
164        $('#' + ob.data('btnId')).addClass('btn-error');
165    },
166    unSetError: function (ob) {
167        $('#' + ob.data('btnId')).removeClass('btn-error');
168    }
169}
170
171restaurantReserve.init();.btn {
172    border: none;
173    border-radius: 8px;
174    height: 40px;
175    padding: 10px 15px;
176    font-weight: 800;
177    font-size: 14px;
178    margin-right: 10px;
179    cursor: pointer;
180}
181
182.btn-fourth {
183    text-decoration: none;
184    background: #e3e5e8;
185    color: #747b8b;
186}
187
188ul.with-out > li:before, .dropdown-menu li:before, ul.whithout > li:before {display:none;}
189
190.dropdown-menu li {padding:0;}
191
192.dropdown-menu-height-fixed {max-height:200px;overflow-y:auto;}
193
194.dropdown-item.active, .dropdown-item:active {background:red;}
195
196.block-shadow {box-shadow:0 2px 8px 0 rgba(32,35,44,0.05);}
197.block-white {background:#fff;border-radius:8px;padding:20px;}<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
198<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.9.0/css/bootstrap-datepicker.min.css" rel="stylesheet">
199<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.9.0/js/bootstrap-datepicker.min.js"></script>
200
201<form id="reservation" action="/restaurants/123/" method="post">
202   <div class="block-shadow block-white mb-4">
203        <h5 class="fw-bold mb-3">Reserve a table</h5>
204        <div class="btn-s">
205            <a class="btn btn-fourth "
206               id="reservation-date"
207               data-date=">">
208                <span class="icon br-calender"></span> <span class="js-value">
209                    -- ---                </span>
210            </a>
211            <a class="btn btn-fourth "
212               id="reservation-time" role="button" data-bs-toggle="dropdown" aria-expanded="false">
213                <span class="icon br-clock"></span> <span class="js-value">
214                    -- : --                </span>
215            </a>
216            <ul class="dropdown-menu dropdown-menu-height-fixed" aria-labelledby="reservation-time">
217                                    <li><a class="dropdown-item " href="#" data-value="0.00">00.00 PM</a></li>
218                                    <li><a class="dropdown-item " href="#" data-value="0.30">00.30 AM</a></li>
219                                    <li><a class="dropdown-item " href="#" data-value="1.00">01.00 AM</a></li>
220                                    <li><a class="dropdown-item " href="#" data-value="1.30">01.30 AM</a></li>
221                                    <li><a class="dropdown-item " href="#" data-value="2.00">02.00 AM</a></li>
222                                    <li><a class="dropdown-item " href="#" data-value="2.30">02.30 AM</a></li>
223                                    <li><a class="dropdown-item " href="#" data-value="3.00">03.00 AM</a></li>
224                                    <li><a class="dropdown-item " href="#" data-value="3.30">03.30 AM</a></li>
225                                    <li><a class="dropdown-item " href="#" data-value="4.00">04.00 AM</a></li>
226                                    <li><a class="dropdown-item " href="#" data-value="4.30">04.30 AM</a></li>
227                                    <li><a class="dropdown-item " href="#" data-value="5.00">05.00 AM</a></li>
228                                    <li><a class="dropdown-item " href="#" data-value="5.30">05.30 AM</a></li>
229                                    <li><a class="dropdown-item " href="#" data-value="6.00">06.00 AM</a></li>
230                                    <li><a class="dropdown-item " href="#" data-value="6.30">06.30 AM</a></li>
231                                    <li><a class="dropdown-item " href="#" data-value="7.00">07.00 AM</a></li>
232                                    <li><a class="dropdown-item " href="#" data-value="7.30">07.30 AM</a></li>
233                                    <li><a class="dropdown-item " href="#" data-value="8.00">08.00 AM</a></li>
234                                    <li><a class="dropdown-item " href="#" data-value="8.30">08.30 AM</a></li>
235                                    <li><a class="dropdown-item " href="#" data-value="9.00">09.00 AM</a></li>
236                                    <li><a class="dropdown-item " href="#" data-value="9.30">09.30 AM</a></li>
237                                    <li><a class="dropdown-item " href="#" data-value="10.00">10.00 AM</a></li>
238                                    <li><a class="dropdown-item " href="#" data-value="10.30">10.30 AM</a></li>
239                                    <li><a class="dropdown-item " href="#" data-value="11.00">11.00 AM</a></li>
240                                    <li><a class="dropdown-item " href="#" data-value="11.30">11.30 AM</a></li>
241                                    <li><a class="dropdown-item " href="#" data-value="12.00">00.00 AM</a></li>
242                                    <li><a class="dropdown-item " href="#" data-value="12.30">00.30 PM</a></li>
243                                    <li><a class="dropdown-item " href="#" data-value="13.00">01.00 PM</a></li>
244                                    <li><a class="dropdown-item " href="#" data-value="13.30">01.30 PM</a></li>
245                                    <li><a class="dropdown-item " href="#" data-value="14.00">02.00 PM</a></li>
246                                    <li><a class="dropdown-item " href="#" data-value="14.30">02.30 PM</a></li>
247                                    <li><a class="dropdown-item " href="#" data-value="15.00">03.00 PM</a></li>
248                                    <li><a class="dropdown-item " href="#" data-value="15.30">03.30 PM</a></li>
249                                    <li><a class="dropdown-item " href="#" data-value="16.00">04.00 PM</a></li>
250                                    <li><a class="dropdown-item " href="#" data-value="16.30">04.30 PM</a></li>
251                                    <li><a class="dropdown-item " href="#" data-value="17.00">05.00 PM</a></li>
252                                    <li><a class="dropdown-item " href="#" data-value="17.30">05.30 PM</a></li>
253                                    <li><a class="dropdown-item " href="#" data-value="18.00">06.00 PM</a></li>
254                                    <li><a class="dropdown-item " href="#" data-value="18.30">06.30 PM</a></li>
255                                    <li><a class="dropdown-item " href="#" data-value="19.00">07.00 PM</a></li>
256                                    <li><a class="dropdown-item " href="#" data-value="19.30">07.30 PM</a></li>
257                                    <li><a class="dropdown-item " href="#" data-value="20.00">08.00 PM</a></li>
258                                    <li><a class="dropdown-item " href="#" data-value="20.30">08.30 PM</a></li>
259                                    <li><a class="dropdown-item " href="#" data-value="21.00">09.00 PM</a></li>
260                                    <li><a class="dropdown-item " href="#" data-value="21.30">09.30 PM</a></li>
261                                    <li><a class="dropdown-item " href="#" data-value="22.00">10.00 PM</a></li>
262                                    <li><a class="dropdown-item " href="#" data-value="22.30">10.30 PM</a></li>
263                                    <li><a class="dropdown-item " href="#" data-value="23.00">11.00 PM</a></li>
264                                    <li><a class="dropdown-item " href="#" data-value="23.30">11.30 PM</a></li>
265                            </ul>
266        </div>
267        <div class="form-group field-restaurantreservationform-personcount">
268<input type="hidden" id="restaurantreservationform-personcount" class="form-control" name="RestaurantReservationForm[personCount]" data-btn-id="reservation-person">
269</div>        <div class="form-group field-restaurantreservationform-date required">
270<input type="hidden" id="restaurantreservationform-date" class="form-control" name="RestaurantReservationForm[date]" data-btn-id="reservation-date">
271</div>        <div class="form-group field-restaurantreservationform-time">
272<input type="hidden" id="restaurantreservationform-time" class="form-control" name="RestaurantReservationForm[time]" data-btn-id="reservation-time">
273</div>[{"id":86,"restaurant_id":1,"day":"Mon","open":"9.30","close":"14.30","created_at":"2022-02-22 10:56:15"},{"id":87,"restaurant_id":1,"day":"Tue","open":"3.00","close":"21.00","created_at":"2022-02-22 10:56:15"},{"id":88,"restaurant_id":1,"day":"Wed","open":"4.30","close":"6.30","created_at":"2022-02-22 10:56:15"},{"id":89,"restaurant_id":1,"day":"Thu","open":"2.30","close":"7.00","created_at":"2022-02-22 10:56:15"},{"id":90,"restaurant_id":1,"day":"Fri","open":"3.00","close":"22.00","created_at":"2022-02-22 10:56:15"},{"id":91,"restaurant_id":1,"day":"Sat","open":"1.30","close":"4.30","created_at":"2022-02-22 10:56:15"},{"id":92,"restaurant_id":1,"day":"Sun","open":"3.00","close":"20.30","created_at":"2022-02-22 10:56:15"}]
274[{"id":107,"restaurant_id":3,"day":"Mon","open":"1.30","close":"19.00","created_at":"2022-02-22 10:58:59"},{"id":108,"restaurant_id":3,"day":"Tue","open":"5.30","close":"8.00","created_at":"2022-02-22 10:58:59"},{"id":109,"restaurant_id":3,"day":"Wed","open":"3.00","close":"20.30","created_at":"2022-02-22 10:58:59"},{"id":110,"restaurant_id":3,"day":"Thu","open":"1.00","close":"12.30","created_at":"2022-02-22 10:58:59"},{"id":111,"restaurant_id":3,"day":"Fri","open":"2.30","close":"12.30","created_at":"2022-02-22 10:58:59"},{"id":112,"restaurant_id":3,"day":"Sat","open":"4.00","close":"22.00","created_at":"2022-02-22 10:58:59"},{"id":113,"restaurant_id":3,"day":"Sun","open":"4.00","close":"22.30","created_at":"2022-02-22 10:58:59"}]
275[{"id":"1","restaurant_id":"1","day":"Mon","open":"9.30","close":"14.30","created_at":"2022-02-15 05:00:57"}]
276

has a restaurant_id and a day. So, let's define a function that finds all hours for all days for a restaurant:

1<?php
2
3namespace common\models;
4
5use yii\behaviors\TimestampBehavior;
6use yii\db\ActiveRecord;
7use yii\db\Expression;
8
9class WorkHours extends _source_WorkHours
10{
11    public const WEEK_DAY_MON = 'Mon';
12    public const WEEK_DAY_TUE = 'Tue';
13    public const WEEK_DAY_WED = 'Wed';
14    public const WEEK_DAY_THU = 'Thu';
15    public const WEEK_DAY_FRI = 'Fri';
16    public const WEEK_DAY_SAT = 'Sat';
17    public const WEEK_DAY_SUN = 'Sun';
18
19
20    /**
21     * {@inheritdoc}
22     */
23    public function behaviors(): array
24    {
25        return [
26            'timestamp' => [
27                'class'      => TimestampBehavior::class,
28                'attributes' => [
29                    ActiveRecord::EVENT_BEFORE_INSERT => ['created_at'],
30                ],
31                'value'      => new Expression('NOW()'),
32            ],
33        ];
34    }
35
36    public static function weekDays(): array
37    {
38        return [
39            self::WEEK_DAY_MON => 'Monday',
40            self::WEEK_DAY_TUE => 'Tuesday',
41            self::WEEK_DAY_WED => 'Wednesday',
42            self::WEEK_DAY_THU => 'Thursday',
43            self::WEEK_DAY_FRI => 'Friday',
44            self::WEEK_DAY_SAT => 'Saturday',
45            self::WEEK_DAY_SUN => 'Sunday',
46        ];
47    }
48
49    public static function getWeekDay(string $val): string
50    {
51        $ar = self::weekDays();
52
53        return $ar[$val] ?? $val;
54    }
55
56    public static function hoursList(): array
57    {
58        $list = [];
59        for ($i = 0; $i < 24; $i++) {
60            $A = 'AM';
61            $n = $i;
62            if ($i >= 12) {
63                $A = 'PM';
64                $n = $i - 12;
65            }
66
67            $n = $n < 10 ? '0' . $n : $n;
68            $_A = ($i === 12 ? 'AM' : $A);
69            $list[$i . '.00'] = $n . '.00 ' . ($i === 0 ? 'PM' : $_A);
70            $list[$i . '.30'] = $n . '.30 ' . $A;
71        }
72        return $list;
73    }
74}
75$this->registerJsFile('/js/restaurant-reserve.js', ['depends' => [JqueryAsset::class]]);
76$this->registerJs('restaurantReserve.init()');
77
78<a class="btn btn-fourth <?= $restaurantReservationForm->getErrors('date') ? 'btn-error' : '' ?>" id="reservation-date" data-date="<?= $restaurantReservationForm->getDate()
79                   ? $restaurantReservationForm->getDate()->format('m/d/Y') : '' ?>>">
80  <span class="icon br-calender"></span> <span class="js-value">
81                    <?= $restaurantReservationForm->date
82                        ? (new DateTime($restaurantReservationForm->date))->format('d M') : '-- ---' ?>
83                </span>
84</a>
85<a class="btn btn-fourth <?= $restaurantReservationForm->getErrors('time') ? 'btn-error' : '' ?>" id="reservation-time" role="button" data-bs-toggle="dropdown" aria-expanded="false">
86  <span class="icon br-clock"></span> <span class="js-value">
87                    <?= $restaurantReservationForm->time
88                        ? WorkHours::hoursList()[$restaurantReservationForm->time] : '-- : --' ?>
89                </span>
90</a>
91<ul class="dropdown-menu dropdown-menu-height-fixed" aria-labelledby="reservation-time">
92  <?php foreach (WorkHours::hoursList() as $k => $v) { ?>
93    <li>
94      <a class="dropdown-item <?= $restaurantReservationForm->time === $k ? 'active' : ''
95                        ?>" href="#" data-value="<?= $k ?>">
96        <?= $v ?>
97      </a>
98    </li>
99    <?php } ?>
100</ul>
101let restaurantReserve = {
102    init: function () {
103        let _self = this;
104
105        $('#reservation-date').datepicker({startDate: '+0d'}).on('changeDate', function (e) {
106            const arDate = e.date.toString().split(' ');
107            let input = $('[name="RestaurantReservationForm[date]"]');
108            input.val(arDate[3] + '-' + (e.date.getMonth() + 1) + '-' + arDate[2]);
109            _self.unSetError(input);
110            $('#reservation-date .js-value').text(arDate[2] + ' ' + arDate[1]);
111        });
112
113        $('[aria-labelledby="reservation-time"] li a').click(function () {
114            $(this).closest('ul').find('a').removeClass('active');
115            $(this).addClass('active');
116            let input = $('[name="RestaurantReservationForm[time]"]');
117            input.val($(this).data('value'));
118            _self.unSetError(input);
119            $('#reservation-time .js-value').text($(this).text());
120        });
121
122        $('[aria-labelledby="reservation-person"] li a').click(function () {
123            $(this).closest('ul').find('a').removeClass('active');
124            $(this).addClass('active');
125            let input = $('[name="RestaurantReservationForm[personCount]"]');
126            input.val($(this).data('value'));
127            _self.unSetError(input);
128            $('#reservation-person .js-value').text($(this).data('value'));
129        });
130    },
131    setError: function (ob) {
132        $('#' + ob.data('btnId')).addClass('btn-error');
133    },
134    unSetError: function (ob) {
135        $('#' + ob.data('btnId')).removeClass('btn-error');
136    }
137}
138$this->registerJs('restaurantReserve.init('. Json::encode($restaurant->workHours) .')');
139restaurantDate: function (e) {
140        ...
141    }
142let restaurantReserve = {
143    init: function () {
144        let _self = this;
145        
146        $('#reservation-date').datepicker({startDate: '+0d'}).on('changeDate', function (e) {
147            const arDate = e.date.toString().split(' ');
148            let input = $('[name="RestaurantReservationForm[date]"]');
149            input.val(arDate[3] + '-' + (e.date.getMonth() + 1) + '-' + arDate[2]);
150            _self.unSetError(input);
151            $('#reservation-date .js-value').text(arDate[2] + ' ' + arDate[1]);
152        });
153
154        $('[aria-labelledby="reservation-time"] li a').click(function () {
155            $(this).closest('ul').find('a').removeClass('active');
156            $(this).addClass('active');
157            let input = $('[name="RestaurantReservationForm[time]"]');
158            input.val($(this).data('value'));
159            _self.unSetError(input);
160            $('#reservation-time .js-value').text($(this).text());
161        });
162    },
163    setError: function (ob) {
164        $('#' + ob.data('btnId')).addClass('btn-error');
165    },
166    unSetError: function (ob) {
167        $('#' + ob.data('btnId')).removeClass('btn-error');
168    }
169}
170
171restaurantReserve.init();.btn {
172    border: none;
173    border-radius: 8px;
174    height: 40px;
175    padding: 10px 15px;
176    font-weight: 800;
177    font-size: 14px;
178    margin-right: 10px;
179    cursor: pointer;
180}
181
182.btn-fourth {
183    text-decoration: none;
184    background: #e3e5e8;
185    color: #747b8b;
186}
187
188ul.with-out > li:before, .dropdown-menu li:before, ul.whithout > li:before {display:none;}
189
190.dropdown-menu li {padding:0;}
191
192.dropdown-menu-height-fixed {max-height:200px;overflow-y:auto;}
193
194.dropdown-item.active, .dropdown-item:active {background:red;}
195
196.block-shadow {box-shadow:0 2px 8px 0 rgba(32,35,44,0.05);}
197.block-white {background:#fff;border-radius:8px;padding:20px;}<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
198<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.9.0/css/bootstrap-datepicker.min.css" rel="stylesheet">
199<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.9.0/js/bootstrap-datepicker.min.js"></script>
200
201<form id="reservation" action="/restaurants/123/" method="post">
202   <div class="block-shadow block-white mb-4">
203        <h5 class="fw-bold mb-3">Reserve a table</h5>
204        <div class="btn-s">
205            <a class="btn btn-fourth "
206               id="reservation-date"
207               data-date=">">
208                <span class="icon br-calender"></span> <span class="js-value">
209                    -- ---                </span>
210            </a>
211            <a class="btn btn-fourth "
212               id="reservation-time" role="button" data-bs-toggle="dropdown" aria-expanded="false">
213                <span class="icon br-clock"></span> <span class="js-value">
214                    -- : --                </span>
215            </a>
216            <ul class="dropdown-menu dropdown-menu-height-fixed" aria-labelledby="reservation-time">
217                                    <li><a class="dropdown-item " href="#" data-value="0.00">00.00 PM</a></li>
218                                    <li><a class="dropdown-item " href="#" data-value="0.30">00.30 AM</a></li>
219                                    <li><a class="dropdown-item " href="#" data-value="1.00">01.00 AM</a></li>
220                                    <li><a class="dropdown-item " href="#" data-value="1.30">01.30 AM</a></li>
221                                    <li><a class="dropdown-item " href="#" data-value="2.00">02.00 AM</a></li>
222                                    <li><a class="dropdown-item " href="#" data-value="2.30">02.30 AM</a></li>
223                                    <li><a class="dropdown-item " href="#" data-value="3.00">03.00 AM</a></li>
224                                    <li><a class="dropdown-item " href="#" data-value="3.30">03.30 AM</a></li>
225                                    <li><a class="dropdown-item " href="#" data-value="4.00">04.00 AM</a></li>
226                                    <li><a class="dropdown-item " href="#" data-value="4.30">04.30 AM</a></li>
227                                    <li><a class="dropdown-item " href="#" data-value="5.00">05.00 AM</a></li>
228                                    <li><a class="dropdown-item " href="#" data-value="5.30">05.30 AM</a></li>
229                                    <li><a class="dropdown-item " href="#" data-value="6.00">06.00 AM</a></li>
230                                    <li><a class="dropdown-item " href="#" data-value="6.30">06.30 AM</a></li>
231                                    <li><a class="dropdown-item " href="#" data-value="7.00">07.00 AM</a></li>
232                                    <li><a class="dropdown-item " href="#" data-value="7.30">07.30 AM</a></li>
233                                    <li><a class="dropdown-item " href="#" data-value="8.00">08.00 AM</a></li>
234                                    <li><a class="dropdown-item " href="#" data-value="8.30">08.30 AM</a></li>
235                                    <li><a class="dropdown-item " href="#" data-value="9.00">09.00 AM</a></li>
236                                    <li><a class="dropdown-item " href="#" data-value="9.30">09.30 AM</a></li>
237                                    <li><a class="dropdown-item " href="#" data-value="10.00">10.00 AM</a></li>
238                                    <li><a class="dropdown-item " href="#" data-value="10.30">10.30 AM</a></li>
239                                    <li><a class="dropdown-item " href="#" data-value="11.00">11.00 AM</a></li>
240                                    <li><a class="dropdown-item " href="#" data-value="11.30">11.30 AM</a></li>
241                                    <li><a class="dropdown-item " href="#" data-value="12.00">00.00 AM</a></li>
242                                    <li><a class="dropdown-item " href="#" data-value="12.30">00.30 PM</a></li>
243                                    <li><a class="dropdown-item " href="#" data-value="13.00">01.00 PM</a></li>
244                                    <li><a class="dropdown-item " href="#" data-value="13.30">01.30 PM</a></li>
245                                    <li><a class="dropdown-item " href="#" data-value="14.00">02.00 PM</a></li>
246                                    <li><a class="dropdown-item " href="#" data-value="14.30">02.30 PM</a></li>
247                                    <li><a class="dropdown-item " href="#" data-value="15.00">03.00 PM</a></li>
248                                    <li><a class="dropdown-item " href="#" data-value="15.30">03.30 PM</a></li>
249                                    <li><a class="dropdown-item " href="#" data-value="16.00">04.00 PM</a></li>
250                                    <li><a class="dropdown-item " href="#" data-value="16.30">04.30 PM</a></li>
251                                    <li><a class="dropdown-item " href="#" data-value="17.00">05.00 PM</a></li>
252                                    <li><a class="dropdown-item " href="#" data-value="17.30">05.30 PM</a></li>
253                                    <li><a class="dropdown-item " href="#" data-value="18.00">06.00 PM</a></li>
254                                    <li><a class="dropdown-item " href="#" data-value="18.30">06.30 PM</a></li>
255                                    <li><a class="dropdown-item " href="#" data-value="19.00">07.00 PM</a></li>
256                                    <li><a class="dropdown-item " href="#" data-value="19.30">07.30 PM</a></li>
257                                    <li><a class="dropdown-item " href="#" data-value="20.00">08.00 PM</a></li>
258                                    <li><a class="dropdown-item " href="#" data-value="20.30">08.30 PM</a></li>
259                                    <li><a class="dropdown-item " href="#" data-value="21.00">09.00 PM</a></li>
260                                    <li><a class="dropdown-item " href="#" data-value="21.30">09.30 PM</a></li>
261                                    <li><a class="dropdown-item " href="#" data-value="22.00">10.00 PM</a></li>
262                                    <li><a class="dropdown-item " href="#" data-value="22.30">10.30 PM</a></li>
263                                    <li><a class="dropdown-item " href="#" data-value="23.00">11.00 PM</a></li>
264                                    <li><a class="dropdown-item " href="#" data-value="23.30">11.30 PM</a></li>
265                            </ul>
266        </div>
267        <div class="form-group field-restaurantreservationform-personcount">
268<input type="hidden" id="restaurantreservationform-personcount" class="form-control" name="RestaurantReservationForm[personCount]" data-btn-id="reservation-person">
269</div>        <div class="form-group field-restaurantreservationform-date required">
270<input type="hidden" id="restaurantreservationform-date" class="form-control" name="RestaurantReservationForm[date]" data-btn-id="reservation-date">
271</div>        <div class="form-group field-restaurantreservationform-time">
272<input type="hidden" id="restaurantreservationform-time" class="form-control" name="RestaurantReservationForm[time]" data-btn-id="reservation-time">
273</div>[{"id":86,"restaurant_id":1,"day":"Mon","open":"9.30","close":"14.30","created_at":"2022-02-22 10:56:15"},{"id":87,"restaurant_id":1,"day":"Tue","open":"3.00","close":"21.00","created_at":"2022-02-22 10:56:15"},{"id":88,"restaurant_id":1,"day":"Wed","open":"4.30","close":"6.30","created_at":"2022-02-22 10:56:15"},{"id":89,"restaurant_id":1,"day":"Thu","open":"2.30","close":"7.00","created_at":"2022-02-22 10:56:15"},{"id":90,"restaurant_id":1,"day":"Fri","open":"3.00","close":"22.00","created_at":"2022-02-22 10:56:15"},{"id":91,"restaurant_id":1,"day":"Sat","open":"1.30","close":"4.30","created_at":"2022-02-22 10:56:15"},{"id":92,"restaurant_id":1,"day":"Sun","open":"3.00","close":"20.30","created_at":"2022-02-22 10:56:15"}]
274[{"id":107,"restaurant_id":3,"day":"Mon","open":"1.30","close":"19.00","created_at":"2022-02-22 10:58:59"},{"id":108,"restaurant_id":3,"day":"Tue","open":"5.30","close":"8.00","created_at":"2022-02-22 10:58:59"},{"id":109,"restaurant_id":3,"day":"Wed","open":"3.00","close":"20.30","created_at":"2022-02-22 10:58:59"},{"id":110,"restaurant_id":3,"day":"Thu","open":"1.00","close":"12.30","created_at":"2022-02-22 10:58:59"},{"id":111,"restaurant_id":3,"day":"Fri","open":"2.30","close":"12.30","created_at":"2022-02-22 10:58:59"},{"id":112,"restaurant_id":3,"day":"Sat","open":"4.00","close":"22.00","created_at":"2022-02-22 10:58:59"},{"id":113,"restaurant_id":3,"day":"Sun","open":"4.00","close":"22.30","created_at":"2022-02-22 10:58:59"}]
275[{"id":"1","restaurant_id":"1","day":"Mon","open":"9.30","close":"14.30","created_at":"2022-02-15 05:00:57"}]
276function getWorkHours(json, restaurant_id) {
277    return json.filter(item => item.restaurant_id === restaurant_id);
278}
279

And this is how you can find the work hours of a day for a restaurant:

1<?php
2
3namespace common\models;
4
5use yii\behaviors\TimestampBehavior;
6use yii\db\ActiveRecord;
7use yii\db\Expression;
8
9class WorkHours extends _source_WorkHours
10{
11    public const WEEK_DAY_MON = 'Mon';
12    public const WEEK_DAY_TUE = 'Tue';
13    public const WEEK_DAY_WED = 'Wed';
14    public const WEEK_DAY_THU = 'Thu';
15    public const WEEK_DAY_FRI = 'Fri';
16    public const WEEK_DAY_SAT = 'Sat';
17    public const WEEK_DAY_SUN = 'Sun';
18
19
20    /**
21     * {@inheritdoc}
22     */
23    public function behaviors(): array
24    {
25        return [
26            'timestamp' => [
27                'class'      => TimestampBehavior::class,
28                'attributes' => [
29                    ActiveRecord::EVENT_BEFORE_INSERT => ['created_at'],
30                ],
31                'value'      => new Expression('NOW()'),
32            ],
33        ];
34    }
35
36    public static function weekDays(): array
37    {
38        return [
39            self::WEEK_DAY_MON => 'Monday',
40            self::WEEK_DAY_TUE => 'Tuesday',
41            self::WEEK_DAY_WED => 'Wednesday',
42            self::WEEK_DAY_THU => 'Thursday',
43            self::WEEK_DAY_FRI => 'Friday',
44            self::WEEK_DAY_SAT => 'Saturday',
45            self::WEEK_DAY_SUN => 'Sunday',
46        ];
47    }
48
49    public static function getWeekDay(string $val): string
50    {
51        $ar = self::weekDays();
52
53        return $ar[$val] ?? $val;
54    }
55
56    public static function hoursList(): array
57    {
58        $list = [];
59        for ($i = 0; $i < 24; $i++) {
60            $A = 'AM';
61            $n = $i;
62            if ($i >= 12) {
63                $A = 'PM';
64                $n = $i - 12;
65            }
66
67            $n = $n < 10 ? '0' . $n : $n;
68            $_A = ($i === 12 ? 'AM' : $A);
69            $list[$i . '.00'] = $n . '.00 ' . ($i === 0 ? 'PM' : $_A);
70            $list[$i . '.30'] = $n . '.30 ' . $A;
71        }
72        return $list;
73    }
74}
75$this->registerJsFile('/js/restaurant-reserve.js', ['depends' => [JqueryAsset::class]]);
76$this->registerJs('restaurantReserve.init()');
77
78<a class="btn btn-fourth <?= $restaurantReservationForm->getErrors('date') ? 'btn-error' : '' ?>" id="reservation-date" data-date="<?= $restaurantReservationForm->getDate()
79                   ? $restaurantReservationForm->getDate()->format('m/d/Y') : '' ?>>">
80  <span class="icon br-calender"></span> <span class="js-value">
81                    <?= $restaurantReservationForm->date
82                        ? (new DateTime($restaurantReservationForm->date))->format('d M') : '-- ---' ?>
83                </span>
84</a>
85<a class="btn btn-fourth <?= $restaurantReservationForm->getErrors('time') ? 'btn-error' : '' ?>" id="reservation-time" role="button" data-bs-toggle="dropdown" aria-expanded="false">
86  <span class="icon br-clock"></span> <span class="js-value">
87                    <?= $restaurantReservationForm->time
88                        ? WorkHours::hoursList()[$restaurantReservationForm->time] : '-- : --' ?>
89                </span>
90</a>
91<ul class="dropdown-menu dropdown-menu-height-fixed" aria-labelledby="reservation-time">
92  <?php foreach (WorkHours::hoursList() as $k => $v) { ?>
93    <li>
94      <a class="dropdown-item <?= $restaurantReservationForm->time === $k ? 'active' : ''
95                        ?>" href="#" data-value="<?= $k ?>">
96        <?= $v ?>
97      </a>
98    </li>
99    <?php } ?>
100</ul>
101let restaurantReserve = {
102    init: function () {
103        let _self = this;
104
105        $('#reservation-date').datepicker({startDate: '+0d'}).on('changeDate', function (e) {
106            const arDate = e.date.toString().split(' ');
107            let input = $('[name="RestaurantReservationForm[date]"]');
108            input.val(arDate[3] + '-' + (e.date.getMonth() + 1) + '-' + arDate[2]);
109            _self.unSetError(input);
110            $('#reservation-date .js-value').text(arDate[2] + ' ' + arDate[1]);
111        });
112
113        $('[aria-labelledby="reservation-time"] li a').click(function () {
114            $(this).closest('ul').find('a').removeClass('active');
115            $(this).addClass('active');
116            let input = $('[name="RestaurantReservationForm[time]"]');
117            input.val($(this).data('value'));
118            _self.unSetError(input);
119            $('#reservation-time .js-value').text($(this).text());
120        });
121
122        $('[aria-labelledby="reservation-person"] li a').click(function () {
123            $(this).closest('ul').find('a').removeClass('active');
124            $(this).addClass('active');
125            let input = $('[name="RestaurantReservationForm[personCount]"]');
126            input.val($(this).data('value'));
127            _self.unSetError(input);
128            $('#reservation-person .js-value').text($(this).data('value'));
129        });
130    },
131    setError: function (ob) {
132        $('#' + ob.data('btnId')).addClass('btn-error');
133    },
134    unSetError: function (ob) {
135        $('#' + ob.data('btnId')).removeClass('btn-error');
136    }
137}
138$this->registerJs('restaurantReserve.init('. Json::encode($restaurant->workHours) .')');
139restaurantDate: function (e) {
140        ...
141    }
142let restaurantReserve = {
143    init: function () {
144        let _self = this;
145        
146        $('#reservation-date').datepicker({startDate: '+0d'}).on('changeDate', function (e) {
147            const arDate = e.date.toString().split(' ');
148            let input = $('[name="RestaurantReservationForm[date]"]');
149            input.val(arDate[3] + '-' + (e.date.getMonth() + 1) + '-' + arDate[2]);
150            _self.unSetError(input);
151            $('#reservation-date .js-value').text(arDate[2] + ' ' + arDate[1]);
152        });
153
154        $('[aria-labelledby="reservation-time"] li a').click(function () {
155            $(this).closest('ul').find('a').removeClass('active');
156            $(this).addClass('active');
157            let input = $('[name="RestaurantReservationForm[time]"]');
158            input.val($(this).data('value'));
159            _self.unSetError(input);
160            $('#reservation-time .js-value').text($(this).text());
161        });
162    },
163    setError: function (ob) {
164        $('#' + ob.data('btnId')).addClass('btn-error');
165    },
166    unSetError: function (ob) {
167        $('#' + ob.data('btnId')).removeClass('btn-error');
168    }
169}
170
171restaurantReserve.init();.btn {
172    border: none;
173    border-radius: 8px;
174    height: 40px;
175    padding: 10px 15px;
176    font-weight: 800;
177    font-size: 14px;
178    margin-right: 10px;
179    cursor: pointer;
180}
181
182.btn-fourth {
183    text-decoration: none;
184    background: #e3e5e8;
185    color: #747b8b;
186}
187
188ul.with-out > li:before, .dropdown-menu li:before, ul.whithout > li:before {display:none;}
189
190.dropdown-menu li {padding:0;}
191
192.dropdown-menu-height-fixed {max-height:200px;overflow-y:auto;}
193
194.dropdown-item.active, .dropdown-item:active {background:red;}
195
196.block-shadow {box-shadow:0 2px 8px 0 rgba(32,35,44,0.05);}
197.block-white {background:#fff;border-radius:8px;padding:20px;}<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
198<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.9.0/css/bootstrap-datepicker.min.css" rel="stylesheet">
199<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.9.0/js/bootstrap-datepicker.min.js"></script>
200
201<form id="reservation" action="/restaurants/123/" method="post">
202   <div class="block-shadow block-white mb-4">
203        <h5 class="fw-bold mb-3">Reserve a table</h5>
204        <div class="btn-s">
205            <a class="btn btn-fourth "
206               id="reservation-date"
207               data-date=">">
208                <span class="icon br-calender"></span> <span class="js-value">
209                    -- ---                </span>
210            </a>
211            <a class="btn btn-fourth "
212               id="reservation-time" role="button" data-bs-toggle="dropdown" aria-expanded="false">
213                <span class="icon br-clock"></span> <span class="js-value">
214                    -- : --                </span>
215            </a>
216            <ul class="dropdown-menu dropdown-menu-height-fixed" aria-labelledby="reservation-time">
217                                    <li><a class="dropdown-item " href="#" data-value="0.00">00.00 PM</a></li>
218                                    <li><a class="dropdown-item " href="#" data-value="0.30">00.30 AM</a></li>
219                                    <li><a class="dropdown-item " href="#" data-value="1.00">01.00 AM</a></li>
220                                    <li><a class="dropdown-item " href="#" data-value="1.30">01.30 AM</a></li>
221                                    <li><a class="dropdown-item " href="#" data-value="2.00">02.00 AM</a></li>
222                                    <li><a class="dropdown-item " href="#" data-value="2.30">02.30 AM</a></li>
223                                    <li><a class="dropdown-item " href="#" data-value="3.00">03.00 AM</a></li>
224                                    <li><a class="dropdown-item " href="#" data-value="3.30">03.30 AM</a></li>
225                                    <li><a class="dropdown-item " href="#" data-value="4.00">04.00 AM</a></li>
226                                    <li><a class="dropdown-item " href="#" data-value="4.30">04.30 AM</a></li>
227                                    <li><a class="dropdown-item " href="#" data-value="5.00">05.00 AM</a></li>
228                                    <li><a class="dropdown-item " href="#" data-value="5.30">05.30 AM</a></li>
229                                    <li><a class="dropdown-item " href="#" data-value="6.00">06.00 AM</a></li>
230                                    <li><a class="dropdown-item " href="#" data-value="6.30">06.30 AM</a></li>
231                                    <li><a class="dropdown-item " href="#" data-value="7.00">07.00 AM</a></li>
232                                    <li><a class="dropdown-item " href="#" data-value="7.30">07.30 AM</a></li>
233                                    <li><a class="dropdown-item " href="#" data-value="8.00">08.00 AM</a></li>
234                                    <li><a class="dropdown-item " href="#" data-value="8.30">08.30 AM</a></li>
235                                    <li><a class="dropdown-item " href="#" data-value="9.00">09.00 AM</a></li>
236                                    <li><a class="dropdown-item " href="#" data-value="9.30">09.30 AM</a></li>
237                                    <li><a class="dropdown-item " href="#" data-value="10.00">10.00 AM</a></li>
238                                    <li><a class="dropdown-item " href="#" data-value="10.30">10.30 AM</a></li>
239                                    <li><a class="dropdown-item " href="#" data-value="11.00">11.00 AM</a></li>
240                                    <li><a class="dropdown-item " href="#" data-value="11.30">11.30 AM</a></li>
241                                    <li><a class="dropdown-item " href="#" data-value="12.00">00.00 AM</a></li>
242                                    <li><a class="dropdown-item " href="#" data-value="12.30">00.30 PM</a></li>
243                                    <li><a class="dropdown-item " href="#" data-value="13.00">01.00 PM</a></li>
244                                    <li><a class="dropdown-item " href="#" data-value="13.30">01.30 PM</a></li>
245                                    <li><a class="dropdown-item " href="#" data-value="14.00">02.00 PM</a></li>
246                                    <li><a class="dropdown-item " href="#" data-value="14.30">02.30 PM</a></li>
247                                    <li><a class="dropdown-item " href="#" data-value="15.00">03.00 PM</a></li>
248                                    <li><a class="dropdown-item " href="#" data-value="15.30">03.30 PM</a></li>
249                                    <li><a class="dropdown-item " href="#" data-value="16.00">04.00 PM</a></li>
250                                    <li><a class="dropdown-item " href="#" data-value="16.30">04.30 PM</a></li>
251                                    <li><a class="dropdown-item " href="#" data-value="17.00">05.00 PM</a></li>
252                                    <li><a class="dropdown-item " href="#" data-value="17.30">05.30 PM</a></li>
253                                    <li><a class="dropdown-item " href="#" data-value="18.00">06.00 PM</a></li>
254                                    <li><a class="dropdown-item " href="#" data-value="18.30">06.30 PM</a></li>
255                                    <li><a class="dropdown-item " href="#" data-value="19.00">07.00 PM</a></li>
256                                    <li><a class="dropdown-item " href="#" data-value="19.30">07.30 PM</a></li>
257                                    <li><a class="dropdown-item " href="#" data-value="20.00">08.00 PM</a></li>
258                                    <li><a class="dropdown-item " href="#" data-value="20.30">08.30 PM</a></li>
259                                    <li><a class="dropdown-item " href="#" data-value="21.00">09.00 PM</a></li>
260                                    <li><a class="dropdown-item " href="#" data-value="21.30">09.30 PM</a></li>
261                                    <li><a class="dropdown-item " href="#" data-value="22.00">10.00 PM</a></li>
262                                    <li><a class="dropdown-item " href="#" data-value="22.30">10.30 PM</a></li>
263                                    <li><a class="dropdown-item " href="#" data-value="23.00">11.00 PM</a></li>
264                                    <li><a class="dropdown-item " href="#" data-value="23.30">11.30 PM</a></li>
265                            </ul>
266        </div>
267        <div class="form-group field-restaurantreservationform-personcount">
268<input type="hidden" id="restaurantreservationform-personcount" class="form-control" name="RestaurantReservationForm[personCount]" data-btn-id="reservation-person">
269</div>        <div class="form-group field-restaurantreservationform-date required">
270<input type="hidden" id="restaurantreservationform-date" class="form-control" name="RestaurantReservationForm[date]" data-btn-id="reservation-date">
271</div>        <div class="form-group field-restaurantreservationform-time">
272<input type="hidden" id="restaurantreservationform-time" class="form-control" name="RestaurantReservationForm[time]" data-btn-id="reservation-time">
273</div>[{"id":86,"restaurant_id":1,"day":"Mon","open":"9.30","close":"14.30","created_at":"2022-02-22 10:56:15"},{"id":87,"restaurant_id":1,"day":"Tue","open":"3.00","close":"21.00","created_at":"2022-02-22 10:56:15"},{"id":88,"restaurant_id":1,"day":"Wed","open":"4.30","close":"6.30","created_at":"2022-02-22 10:56:15"},{"id":89,"restaurant_id":1,"day":"Thu","open":"2.30","close":"7.00","created_at":"2022-02-22 10:56:15"},{"id":90,"restaurant_id":1,"day":"Fri","open":"3.00","close":"22.00","created_at":"2022-02-22 10:56:15"},{"id":91,"restaurant_id":1,"day":"Sat","open":"1.30","close":"4.30","created_at":"2022-02-22 10:56:15"},{"id":92,"restaurant_id":1,"day":"Sun","open":"3.00","close":"20.30","created_at":"2022-02-22 10:56:15"}]
274[{"id":107,"restaurant_id":3,"day":"Mon","open":"1.30","close":"19.00","created_at":"2022-02-22 10:58:59"},{"id":108,"restaurant_id":3,"day":"Tue","open":"5.30","close":"8.00","created_at":"2022-02-22 10:58:59"},{"id":109,"restaurant_id":3,"day":"Wed","open":"3.00","close":"20.30","created_at":"2022-02-22 10:58:59"},{"id":110,"restaurant_id":3,"day":"Thu","open":"1.00","close":"12.30","created_at":"2022-02-22 10:58:59"},{"id":111,"restaurant_id":3,"day":"Fri","open":"2.30","close":"12.30","created_at":"2022-02-22 10:58:59"},{"id":112,"restaurant_id":3,"day":"Sat","open":"4.00","close":"22.00","created_at":"2022-02-22 10:58:59"},{"id":113,"restaurant_id":3,"day":"Sun","open":"4.00","close":"22.30","created_at":"2022-02-22 10:58:59"}]
275[{"id":"1","restaurant_id":"1","day":"Mon","open":"9.30","close":"14.30","created_at":"2022-02-15 05:00:57"}]
276function getWorkHours(json, restaurant_id) {
277    return json.filter(item => item.restaurant_id === restaurant_id);
278}
279function getWorkHoursForDay(json, restaurant_id, day) {
280    return getWorkHours(json, restaurant_id).filter(item => item.day === day);
281}
282

Using these functions you can get the data you need. Based on that data you can fill your HTML the way you need. If you need more information, then please provide a minimal reproducible example of your problem, a JSON input, your current HTML and the HTML you desire based on the JSON input. Then I can apply this for your structure. But, in order to do so, I need to have much more information.

EDIT

Based on the discussion we had in the comment section I have received enough information to solve the issue:

1<?php
2
3namespace common\models;
4
5use yii\behaviors\TimestampBehavior;
6use yii\db\ActiveRecord;
7use yii\db\Expression;
8
9class WorkHours extends _source_WorkHours
10{
11    public const WEEK_DAY_MON = 'Mon';
12    public const WEEK_DAY_TUE = 'Tue';
13    public const WEEK_DAY_WED = 'Wed';
14    public const WEEK_DAY_THU = 'Thu';
15    public const WEEK_DAY_FRI = 'Fri';
16    public const WEEK_DAY_SAT = 'Sat';
17    public const WEEK_DAY_SUN = 'Sun';
18
19
20    /**
21     * {@inheritdoc}
22     */
23    public function behaviors(): array
24    {
25        return [
26            'timestamp' => [
27                'class'      => TimestampBehavior::class,
28                'attributes' => [
29                    ActiveRecord::EVENT_BEFORE_INSERT => ['created_at'],
30                ],
31                'value'      => new Expression('NOW()'),
32            ],
33        ];
34    }
35
36    public static function weekDays(): array
37    {
38        return [
39            self::WEEK_DAY_MON => 'Monday',
40            self::WEEK_DAY_TUE => 'Tuesday',
41            self::WEEK_DAY_WED => 'Wednesday',
42            self::WEEK_DAY_THU => 'Thursday',
43            self::WEEK_DAY_FRI => 'Friday',
44            self::WEEK_DAY_SAT => 'Saturday',
45            self::WEEK_DAY_SUN => 'Sunday',
46        ];
47    }
48
49    public static function getWeekDay(string $val): string
50    {
51        $ar = self::weekDays();
52
53        return $ar[$val] ?? $val;
54    }
55
56    public static function hoursList(): array
57    {
58        $list = [];
59        for ($i = 0; $i < 24; $i++) {
60            $A = 'AM';
61            $n = $i;
62            if ($i >= 12) {
63                $A = 'PM';
64                $n = $i - 12;
65            }
66
67            $n = $n < 10 ? '0' . $n : $n;
68            $_A = ($i === 12 ? 'AM' : $A);
69            $list[$i . '.00'] = $n . '.00 ' . ($i === 0 ? 'PM' : $_A);
70            $list[$i . '.30'] = $n . '.30 ' . $A;
71        }
72        return $list;
73    }
74}
75$this->registerJsFile('/js/restaurant-reserve.js', ['depends' => [JqueryAsset::class]]);
76$this->registerJs('restaurantReserve.init()');
77
78<a class="btn btn-fourth <?= $restaurantReservationForm->getErrors('date') ? 'btn-error' : '' ?>" id="reservation-date" data-date="<?= $restaurantReservationForm->getDate()
79                   ? $restaurantReservationForm->getDate()->format('m/d/Y') : '' ?>>">
80  <span class="icon br-calender"></span> <span class="js-value">
81                    <?= $restaurantReservationForm->date
82                        ? (new DateTime($restaurantReservationForm->date))->format('d M') : '-- ---' ?>
83                </span>
84</a>
85<a class="btn btn-fourth <?= $restaurantReservationForm->getErrors('time') ? 'btn-error' : '' ?>" id="reservation-time" role="button" data-bs-toggle="dropdown" aria-expanded="false">
86  <span class="icon br-clock"></span> <span class="js-value">
87                    <?= $restaurantReservationForm->time
88                        ? WorkHours::hoursList()[$restaurantReservationForm->time] : '-- : --' ?>
89                </span>
90</a>
91<ul class="dropdown-menu dropdown-menu-height-fixed" aria-labelledby="reservation-time">
92  <?php foreach (WorkHours::hoursList() as $k => $v) { ?>
93    <li>
94      <a class="dropdown-item <?= $restaurantReservationForm->time === $k ? 'active' : ''
95                        ?>" href="#" data-value="<?= $k ?>">
96        <?= $v ?>
97      </a>
98    </li>
99    <?php } ?>
100</ul>
101let restaurantReserve = {
102    init: function () {
103        let _self = this;
104
105        $('#reservation-date').datepicker({startDate: '+0d'}).on('changeDate', function (e) {
106            const arDate = e.date.toString().split(' ');
107            let input = $('[name="RestaurantReservationForm[date]"]');
108            input.val(arDate[3] + '-' + (e.date.getMonth() + 1) + '-' + arDate[2]);
109            _self.unSetError(input);
110            $('#reservation-date .js-value').text(arDate[2] + ' ' + arDate[1]);
111        });
112
113        $('[aria-labelledby="reservation-time"] li a').click(function () {
114            $(this).closest('ul').find('a').removeClass('active');
115            $(this).addClass('active');
116            let input = $('[name="RestaurantReservationForm[time]"]');
117            input.val($(this).data('value'));
118            _self.unSetError(input);
119            $('#reservation-time .js-value').text($(this).text());
120        });
121
122        $('[aria-labelledby="reservation-person"] li a').click(function () {
123            $(this).closest('ul').find('a').removeClass('active');
124            $(this).addClass('active');
125            let input = $('[name="RestaurantReservationForm[personCount]"]');
126            input.val($(this).data('value'));
127            _self.unSetError(input);
128            $('#reservation-person .js-value').text($(this).data('value'));
129        });
130    },
131    setError: function (ob) {
132        $('#' + ob.data('btnId')).addClass('btn-error');
133    },
134    unSetError: function (ob) {
135        $('#' + ob.data('btnId')).removeClass('btn-error');
136    }
137}
138$this->registerJs('restaurantReserve.init('. Json::encode($restaurant->workHours) .')');
139restaurantDate: function (e) {
140        ...
141    }
142let restaurantReserve = {
143    init: function () {
144        let _self = this;
145        
146        $('#reservation-date').datepicker({startDate: '+0d'}).on('changeDate', function (e) {
147            const arDate = e.date.toString().split(' ');
148            let input = $('[name="RestaurantReservationForm[date]"]');
149            input.val(arDate[3] + '-' + (e.date.getMonth() + 1) + '-' + arDate[2]);
150            _self.unSetError(input);
151            $('#reservation-date .js-value').text(arDate[2] + ' ' + arDate[1]);
152        });
153
154        $('[aria-labelledby="reservation-time"] li a').click(function () {
155            $(this).closest('ul').find('a').removeClass('active');
156            $(this).addClass('active');
157            let input = $('[name="RestaurantReservationForm[time]"]');
158            input.val($(this).data('value'));
159            _self.unSetError(input);
160            $('#reservation-time .js-value').text($(this).text());
161        });
162    },
163    setError: function (ob) {
164        $('#' + ob.data('btnId')).addClass('btn-error');
165    },
166    unSetError: function (ob) {
167        $('#' + ob.data('btnId')).removeClass('btn-error');
168    }
169}
170
171restaurantReserve.init();.btn {
172    border: none;
173    border-radius: 8px;
174    height: 40px;
175    padding: 10px 15px;
176    font-weight: 800;
177    font-size: 14px;
178    margin-right: 10px;
179    cursor: pointer;
180}
181
182.btn-fourth {
183    text-decoration: none;
184    background: #e3e5e8;
185    color: #747b8b;
186}
187
188ul.with-out > li:before, .dropdown-menu li:before, ul.whithout > li:before {display:none;}
189
190.dropdown-menu li {padding:0;}
191
192.dropdown-menu-height-fixed {max-height:200px;overflow-y:auto;}
193
194.dropdown-item.active, .dropdown-item:active {background:red;}
195
196.block-shadow {box-shadow:0 2px 8px 0 rgba(32,35,44,0.05);}
197.block-white {background:#fff;border-radius:8px;padding:20px;}<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
198<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.9.0/css/bootstrap-datepicker.min.css" rel="stylesheet">
199<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.9.0/js/bootstrap-datepicker.min.js"></script>
200
201<form id="reservation" action="/restaurants/123/" method="post">
202   <div class="block-shadow block-white mb-4">
203        <h5 class="fw-bold mb-3">Reserve a table</h5>
204        <div class="btn-s">
205            <a class="btn btn-fourth "
206               id="reservation-date"
207               data-date=">">
208                <span class="icon br-calender"></span> <span class="js-value">
209                    -- ---                </span>
210            </a>
211            <a class="btn btn-fourth "
212               id="reservation-time" role="button" data-bs-toggle="dropdown" aria-expanded="false">
213                <span class="icon br-clock"></span> <span class="js-value">
214                    -- : --                </span>
215            </a>
216            <ul class="dropdown-menu dropdown-menu-height-fixed" aria-labelledby="reservation-time">
217                                    <li><a class="dropdown-item " href="#" data-value="0.00">00.00 PM</a></li>
218                                    <li><a class="dropdown-item " href="#" data-value="0.30">00.30 AM</a></li>
219                                    <li><a class="dropdown-item " href="#" data-value="1.00">01.00 AM</a></li>
220                                    <li><a class="dropdown-item " href="#" data-value="1.30">01.30 AM</a></li>
221                                    <li><a class="dropdown-item " href="#" data-value="2.00">02.00 AM</a></li>
222                                    <li><a class="dropdown-item " href="#" data-value="2.30">02.30 AM</a></li>
223                                    <li><a class="dropdown-item " href="#" data-value="3.00">03.00 AM</a></li>
224                                    <li><a class="dropdown-item " href="#" data-value="3.30">03.30 AM</a></li>
225                                    <li><a class="dropdown-item " href="#" data-value="4.00">04.00 AM</a></li>
226                                    <li><a class="dropdown-item " href="#" data-value="4.30">04.30 AM</a></li>
227                                    <li><a class="dropdown-item " href="#" data-value="5.00">05.00 AM</a></li>
228                                    <li><a class="dropdown-item " href="#" data-value="5.30">05.30 AM</a></li>
229                                    <li><a class="dropdown-item " href="#" data-value="6.00">06.00 AM</a></li>
230                                    <li><a class="dropdown-item " href="#" data-value="6.30">06.30 AM</a></li>
231                                    <li><a class="dropdown-item " href="#" data-value="7.00">07.00 AM</a></li>
232                                    <li><a class="dropdown-item " href="#" data-value="7.30">07.30 AM</a></li>
233                                    <li><a class="dropdown-item " href="#" data-value="8.00">08.00 AM</a></li>
234                                    <li><a class="dropdown-item " href="#" data-value="8.30">08.30 AM</a></li>
235                                    <li><a class="dropdown-item " href="#" data-value="9.00">09.00 AM</a></li>
236                                    <li><a class="dropdown-item " href="#" data-value="9.30">09.30 AM</a></li>
237                                    <li><a class="dropdown-item " href="#" data-value="10.00">10.00 AM</a></li>
238                                    <li><a class="dropdown-item " href="#" data-value="10.30">10.30 AM</a></li>
239                                    <li><a class="dropdown-item " href="#" data-value="11.00">11.00 AM</a></li>
240                                    <li><a class="dropdown-item " href="#" data-value="11.30">11.30 AM</a></li>
241                                    <li><a class="dropdown-item " href="#" data-value="12.00">00.00 AM</a></li>
242                                    <li><a class="dropdown-item " href="#" data-value="12.30">00.30 PM</a></li>
243                                    <li><a class="dropdown-item " href="#" data-value="13.00">01.00 PM</a></li>
244                                    <li><a class="dropdown-item " href="#" data-value="13.30">01.30 PM</a></li>
245                                    <li><a class="dropdown-item " href="#" data-value="14.00">02.00 PM</a></li>
246                                    <li><a class="dropdown-item " href="#" data-value="14.30">02.30 PM</a></li>
247                                    <li><a class="dropdown-item " href="#" data-value="15.00">03.00 PM</a></li>
248                                    <li><a class="dropdown-item " href="#" data-value="15.30">03.30 PM</a></li>
249                                    <li><a class="dropdown-item " href="#" data-value="16.00">04.00 PM</a></li>
250                                    <li><a class="dropdown-item " href="#" data-value="16.30">04.30 PM</a></li>
251                                    <li><a class="dropdown-item " href="#" data-value="17.00">05.00 PM</a></li>
252                                    <li><a class="dropdown-item " href="#" data-value="17.30">05.30 PM</a></li>
253                                    <li><a class="dropdown-item " href="#" data-value="18.00">06.00 PM</a></li>
254                                    <li><a class="dropdown-item " href="#" data-value="18.30">06.30 PM</a></li>
255                                    <li><a class="dropdown-item " href="#" data-value="19.00">07.00 PM</a></li>
256                                    <li><a class="dropdown-item " href="#" data-value="19.30">07.30 PM</a></li>
257                                    <li><a class="dropdown-item " href="#" data-value="20.00">08.00 PM</a></li>
258                                    <li><a class="dropdown-item " href="#" data-value="20.30">08.30 PM</a></li>
259                                    <li><a class="dropdown-item " href="#" data-value="21.00">09.00 PM</a></li>
260                                    <li><a class="dropdown-item " href="#" data-value="21.30">09.30 PM</a></li>
261                                    <li><a class="dropdown-item " href="#" data-value="22.00">10.00 PM</a></li>
262                                    <li><a class="dropdown-item " href="#" data-value="22.30">10.30 PM</a></li>
263                                    <li><a class="dropdown-item " href="#" data-value="23.00">11.00 PM</a></li>
264                                    <li><a class="dropdown-item " href="#" data-value="23.30">11.30 PM</a></li>
265                            </ul>
266        </div>
267        <div class="form-group field-restaurantreservationform-personcount">
268<input type="hidden" id="restaurantreservationform-personcount" class="form-control" name="RestaurantReservationForm[personCount]" data-btn-id="reservation-person">
269</div>        <div class="form-group field-restaurantreservationform-date required">
270<input type="hidden" id="restaurantreservationform-date" class="form-control" name="RestaurantReservationForm[date]" data-btn-id="reservation-date">
271</div>        <div class="form-group field-restaurantreservationform-time">
272<input type="hidden" id="restaurantreservationform-time" class="form-control" name="RestaurantReservationForm[time]" data-btn-id="reservation-time">
273</div>[{"id":86,"restaurant_id":1,"day":"Mon","open":"9.30","close":"14.30","created_at":"2022-02-22 10:56:15"},{"id":87,"restaurant_id":1,"day":"Tue","open":"3.00","close":"21.00","created_at":"2022-02-22 10:56:15"},{"id":88,"restaurant_id":1,"day":"Wed","open":"4.30","close":"6.30","created_at":"2022-02-22 10:56:15"},{"id":89,"restaurant_id":1,"day":"Thu","open":"2.30","close":"7.00","created_at":"2022-02-22 10:56:15"},{"id":90,"restaurant_id":1,"day":"Fri","open":"3.00","close":"22.00","created_at":"2022-02-22 10:56:15"},{"id":91,"restaurant_id":1,"day":"Sat","open":"1.30","close":"4.30","created_at":"2022-02-22 10:56:15"},{"id":92,"restaurant_id":1,"day":"Sun","open":"3.00","close":"20.30","created_at":"2022-02-22 10:56:15"}]
274[{"id":107,"restaurant_id":3,"day":"Mon","open":"1.30","close":"19.00","created_at":"2022-02-22 10:58:59"},{"id":108,"restaurant_id":3,"day":"Tue","open":"5.30","close":"8.00","created_at":"2022-02-22 10:58:59"},{"id":109,"restaurant_id":3,"day":"Wed","open":"3.00","close":"20.30","created_at":"2022-02-22 10:58:59"},{"id":110,"restaurant_id":3,"day":"Thu","open":"1.00","close":"12.30","created_at":"2022-02-22 10:58:59"},{"id":111,"restaurant_id":3,"day":"Fri","open":"2.30","close":"12.30","created_at":"2022-02-22 10:58:59"},{"id":112,"restaurant_id":3,"day":"Sat","open":"4.00","close":"22.00","created_at":"2022-02-22 10:58:59"},{"id":113,"restaurant_id":3,"day":"Sun","open":"4.00","close":"22.30","created_at":"2022-02-22 10:58:59"}]
275[{"id":"1","restaurant_id":"1","day":"Mon","open":"9.30","close":"14.30","created_at":"2022-02-15 05:00:57"}]
276function getWorkHours(json, restaurant_id) {
277    return json.filter(item => item.restaurant_id === restaurant_id);
278}
279function getWorkHoursForDay(json, restaurant_id, day) {
280    return getWorkHours(json, restaurant_id).filter(item => item.day === day);
281}
282let restaurantReserve = {
283        init: function () {
284            let _self = this;
285            
286            $('#reservation-date').datepicker({startDate: '+0d'}).on('changeDate', function (e) {
287                const arDate = e.date.toString().split(' ');
288                let input = $('[name="RestaurantReservationForm[date]"]');
289                input.val(arDate[3] + '-' + (e.date.getMonth() + 1) + '-' + arDate[2]);
290                _self.unSetError(input);
291                $('#reservation-date .js-value').text(arDate[2] + ' ' + arDate[1]);
292            });
293
294            $('[aria-labelledby="reservation-time"] li a').click(function () {
295                $(this).closest('ul').find('a').removeClass('active');
296                $(this).addClass('active');
297                let input = $('[name="RestaurantReservationForm[time]"]');
298                input.val($(this).data('value'));
299                _self.unSetError(input);
300                $('#reservation-time .js-value').text($(this).text());
301            });
302        },
303        setError: function (ob) {
304            $('#' + ob.data('btnId')).addClass('btn-error');
305        },
306        unSetError: function (ob) {
307            $('#' + ob.data('btnId')).removeClass('btn-error');
308        }
309    }
310
311    restaurantReserve.init();
312    
313    let json = [{"id":86,"restaurant_id":1,"day":"Mon","open":"9.30","close":"14.30","created_at":"2022-02-22 10:56:15"},{"id":87,"restaurant_id":1,"day":"Tue","open":"3.00","close":"21.00","created_at":"2022-02-22 10:56:15"},{"id":88,"restaurant_id":1,"day":"Wed","open":"4.30","close":"6.30","created_at":"2022-02-22 10:56:15"},{"id":89,"restaurant_id":1,"day":"Thu","open":"2.30","close":"7.00","created_at":"2022-02-22 10:56:15"},{"id":90,"restaurant_id":1,"day":"Fri","open":"3.00","close":"22.00","created_at":"2022-02-22 10:56:15"},/*{"id":91,"restaurant_id":1,"day":"Sat","open":"1.30","close":"4.30","created_at":"2022-02-22 10:56:15"},*/{"id":91,"restaurant_id":1,"day":"Sat","open":"0","close":"4.30","created_at":"2022-02-22 10:56:15"},{"id":92,"restaurant_id":1,"day":"Sun","open":"3.00","close":"20.30","created_at":"2022-02-22 10:56:15"}, {"id":107,"restaurant_id":3,"day":"Mon","open":"1.30","close":"19.00","created_at":"2022-02-22 10:58:59"},{"id":108,"restaurant_id":3,"day":"Tue","open":"5.30","close":"8.00","created_at":"2022-02-22 10:58:59"},{"id":109,"restaurant_id":3,"day":"Wed","open":"3.00","close":"20.30","created_at":"2022-02-22 10:58:59"},{"id":110,"restaurant_id":3,"day":"Thu","open":"1.00","close":"12.30","created_at":"2022-02-22 10:58:59"},{"id":111,"restaurant_id":3,"day":"Fri","open":"2.30","close":"12.30","created_at":"2022-02-22 10:58:59"},{"id":112,"restaurant_id":3,"day":"Sat","open":"4.00","close":"22.00","created_at":"2022-02-22 10:58:59"},{"id":113,"restaurant_id":3,"day":"Sun","open":"4.00","close":"22.30","created_at":"2022-02-22 10:58:59"}];
314
315    function getWorkHours(json, restaurant_id) {
316        return json.filter(item => item.restaurant_id == restaurant_id);
317    }
318
319    function getWorkHoursForDay(json, restaurant_id, day) {
320        return getWorkHours(json, restaurant_id).filter(item => item.day === day)[0];
321    }
322
323    function filterTimes() {
324        let restaurantID = document.getElementById("restaurantid").value;
325        let dayofweek = document.getElementById("dayofweek").value;
326        if ((["1", "3"].indexOf(restaurantID) >= 0) && ((["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"].indexOf(dayofweek)) >= 0)) {
327            let workHours = getWorkHoursForDay(json, restaurantID, dayofweek);
328            let items = document.querySelectorAll(".dropdown-menu.dropdown-menu-height-fixed li a");
329            for (let item of items) {
330                let itemValueParts = item.innerText.split(" ");
331                itemValue = parseFloat(itemValueParts[0]) + (((itemValueParts[1] === "PM") && (itemValueParts[0] !== "00.00")) ? 12 : 0);
332                item.parentNode.classList[((itemValue < parseFloat(workHours.open)) || (itemValue > parseFloat(workHours.close)) ? "add" : "remove")]("invisible");
333            }
334        }
335    }
1<?php
2
3namespace common\models;
4
5use yii\behaviors\TimestampBehavior;
6use yii\db\ActiveRecord;
7use yii\db\Expression;
8
9class WorkHours extends _source_WorkHours
10{
11    public const WEEK_DAY_MON = 'Mon';
12    public const WEEK_DAY_TUE = 'Tue';
13    public const WEEK_DAY_WED = 'Wed';
14    public const WEEK_DAY_THU = 'Thu';
15    public const WEEK_DAY_FRI = 'Fri';
16    public const WEEK_DAY_SAT = 'Sat';
17    public const WEEK_DAY_SUN = 'Sun';
18
19
20    /**
21     * {@inheritdoc}
22     */
23    public function behaviors(): array
24    {
25        return [
26            'timestamp' => [
27                'class'      => TimestampBehavior::class,
28                'attributes' => [
29                    ActiveRecord::EVENT_BEFORE_INSERT => ['created_at'],
30                ],
31                'value'      => new Expression('NOW()'),
32            ],
33        ];
34    }
35
36    public static function weekDays(): array
37    {
38        return [
39            self::WEEK_DAY_MON => 'Monday',
40            self::WEEK_DAY_TUE => 'Tuesday',
41            self::WEEK_DAY_WED => 'Wednesday',
42            self::WEEK_DAY_THU => 'Thursday',
43            self::WEEK_DAY_FRI => 'Friday',
44            self::WEEK_DAY_SAT => 'Saturday',
45            self::WEEK_DAY_SUN => 'Sunday',
46        ];
47    }
48
49    public static function getWeekDay(string $val): string
50    {
51        $ar = self::weekDays();
52
53        return $ar[$val] ?? $val;
54    }
55
56    public static function hoursList(): array
57    {
58        $list = [];
59        for ($i = 0; $i < 24; $i++) {
60            $A = 'AM';
61            $n = $i;
62            if ($i >= 12) {
63                $A = 'PM';
64                $n = $i - 12;
65            }
66
67            $n = $n < 10 ? '0' . $n : $n;
68            $_A = ($i === 12 ? 'AM' : $A);
69            $list[$i . '.00'] = $n . '.00 ' . ($i === 0 ? 'PM' : $_A);
70            $list[$i . '.30'] = $n . '.30 ' . $A;
71        }
72        return $list;
73    }
74}
75$this->registerJsFile('/js/restaurant-reserve.js', ['depends' => [JqueryAsset::class]]);
76$this->registerJs('restaurantReserve.init()');
77
78<a class="btn btn-fourth <?= $restaurantReservationForm->getErrors('date') ? 'btn-error' : '' ?>" id="reservation-date" data-date="<?= $restaurantReservationForm->getDate()
79                   ? $restaurantReservationForm->getDate()->format('m/d/Y') : '' ?>>">
80  <span class="icon br-calender"></span> <span class="js-value">
81                    <?= $restaurantReservationForm->date
82                        ? (new DateTime($restaurantReservationForm->date))->format('d M') : '-- ---' ?>
83                </span>
84</a>
85<a class="btn btn-fourth <?= $restaurantReservationForm->getErrors('time') ? 'btn-error' : '' ?>" id="reservation-time" role="button" data-bs-toggle="dropdown" aria-expanded="false">
86  <span class="icon br-clock"></span> <span class="js-value">
87                    <?= $restaurantReservationForm->time
88                        ? WorkHours::hoursList()[$restaurantReservationForm->time] : '-- : --' ?>
89                </span>
90</a>
91<ul class="dropdown-menu dropdown-menu-height-fixed" aria-labelledby="reservation-time">
92  <?php foreach (WorkHours::hoursList() as $k => $v) { ?>
93    <li>
94      <a class="dropdown-item <?= $restaurantReservationForm->time === $k ? 'active' : ''
95                        ?>" href="#" data-value="<?= $k ?>">
96        <?= $v ?>
97      </a>
98    </li>
99    <?php } ?>
100</ul>
101let restaurantReserve = {
102    init: function () {
103        let _self = this;
104
105        $('#reservation-date').datepicker({startDate: '+0d'}).on('changeDate', function (e) {
106            const arDate = e.date.toString().split(' ');
107            let input = $('[name="RestaurantReservationForm[date]"]');
108            input.val(arDate[3] + '-' + (e.date.getMonth() + 1) + '-' + arDate[2]);
109            _self.unSetError(input);
110            $('#reservation-date .js-value').text(arDate[2] + ' ' + arDate[1]);
111        });
112
113        $('[aria-labelledby="reservation-time"] li a').click(function () {
114            $(this).closest('ul').find('a').removeClass('active');
115            $(this).addClass('active');
116            let input = $('[name="RestaurantReservationForm[time]"]');
117            input.val($(this).data('value'));
118            _self.unSetError(input);
119            $('#reservation-time .js-value').text($(this).text());
120        });
121
122        $('[aria-labelledby="reservation-person"] li a').click(function () {
123            $(this).closest('ul').find('a').removeClass('active');
124            $(this).addClass('active');
125            let input = $('[name="RestaurantReservationForm[personCount]"]');
126            input.val($(this).data('value'));
127            _self.unSetError(input);
128            $('#reservation-person .js-value').text($(this).data('value'));
129        });
130    },
131    setError: function (ob) {
132        $('#' + ob.data('btnId')).addClass('btn-error');
133    },
134    unSetError: function (ob) {
135        $('#' + ob.data('btnId')).removeClass('btn-error');
136    }
137}
138$this->registerJs('restaurantReserve.init('. Json::encode($restaurant->workHours) .')');
139restaurantDate: function (e) {
140        ...
141    }
142let restaurantReserve = {
143    init: function () {
144        let _self = this;
145        
146        $('#reservation-date').datepicker({startDate: '+0d'}).on('changeDate', function (e) {
147            const arDate = e.date.toString().split(' ');
148            let input = $('[name="RestaurantReservationForm[date]"]');
149            input.val(arDate[3] + '-' + (e.date.getMonth() + 1) + '-' + arDate[2]);
150            _self.unSetError(input);
151            $('#reservation-date .js-value').text(arDate[2] + ' ' + arDate[1]);
152        });
153
154        $('[aria-labelledby="reservation-time"] li a').click(function () {
155            $(this).closest('ul').find('a').removeClass('active');
156            $(this).addClass('active');
157            let input = $('[name="RestaurantReservationForm[time]"]');
158            input.val($(this).data('value'));
159            _self.unSetError(input);
160            $('#reservation-time .js-value').text($(this).text());
161        });
162    },
163    setError: function (ob) {
164        $('#' + ob.data('btnId')).addClass('btn-error');
165    },
166    unSetError: function (ob) {
167        $('#' + ob.data('btnId')).removeClass('btn-error');
168    }
169}
170
171restaurantReserve.init();.btn {
172    border: none;
173    border-radius: 8px;
174    height: 40px;
175    padding: 10px 15px;
176    font-weight: 800;
177    font-size: 14px;
178    margin-right: 10px;
179    cursor: pointer;
180}
181
182.btn-fourth {
183    text-decoration: none;
184    background: #e3e5e8;
185    color: #747b8b;
186}
187
188ul.with-out > li:before, .dropdown-menu li:before, ul.whithout > li:before {display:none;}
189
190.dropdown-menu li {padding:0;}
191
192.dropdown-menu-height-fixed {max-height:200px;overflow-y:auto;}
193
194.dropdown-item.active, .dropdown-item:active {background:red;}
195
196.block-shadow {box-shadow:0 2px 8px 0 rgba(32,35,44,0.05);}
197.block-white {background:#fff;border-radius:8px;padding:20px;}<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
198<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.9.0/css/bootstrap-datepicker.min.css" rel="stylesheet">
199<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.9.0/js/bootstrap-datepicker.min.js"></script>
200
201<form id="reservation" action="/restaurants/123/" method="post">
202   <div class="block-shadow block-white mb-4">
203        <h5 class="fw-bold mb-3">Reserve a table</h5>
204        <div class="btn-s">
205            <a class="btn btn-fourth "
206               id="reservation-date"
207               data-date=">">
208                <span class="icon br-calender"></span> <span class="js-value">
209                    -- ---                </span>
210            </a>
211            <a class="btn btn-fourth "
212               id="reservation-time" role="button" data-bs-toggle="dropdown" aria-expanded="false">
213                <span class="icon br-clock"></span> <span class="js-value">
214                    -- : --                </span>
215            </a>
216            <ul class="dropdown-menu dropdown-menu-height-fixed" aria-labelledby="reservation-time">
217                                    <li><a class="dropdown-item " href="#" data-value="0.00">00.00 PM</a></li>
218                                    <li><a class="dropdown-item " href="#" data-value="0.30">00.30 AM</a></li>
219                                    <li><a class="dropdown-item " href="#" data-value="1.00">01.00 AM</a></li>
220                                    <li><a class="dropdown-item " href="#" data-value="1.30">01.30 AM</a></li>
221                                    <li><a class="dropdown-item " href="#" data-value="2.00">02.00 AM</a></li>
222                                    <li><a class="dropdown-item " href="#" data-value="2.30">02.30 AM</a></li>
223                                    <li><a class="dropdown-item " href="#" data-value="3.00">03.00 AM</a></li>
224                                    <li><a class="dropdown-item " href="#" data-value="3.30">03.30 AM</a></li>
225                                    <li><a class="dropdown-item " href="#" data-value="4.00">04.00 AM</a></li>
226                                    <li><a class="dropdown-item " href="#" data-value="4.30">04.30 AM</a></li>
227                                    <li><a class="dropdown-item " href="#" data-value="5.00">05.00 AM</a></li>
228                                    <li><a class="dropdown-item " href="#" data-value="5.30">05.30 AM</a></li>
229                                    <li><a class="dropdown-item " href="#" data-value="6.00">06.00 AM</a></li>
230                                    <li><a class="dropdown-item " href="#" data-value="6.30">06.30 AM</a></li>
231                                    <li><a class="dropdown-item " href="#" data-value="7.00">07.00 AM</a></li>
232                                    <li><a class="dropdown-item " href="#" data-value="7.30">07.30 AM</a></li>
233                                    <li><a class="dropdown-item " href="#" data-value="8.00">08.00 AM</a></li>
234                                    <li><a class="dropdown-item " href="#" data-value="8.30">08.30 AM</a></li>
235                                    <li><a class="dropdown-item " href="#" data-value="9.00">09.00 AM</a></li>
236                                    <li><a class="dropdown-item " href="#" data-value="9.30">09.30 AM</a></li>
237                                    <li><a class="dropdown-item " href="#" data-value="10.00">10.00 AM</a></li>
238                                    <li><a class="dropdown-item " href="#" data-value="10.30">10.30 AM</a></li>
239                                    <li><a class="dropdown-item " href="#" data-value="11.00">11.00 AM</a></li>
240                                    <li><a class="dropdown-item " href="#" data-value="11.30">11.30 AM</a></li>
241                                    <li><a class="dropdown-item " href="#" data-value="12.00">00.00 AM</a></li>
242                                    <li><a class="dropdown-item " href="#" data-value="12.30">00.30 PM</a></li>
243                                    <li><a class="dropdown-item " href="#" data-value="13.00">01.00 PM</a></li>
244                                    <li><a class="dropdown-item " href="#" data-value="13.30">01.30 PM</a></li>
245                                    <li><a class="dropdown-item " href="#" data-value="14.00">02.00 PM</a></li>
246                                    <li><a class="dropdown-item " href="#" data-value="14.30">02.30 PM</a></li>
247                                    <li><a class="dropdown-item " href="#" data-value="15.00">03.00 PM</a></li>
248                                    <li><a class="dropdown-item " href="#" data-value="15.30">03.30 PM</a></li>
249                                    <li><a class="dropdown-item " href="#" data-value="16.00">04.00 PM</a></li>
250                                    <li><a class="dropdown-item " href="#" data-value="16.30">04.30 PM</a></li>
251                                    <li><a class="dropdown-item " href="#" data-value="17.00">05.00 PM</a></li>
252                                    <li><a class="dropdown-item " href="#" data-value="17.30">05.30 PM</a></li>
253                                    <li><a class="dropdown-item " href="#" data-value="18.00">06.00 PM</a></li>
254                                    <li><a class="dropdown-item " href="#" data-value="18.30">06.30 PM</a></li>
255                                    <li><a class="dropdown-item " href="#" data-value="19.00">07.00 PM</a></li>
256                                    <li><a class="dropdown-item " href="#" data-value="19.30">07.30 PM</a></li>
257                                    <li><a class="dropdown-item " href="#" data-value="20.00">08.00 PM</a></li>
258                                    <li><a class="dropdown-item " href="#" data-value="20.30">08.30 PM</a></li>
259                                    <li><a class="dropdown-item " href="#" data-value="21.00">09.00 PM</a></li>
260                                    <li><a class="dropdown-item " href="#" data-value="21.30">09.30 PM</a></li>
261                                    <li><a class="dropdown-item " href="#" data-value="22.00">10.00 PM</a></li>
262                                    <li><a class="dropdown-item " href="#" data-value="22.30">10.30 PM</a></li>
263                                    <li><a class="dropdown-item " href="#" data-value="23.00">11.00 PM</a></li>
264                                    <li><a class="dropdown-item " href="#" data-value="23.30">11.30 PM</a></li>
265                            </ul>
266        </div>
267        <div class="form-group field-restaurantreservationform-personcount">
268<input type="hidden" id="restaurantreservationform-personcount" class="form-control" name="RestaurantReservationForm[personCount]" data-btn-id="reservation-person">
269</div>        <div class="form-group field-restaurantreservationform-date required">
270<input type="hidden" id="restaurantreservationform-date" class="form-control" name="RestaurantReservationForm[date]" data-btn-id="reservation-date">
271</div>        <div class="form-group field-restaurantreservationform-time">
272<input type="hidden" id="restaurantreservationform-time" class="form-control" name="RestaurantReservationForm[time]" data-btn-id="reservation-time">
273</div>[{"id":86,"restaurant_id":1,"day":"Mon","open":"9.30","close":"14.30","created_at":"2022-02-22 10:56:15"},{"id":87,"restaurant_id":1,"day":"Tue","open":"3.00","close":"21.00","created_at":"2022-02-22 10:56:15"},{"id":88,"restaurant_id":1,"day":"Wed","open":"4.30","close":"6.30","created_at":"2022-02-22 10:56:15"},{"id":89,"restaurant_id":1,"day":"Thu","open":"2.30","close":"7.00","created_at":"2022-02-22 10:56:15"},{"id":90,"restaurant_id":1,"day":"Fri","open":"3.00","close":"22.00","created_at":"2022-02-22 10:56:15"},{"id":91,"restaurant_id":1,"day":"Sat","open":"1.30","close":"4.30","created_at":"2022-02-22 10:56:15"},{"id":92,"restaurant_id":1,"day":"Sun","open":"3.00","close":"20.30","created_at":"2022-02-22 10:56:15"}]
274[{"id":107,"restaurant_id":3,"day":"Mon","open":"1.30","close":"19.00","created_at":"2022-02-22 10:58:59"},{"id":108,"restaurant_id":3,"day":"Tue","open":"5.30","close":"8.00","created_at":"2022-02-22 10:58:59"},{"id":109,"restaurant_id":3,"day":"Wed","open":"3.00","close":"20.30","created_at":"2022-02-22 10:58:59"},{"id":110,"restaurant_id":3,"day":"Thu","open":"1.00","close":"12.30","created_at":"2022-02-22 10:58:59"},{"id":111,"restaurant_id":3,"day":"Fri","open":"2.30","close":"12.30","created_at":"2022-02-22 10:58:59"},{"id":112,"restaurant_id":3,"day":"Sat","open":"4.00","close":"22.00","created_at":"2022-02-22 10:58:59"},{"id":113,"restaurant_id":3,"day":"Sun","open":"4.00","close":"22.30","created_at":"2022-02-22 10:58:59"}]
275[{"id":"1","restaurant_id":"1","day":"Mon","open":"9.30","close":"14.30","created_at":"2022-02-15 05:00:57"}]
276function getWorkHours(json, restaurant_id) {
277    return json.filter(item => item.restaurant_id === restaurant_id);
278}
279function getWorkHoursForDay(json, restaurant_id, day) {
280    return getWorkHours(json, restaurant_id).filter(item => item.day === day);
281}
282let restaurantReserve = {
283        init: function () {
284            let _self = this;
285            
286            $('#reservation-date').datepicker({startDate: '+0d'}).on('changeDate', function (e) {
287                const arDate = e.date.toString().split(' ');
288                let input = $('[name="RestaurantReservationForm[date]"]');
289                input.val(arDate[3] + '-' + (e.date.getMonth() + 1) + '-' + arDate[2]);
290                _self.unSetError(input);
291                $('#reservation-date .js-value').text(arDate[2] + ' ' + arDate[1]);
292            });
293
294            $('[aria-labelledby="reservation-time"] li a').click(function () {
295                $(this).closest('ul').find('a').removeClass('active');
296                $(this).addClass('active');
297                let input = $('[name="RestaurantReservationForm[time]"]');
298                input.val($(this).data('value'));
299                _self.unSetError(input);
300                $('#reservation-time .js-value').text($(this).text());
301            });
302        },
303        setError: function (ob) {
304            $('#' + ob.data('btnId')).addClass('btn-error');
305        },
306        unSetError: function (ob) {
307            $('#' + ob.data('btnId')).removeClass('btn-error');
308        }
309    }
310
311    restaurantReserve.init();
312    
313    let json = [{"id":86,"restaurant_id":1,"day":"Mon","open":"9.30","close":"14.30","created_at":"2022-02-22 10:56:15"},{"id":87,"restaurant_id":1,"day":"Tue","open":"3.00","close":"21.00","created_at":"2022-02-22 10:56:15"},{"id":88,"restaurant_id":1,"day":"Wed","open":"4.30","close":"6.30","created_at":"2022-02-22 10:56:15"},{"id":89,"restaurant_id":1,"day":"Thu","open":"2.30","close":"7.00","created_at":"2022-02-22 10:56:15"},{"id":90,"restaurant_id":1,"day":"Fri","open":"3.00","close":"22.00","created_at":"2022-02-22 10:56:15"},/*{"id":91,"restaurant_id":1,"day":"Sat","open":"1.30","close":"4.30","created_at":"2022-02-22 10:56:15"},*/{"id":91,"restaurant_id":1,"day":"Sat","open":"0","close":"4.30","created_at":"2022-02-22 10:56:15"},{"id":92,"restaurant_id":1,"day":"Sun","open":"3.00","close":"20.30","created_at":"2022-02-22 10:56:15"}, {"id":107,"restaurant_id":3,"day":"Mon","open":"1.30","close":"19.00","created_at":"2022-02-22 10:58:59"},{"id":108,"restaurant_id":3,"day":"Tue","open":"5.30","close":"8.00","created_at":"2022-02-22 10:58:59"},{"id":109,"restaurant_id":3,"day":"Wed","open":"3.00","close":"20.30","created_at":"2022-02-22 10:58:59"},{"id":110,"restaurant_id":3,"day":"Thu","open":"1.00","close":"12.30","created_at":"2022-02-22 10:58:59"},{"id":111,"restaurant_id":3,"day":"Fri","open":"2.30","close":"12.30","created_at":"2022-02-22 10:58:59"},{"id":112,"restaurant_id":3,"day":"Sat","open":"4.00","close":"22.00","created_at":"2022-02-22 10:58:59"},{"id":113,"restaurant_id":3,"day":"Sun","open":"4.00","close":"22.30","created_at":"2022-02-22 10:58:59"}];
314
315    function getWorkHours(json, restaurant_id) {
316        return json.filter(item => item.restaurant_id == restaurant_id);
317    }
318
319    function getWorkHoursForDay(json, restaurant_id, day) {
320        return getWorkHours(json, restaurant_id).filter(item => item.day === day)[0];
321    }
322
323    function filterTimes() {
324        let restaurantID = document.getElementById("restaurantid").value;
325        let dayofweek = document.getElementById("dayofweek").value;
326        if ((["1", "3"].indexOf(restaurantID) >= 0) && ((["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"].indexOf(dayofweek)) >= 0)) {
327            let workHours = getWorkHoursForDay(json, restaurantID, dayofweek);
328            let items = document.querySelectorAll(".dropdown-menu.dropdown-menu-height-fixed li a");
329            for (let item of items) {
330                let itemValueParts = item.innerText.split(" ");
331                itemValue = parseFloat(itemValueParts[0]) + (((itemValueParts[1] === "PM") && (itemValueParts[0] !== "00.00")) ? 12 : 0);
332                item.parentNode.classList[((itemValue < parseFloat(workHours.open)) || (itemValue > parseFloat(workHours.close)) ? "add" : "remove")]("invisible");
333            }
334        }
335    }.btn {
336        border: none;
337        border-radius: 8px;
338        height: 40px;
339        padding: 10px 15px;
340        font-weight: 800;
341        font-size: 14px;
342        margin-right: 10px;
343        cursor: pointer;
344    }
345
346    .btn-fourth {
347        text-decoration: none;
348        background: #e3e5e8;
349        color: #747b8b;
350    }
351    
352    .invisible {
353        display: none;
354    }
355
356    ul.with-out > li:before, .dropdown-menu li:before, ul.whithout > li:before {display:none;}
357
358    .dropdown-menu li {padding:0;}
359
360    .dropdown-menu-height-fixed {max-height:200px;overflow-y:auto;}
361
362    .dropdown-item.active, .dropdown-item:active {background:red;}
363
364    .block-shadow {box-shadow:0 2px 8px 0 rgba(32,35,44,0.05);}
365    .block-white {background:#fff;border-radius:8px;padding:20px;}
1<?php
2
3namespace common\models;
4
5use yii\behaviors\TimestampBehavior;
6use yii\db\ActiveRecord;
7use yii\db\Expression;
8
9class WorkHours extends _source_WorkHours
10{
11    public const WEEK_DAY_MON = 'Mon';
12    public const WEEK_DAY_TUE = 'Tue';
13    public const WEEK_DAY_WED = 'Wed';
14    public const WEEK_DAY_THU = 'Thu';
15    public const WEEK_DAY_FRI = 'Fri';
16    public const WEEK_DAY_SAT = 'Sat';
17    public const WEEK_DAY_SUN = 'Sun';
18
19
20    /**
21     * {@inheritdoc}
22     */
23    public function behaviors(): array
24    {
25        return [
26            'timestamp' => [
27                'class'      => TimestampBehavior::class,
28                'attributes' => [
29                    ActiveRecord::EVENT_BEFORE_INSERT => ['created_at'],
30                ],
31                'value'      => new Expression('NOW()'),
32            ],
33        ];
34    }
35
36    public static function weekDays(): array
37    {
38        return [
39            self::WEEK_DAY_MON => 'Monday',
40            self::WEEK_DAY_TUE => 'Tuesday',
41            self::WEEK_DAY_WED => 'Wednesday',
42            self::WEEK_DAY_THU => 'Thursday',
43            self::WEEK_DAY_FRI => 'Friday',
44            self::WEEK_DAY_SAT => 'Saturday',
45            self::WEEK_DAY_SUN => 'Sunday',
46        ];
47    }
48
49    public static function getWeekDay(string $val): string
50    {
51        $ar = self::weekDays();
52
53        return $ar[$val] ?? $val;
54    }
55
56    public static function hoursList(): array
57    {
58        $list = [];
59        for ($i = 0; $i < 24; $i++) {
60            $A = 'AM';
61            $n = $i;
62            if ($i >= 12) {
63                $A = 'PM';
64                $n = $i - 12;
65            }
66
67            $n = $n < 10 ? '0' . $n : $n;
68            $_A = ($i === 12 ? 'AM' : $A);
69            $list[$i . '.00'] = $n . '.00 ' . ($i === 0 ? 'PM' : $_A);
70            $list[$i . '.30'] = $n . '.30 ' . $A;
71        }
72        return $list;
73    }
74}
75$this->registerJsFile('/js/restaurant-reserve.js', ['depends' => [JqueryAsset::class]]);
76$this->registerJs('restaurantReserve.init()');
77
78<a class="btn btn-fourth <?= $restaurantReservationForm->getErrors('date') ? 'btn-error' : '' ?>" id="reservation-date" data-date="<?= $restaurantReservationForm->getDate()
79                   ? $restaurantReservationForm->getDate()->format('m/d/Y') : '' ?>>">
80  <span class="icon br-calender"></span> <span class="js-value">
81                    <?= $restaurantReservationForm->date
82                        ? (new DateTime($restaurantReservationForm->date))->format('d M') : '-- ---' ?>
83                </span>
84</a>
85<a class="btn btn-fourth <?= $restaurantReservationForm->getErrors('time') ? 'btn-error' : '' ?>" id="reservation-time" role="button" data-bs-toggle="dropdown" aria-expanded="false">
86  <span class="icon br-clock"></span> <span class="js-value">
87                    <?= $restaurantReservationForm->time
88                        ? WorkHours::hoursList()[$restaurantReservationForm->time] : '-- : --' ?>
89                </span>
90</a>
91<ul class="dropdown-menu dropdown-menu-height-fixed" aria-labelledby="reservation-time">
92  <?php foreach (WorkHours::hoursList() as $k => $v) { ?>
93    <li>
94      <a class="dropdown-item <?= $restaurantReservationForm->time === $k ? 'active' : ''
95                        ?>" href="#" data-value="<?= $k ?>">
96        <?= $v ?>
97      </a>
98    </li>
99    <?php } ?>
100</ul>
101let restaurantReserve = {
102    init: function () {
103        let _self = this;
104
105        $('#reservation-date').datepicker({startDate: '+0d'}).on('changeDate', function (e) {
106            const arDate = e.date.toString().split(' ');
107            let input = $('[name="RestaurantReservationForm[date]"]');
108            input.val(arDate[3] + '-' + (e.date.getMonth() + 1) + '-' + arDate[2]);
109            _self.unSetError(input);
110            $('#reservation-date .js-value').text(arDate[2] + ' ' + arDate[1]);
111        });
112
113        $('[aria-labelledby="reservation-time"] li a').click(function () {
114            $(this).closest('ul').find('a').removeClass('active');
115            $(this).addClass('active');
116            let input = $('[name="RestaurantReservationForm[time]"]');
117            input.val($(this).data('value'));
118            _self.unSetError(input);
119            $('#reservation-time .js-value').text($(this).text());
120        });
121
122        $('[aria-labelledby="reservation-person"] li a').click(function () {
123            $(this).closest('ul').find('a').removeClass('active');
124            $(this).addClass('active');
125            let input = $('[name="RestaurantReservationForm[personCount]"]');
126            input.val($(this).data('value'));
127            _self.unSetError(input);
128            $('#reservation-person .js-value').text($(this).data('value'));
129        });
130    },
131    setError: function (ob) {
132        $('#' + ob.data('btnId')).addClass('btn-error');
133    },
134    unSetError: function (ob) {
135        $('#' + ob.data('btnId')).removeClass('btn-error');
136    }
137}
138$this->registerJs('restaurantReserve.init('. Json::encode($restaurant->workHours) .')');
139restaurantDate: function (e) {
140        ...
141    }
142let restaurantReserve = {
143    init: function () {
144        let _self = this;
145        
146        $('#reservation-date').datepicker({startDate: '+0d'}).on('changeDate', function (e) {
147            const arDate = e.date.toString().split(' ');
148            let input = $('[name="RestaurantReservationForm[date]"]');
149            input.val(arDate[3] + '-' + (e.date.getMonth() + 1) + '-' + arDate[2]);
150            _self.unSetError(input);
151            $('#reservation-date .js-value').text(arDate[2] + ' ' + arDate[1]);
152        });
153
154        $('[aria-labelledby="reservation-time"] li a').click(function () {
155            $(this).closest('ul').find('a').removeClass('active');
156            $(this).addClass('active');
157            let input = $('[name="RestaurantReservationForm[time]"]');
158            input.val($(this).data('value'));
159            _self.unSetError(input);
160            $('#reservation-time .js-value').text($(this).text());
161        });
162    },
163    setError: function (ob) {
164        $('#' + ob.data('btnId')).addClass('btn-error');
165    },
166    unSetError: function (ob) {
167        $('#' + ob.data('btnId')).removeClass('btn-error');
168    }
169}
170
171restaurantReserve.init();.btn {
172    border: none;
173    border-radius: 8px;
174    height: 40px;
175    padding: 10px 15px;
176    font-weight: 800;
177    font-size: 14px;
178    margin-right: 10px;
179    cursor: pointer;
180}
181
182.btn-fourth {
183    text-decoration: none;
184    background: #e3e5e8;
185    color: #747b8b;
186}
187
188ul.with-out > li:before, .dropdown-menu li:before, ul.whithout > li:before {display:none;}
189
190.dropdown-menu li {padding:0;}
191
192.dropdown-menu-height-fixed {max-height:200px;overflow-y:auto;}
193
194.dropdown-item.active, .dropdown-item:active {background:red;}
195
196.block-shadow {box-shadow:0 2px 8px 0 rgba(32,35,44,0.05);}
197.block-white {background:#fff;border-radius:8px;padding:20px;}<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
198<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.9.0/css/bootstrap-datepicker.min.css" rel="stylesheet">
199<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.9.0/js/bootstrap-datepicker.min.js"></script>
200
201<form id="reservation" action="/restaurants/123/" method="post">
202   <div class="block-shadow block-white mb-4">
203        <h5 class="fw-bold mb-3">Reserve a table</h5>
204        <div class="btn-s">
205            <a class="btn btn-fourth "
206               id="reservation-date"
207               data-date=">">
208                <span class="icon br-calender"></span> <span class="js-value">
209                    -- ---                </span>
210            </a>
211            <a class="btn btn-fourth "
212               id="reservation-time" role="button" data-bs-toggle="dropdown" aria-expanded="false">
213                <span class="icon br-clock"></span> <span class="js-value">
214                    -- : --                </span>
215            </a>
216            <ul class="dropdown-menu dropdown-menu-height-fixed" aria-labelledby="reservation-time">
217                                    <li><a class="dropdown-item " href="#" data-value="0.00">00.00 PM</a></li>
218                                    <li><a class="dropdown-item " href="#" data-value="0.30">00.30 AM</a></li>
219                                    <li><a class="dropdown-item " href="#" data-value="1.00">01.00 AM</a></li>
220                                    <li><a class="dropdown-item " href="#" data-value="1.30">01.30 AM</a></li>
221                                    <li><a class="dropdown-item " href="#" data-value="2.00">02.00 AM</a></li>
222                                    <li><a class="dropdown-item " href="#" data-value="2.30">02.30 AM</a></li>
223                                    <li><a class="dropdown-item " href="#" data-value="3.00">03.00 AM</a></li>
224                                    <li><a class="dropdown-item " href="#" data-value="3.30">03.30 AM</a></li>
225                                    <li><a class="dropdown-item " href="#" data-value="4.00">04.00 AM</a></li>
226                                    <li><a class="dropdown-item " href="#" data-value="4.30">04.30 AM</a></li>
227                                    <li><a class="dropdown-item " href="#" data-value="5.00">05.00 AM</a></li>
228                                    <li><a class="dropdown-item " href="#" data-value="5.30">05.30 AM</a></li>
229                                    <li><a class="dropdown-item " href="#" data-value="6.00">06.00 AM</a></li>
230                                    <li><a class="dropdown-item " href="#" data-value="6.30">06.30 AM</a></li>
231                                    <li><a class="dropdown-item " href="#" data-value="7.00">07.00 AM</a></li>
232                                    <li><a class="dropdown-item " href="#" data-value="7.30">07.30 AM</a></li>
233                                    <li><a class="dropdown-item " href="#" data-value="8.00">08.00 AM</a></li>
234                                    <li><a class="dropdown-item " href="#" data-value="8.30">08.30 AM</a></li>
235                                    <li><a class="dropdown-item " href="#" data-value="9.00">09.00 AM</a></li>
236                                    <li><a class="dropdown-item " href="#" data-value="9.30">09.30 AM</a></li>
237                                    <li><a class="dropdown-item " href="#" data-value="10.00">10.00 AM</a></li>
238                                    <li><a class="dropdown-item " href="#" data-value="10.30">10.30 AM</a></li>
239                                    <li><a class="dropdown-item " href="#" data-value="11.00">11.00 AM</a></li>
240                                    <li><a class="dropdown-item " href="#" data-value="11.30">11.30 AM</a></li>
241                                    <li><a class="dropdown-item " href="#" data-value="12.00">00.00 AM</a></li>
242                                    <li><a class="dropdown-item " href="#" data-value="12.30">00.30 PM</a></li>
243                                    <li><a class="dropdown-item " href="#" data-value="13.00">01.00 PM</a></li>
244                                    <li><a class="dropdown-item " href="#" data-value="13.30">01.30 PM</a></li>
245                                    <li><a class="dropdown-item " href="#" data-value="14.00">02.00 PM</a></li>
246                                    <li><a class="dropdown-item " href="#" data-value="14.30">02.30 PM</a></li>
247                                    <li><a class="dropdown-item " href="#" data-value="15.00">03.00 PM</a></li>
248                                    <li><a class="dropdown-item " href="#" data-value="15.30">03.30 PM</a></li>
249                                    <li><a class="dropdown-item " href="#" data-value="16.00">04.00 PM</a></li>
250                                    <li><a class="dropdown-item " href="#" data-value="16.30">04.30 PM</a></li>
251                                    <li><a class="dropdown-item " href="#" data-value="17.00">05.00 PM</a></li>
252                                    <li><a class="dropdown-item " href="#" data-value="17.30">05.30 PM</a></li>
253                                    <li><a class="dropdown-item " href="#" data-value="18.00">06.00 PM</a></li>
254                                    <li><a class="dropdown-item " href="#" data-value="18.30">06.30 PM</a></li>
255                                    <li><a class="dropdown-item " href="#" data-value="19.00">07.00 PM</a></li>
256                                    <li><a class="dropdown-item " href="#" data-value="19.30">07.30 PM</a></li>
257                                    <li><a class="dropdown-item " href="#" data-value="20.00">08.00 PM</a></li>
258                                    <li><a class="dropdown-item " href="#" data-value="20.30">08.30 PM</a></li>
259                                    <li><a class="dropdown-item " href="#" data-value="21.00">09.00 PM</a></li>
260                                    <li><a class="dropdown-item " href="#" data-value="21.30">09.30 PM</a></li>
261                                    <li><a class="dropdown-item " href="#" data-value="22.00">10.00 PM</a></li>
262                                    <li><a class="dropdown-item " href="#" data-value="22.30">10.30 PM</a></li>
263                                    <li><a class="dropdown-item " href="#" data-value="23.00">11.00 PM</a></li>
264                                    <li><a class="dropdown-item " href="#" data-value="23.30">11.30 PM</a></li>
265                            </ul>
266        </div>
267        <div class="form-group field-restaurantreservationform-personcount">
268<input type="hidden" id="restaurantreservationform-personcount" class="form-control" name="RestaurantReservationForm[personCount]" data-btn-id="reservation-person">
269</div>        <div class="form-group field-restaurantreservationform-date required">
270<input type="hidden" id="restaurantreservationform-date" class="form-control" name="RestaurantReservationForm[date]" data-btn-id="reservation-date">
271</div>        <div class="form-group field-restaurantreservationform-time">
272<input type="hidden" id="restaurantreservationform-time" class="form-control" name="RestaurantReservationForm[time]" data-btn-id="reservation-time">
273</div>[{"id":86,"restaurant_id":1,"day":"Mon","open":"9.30","close":"14.30","created_at":"2022-02-22 10:56:15"},{"id":87,"restaurant_id":1,"day":"Tue","open":"3.00","close":"21.00","created_at":"2022-02-22 10:56:15"},{"id":88,"restaurant_id":1,"day":"Wed","open":"4.30","close":"6.30","created_at":"2022-02-22 10:56:15"},{"id":89,"restaurant_id":1,"day":"Thu","open":"2.30","close":"7.00","created_at":"2022-02-22 10:56:15"},{"id":90,"restaurant_id":1,"day":"Fri","open":"3.00","close":"22.00","created_at":"2022-02-22 10:56:15"},{"id":91,"restaurant_id":1,"day":"Sat","open":"1.30","close":"4.30","created_at":"2022-02-22 10:56:15"},{"id":92,"restaurant_id":1,"day":"Sun","open":"3.00","close":"20.30","created_at":"2022-02-22 10:56:15"}]
274[{"id":107,"restaurant_id":3,"day":"Mon","open":"1.30","close":"19.00","created_at":"2022-02-22 10:58:59"},{"id":108,"restaurant_id":3,"day":"Tue","open":"5.30","close":"8.00","created_at":"2022-02-22 10:58:59"},{"id":109,"restaurant_id":3,"day":"Wed","open":"3.00","close":"20.30","created_at":"2022-02-22 10:58:59"},{"id":110,"restaurant_id":3,"day":"Thu","open":"1.00","close":"12.30","created_at":"2022-02-22 10:58:59"},{"id":111,"restaurant_id":3,"day":"Fri","open":"2.30","close":"12.30","created_at":"2022-02-22 10:58:59"},{"id":112,"restaurant_id":3,"day":"Sat","open":"4.00","close":"22.00","created_at":"2022-02-22 10:58:59"},{"id":113,"restaurant_id":3,"day":"Sun","open":"4.00","close":"22.30","created_at":"2022-02-22 10:58:59"}]
275[{"id":"1","restaurant_id":"1","day":"Mon","open":"9.30","close":"14.30","created_at":"2022-02-15 05:00:57"}]
276function getWorkHours(json, restaurant_id) {
277    return json.filter(item => item.restaurant_id === restaurant_id);
278}
279function getWorkHoursForDay(json, restaurant_id, day) {
280    return getWorkHours(json, restaurant_id).filter(item => item.day === day);
281}
282let restaurantReserve = {
283        init: function () {
284            let _self = this;
285            
286            $('#reservation-date').datepicker({startDate: '+0d'}).on('changeDate', function (e) {
287                const arDate = e.date.toString().split(' ');
288                let input = $('[name="RestaurantReservationForm[date]"]');
289                input.val(arDate[3] + '-' + (e.date.getMonth() + 1) + '-' + arDate[2]);
290                _self.unSetError(input);
291                $('#reservation-date .js-value').text(arDate[2] + ' ' + arDate[1]);
292            });
293
294            $('[aria-labelledby="reservation-time"] li a').click(function () {
295                $(this).closest('ul').find('a').removeClass('active');
296                $(this).addClass('active');
297                let input = $('[name="RestaurantReservationForm[time]"]');
298                input.val($(this).data('value'));
299                _self.unSetError(input);
300                $('#reservation-time .js-value').text($(this).text());
301            });
302        },
303        setError: function (ob) {
304            $('#' + ob.data('btnId')).addClass('btn-error');
305        },
306        unSetError: function (ob) {
307            $('#' + ob.data('btnId')).removeClass('btn-error');
308        }
309    }
310
311    restaurantReserve.init();
312    
313    let json = [{"id":86,"restaurant_id":1,"day":"Mon","open":"9.30","close":"14.30","created_at":"2022-02-22 10:56:15"},{"id":87,"restaurant_id":1,"day":"Tue","open":"3.00","close":"21.00","created_at":"2022-02-22 10:56:15"},{"id":88,"restaurant_id":1,"day":"Wed","open":"4.30","close":"6.30","created_at":"2022-02-22 10:56:15"},{"id":89,"restaurant_id":1,"day":"Thu","open":"2.30","close":"7.00","created_at":"2022-02-22 10:56:15"},{"id":90,"restaurant_id":1,"day":"Fri","open":"3.00","close":"22.00","created_at":"2022-02-22 10:56:15"},/*{"id":91,"restaurant_id":1,"day":"Sat","open":"1.30","close":"4.30","created_at":"2022-02-22 10:56:15"},*/{"id":91,"restaurant_id":1,"day":"Sat","open":"0","close":"4.30","created_at":"2022-02-22 10:56:15"},{"id":92,"restaurant_id":1,"day":"Sun","open":"3.00","close":"20.30","created_at":"2022-02-22 10:56:15"}, {"id":107,"restaurant_id":3,"day":"Mon","open":"1.30","close":"19.00","created_at":"2022-02-22 10:58:59"},{"id":108,"restaurant_id":3,"day":"Tue","open":"5.30","close":"8.00","created_at":"2022-02-22 10:58:59"},{"id":109,"restaurant_id":3,"day":"Wed","open":"3.00","close":"20.30","created_at":"2022-02-22 10:58:59"},{"id":110,"restaurant_id":3,"day":"Thu","open":"1.00","close":"12.30","created_at":"2022-02-22 10:58:59"},{"id":111,"restaurant_id":3,"day":"Fri","open":"2.30","close":"12.30","created_at":"2022-02-22 10:58:59"},{"id":112,"restaurant_id":3,"day":"Sat","open":"4.00","close":"22.00","created_at":"2022-02-22 10:58:59"},{"id":113,"restaurant_id":3,"day":"Sun","open":"4.00","close":"22.30","created_at":"2022-02-22 10:58:59"}];
314
315    function getWorkHours(json, restaurant_id) {
316        return json.filter(item => item.restaurant_id == restaurant_id);
317    }
318
319    function getWorkHoursForDay(json, restaurant_id, day) {
320        return getWorkHours(json, restaurant_id).filter(item => item.day === day)[0];
321    }
322
323    function filterTimes() {
324        let restaurantID = document.getElementById("restaurantid").value;
325        let dayofweek = document.getElementById("dayofweek").value;
326        if ((["1", "3"].indexOf(restaurantID) >= 0) && ((["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"].indexOf(dayofweek)) >= 0)) {
327            let workHours = getWorkHoursForDay(json, restaurantID, dayofweek);
328            let items = document.querySelectorAll(".dropdown-menu.dropdown-menu-height-fixed li a");
329            for (let item of items) {
330                let itemValueParts = item.innerText.split(" ");
331                itemValue = parseFloat(itemValueParts[0]) + (((itemValueParts[1] === "PM") && (itemValueParts[0] !== "00.00")) ? 12 : 0);
332                item.parentNode.classList[((itemValue < parseFloat(workHours.open)) || (itemValue > parseFloat(workHours.close)) ? "add" : "remove")]("invisible");
333            }
334        }
335    }.btn {
336        border: none;
337        border-radius: 8px;
338        height: 40px;
339        padding: 10px 15px;
340        font-weight: 800;
341        font-size: 14px;
342        margin-right: 10px;
343        cursor: pointer;
344    }
345
346    .btn-fourth {
347        text-decoration: none;
348        background: #e3e5e8;
349        color: #747b8b;
350    }
351    
352    .invisible {
353        display: none;
354    }
355
356    ul.with-out > li:before, .dropdown-menu li:before, ul.whithout > li:before {display:none;}
357
358    .dropdown-menu li {padding:0;}
359
360    .dropdown-menu-height-fixed {max-height:200px;overflow-y:auto;}
361
362    .dropdown-item.active, .dropdown-item:active {background:red;}
363
364    .block-shadow {box-shadow:0 2px 8px 0 rgba(32,35,44,0.05);}
365    .block-white {background:#fff;border-radius:8px;padding:20px;}<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
366    <link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.9.0/css/bootstrap-datepicker.min.css" rel="stylesheet">
367    <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.9.0/js/bootstrap-datepicker.min.js"></script>
368
369    <form id="reservation" action="/restaurants/123/" method="post">
370       <div class="block-shadow block-white mb-4">
371            <h5 class="fw-bold mb-3">Reserve a table</h5>
372            <div class="btn-s">
373                <a class="btn btn-fourth "
374                   id="reservation-date"
375                   data-date=">">
376                    <span class="icon br-calender"></span> <span class="js-value">
377                        -- ---                </span>
378                </a>
379                <a class="btn btn-fourth "
380                   id="reservation-time" role="button" data-bs-toggle="dropdown" aria-expanded="false">
381                    <span class="icon br-clock"></span> <span class="js-value">
382                        -- : --                </span>
383                </a>
384                <select id="restaurantid" onchange="filterTimes()">
385                    <option>Please Select Restaurant</option>
386                    <option value="1">Pizza Mia</option>
387                    <option value="3">Burger Land</option>
388                </select>
389                <select id="dayofweek" onchange="filterTimes()">
390                    <option>Please Select Day</option>
391                    <option value="Mon">Mon</option>
392                    <option value="Tue">Tue</option>
393                    <option value="Wed">Wed</option>
394                    <option value="Thu">Thu</option>
395                    <option value="Fri">Fri</option>
396                    <option value="Sat">Sat</option>
397                    <option value="Sun">Sun</option>
398                </select>
399                <ul class="dropdown-menu dropdown-menu-height-fixed" aria-labelledby="reservation-time">
400                                        <li><a class="dropdown-item " href="#" data-value="0.00">00.00 PM</a></li>
401                                        <li><a class="dropdown-item " href="#" data-value="0.30">00.30 AM</a></li>
402                                        <li><a class="dropdown-item " href="#" data-value="1.00">01.00 AM</a></li>
403                                        <li><a class="dropdown-item " href="#" data-value="1.30">01.30 AM</a></li>
404                                        <li><a class="dropdown-item " href="#" data-value="2.00">02.00 AM</a></li>
405                                        <li><a class="dropdown-item " href="#" data-value="2.30">02.30 AM</a></li>
406                                        <li><a class="dropdown-item " href="#" data-value="3.00">03.00 AM</a></li>
407                                        <li><a class="dropdown-item " href="#" data-value="3.30">03.30 AM</a></li>
408                                        <li><a class="dropdown-item " href="#" data-value="4.00">04.00 AM</a></li>
409                                        <li><a class="dropdown-item " href="#" data-value="4.30">04.30 AM</a></li>
410                                        <li><a class="dropdown-item " href="#" data-value="5.00">05.00 AM</a></li>
411                                        <li><a class="dropdown-item " href="#" data-value="5.30">05.30 AM</a></li>
412                                        <li><a class="dropdown-item " href="#" data-value="6.00">06.00 AM</a></li>
413                                        <li><a class="dropdown-item " href="#" data-value="6.30">06.30 AM</a></li>
414                                        <li><a class="dropdown-item " href="#" data-value="7.00">07.00 AM</a></li>
415                                        <li><a class="dropdown-item " href="#" data-value="7.30">07.30 AM</a></li>
416                                        <li><a class="dropdown-item " href="#" data-value="8.00">08.00 AM</a></li>
417                                        <li><a class="dropdown-item " href="#" data-value="8.30">08.30 AM</a></li>
418                                        <li><a class="dropdown-item " href="#" data-value="9.00">09.00 AM</a></li>
419                                        <li><a class="dropdown-item " href="#" data-value="9.30">09.30 AM</a></li>
420                                        <li><a class="dropdown-item " href="#" data-value="10.00">10.00 AM</a></li>
421                                        <li><a class="dropdown-item " href="#" data-value="10.30">10.30 AM</a></li>
422                                        <li><a class="dropdown-item " href="#" data-value="11.00">11.00 AM</a></li>
423                                        <li><a class="dropdown-item " href="#" data-value="11.30">11.30 AM</a></li>
424                                        <li><a class="dropdown-item " href="#" data-value="12.00">00.00 AM</a></li>
425                                        <li><a class="dropdown-item " href="#" data-value="12.30">00.30 PM</a></li>
426                                        <li><a class="dropdown-item " href="#" data-value="13.00">01.00 PM</a></li>
427                                        <li><a class="dropdown-item " href="#" data-value="13.30">01.30 PM</a></li>
428                                        <li><a class="dropdown-item " href="#" data-value="14.00">02.00 PM</a></li>
429                                        <li><a class="dropdown-item " href="#" data-value="14.30">02.30 PM</a></li>
430                                        <li><a class="dropdown-item " href="#" data-value="15.00">03.00 PM</a></li>
431                                        <li><a class="dropdown-item " href="#" data-value="15.30">03.30 PM</a></li>
432                                        <li><a class="dropdown-item " href="#" data-value="16.00">04.00 PM</a></li>
433                                        <li><a class="dropdown-item " href="#" data-value="16.30">04.30 PM</a></li>
434                                        <li><a class="dropdown-item " href="#" data-value="17.00">05.00 PM</a></li>
435                                        <li><a class="dropdown-item " href="#" data-value="17.30">05.30 PM</a></li>
436                                        <li><a class="dropdown-item " href="#" data-value="18.00">06.00 PM</a></li>
437                                        <li><a class="dropdown-item " href="#" data-value="18.30">06.30 PM</a></li>
438                                        <li><a class="dropdown-item " href="#" data-value="19.00">07.00 PM</a></li>
439                                        <li><a class="dropdown-item " href="#" data-value="19.30">07.30 PM</a></li>
440                                        <li><a class="dropdown-item " href="#" data-value="20.00">08.00 PM</a></li>
441                                        <li><a class="dropdown-item " href="#" data-value="20.30">08.30 PM</a></li>
442                                        <li><a class="dropdown-item " href="#" data-value="21.00">09.00 PM</a></li>
443                                        <li><a class="dropdown-item " href="#" data-value="21.30">09.30 PM</a></li>
444                                        <li><a class="dropdown-item " href="#" data-value="22.00">10.00 PM</a></li>
445                                        <li><a class="dropdown-item " href="#" data-value="22.30">10.30 PM</a></li>
446                                        <li><a class="dropdown-item " href="#" data-value="23.00">11.00 PM</a></li>
447                                        <li><a class="dropdown-item " href="#" data-value="23.30">11.30 PM</a></li>
448                                </ul>
449            </div>
450            <div class="form-group field-restaurantreservationform-personcount">
451    <input type="hidden" id="restaurantreservationform-personcount" class="form-control" name="RestaurantReservationForm[personCount]" data-btn-id="reservation-person">
452    </div>        <div class="form-group field-restaurantreservationform-date required">
453    <input type="hidden" id="restaurantreservationform-date" class="form-control" name="RestaurantReservationForm[date]" data-btn-id="reservation-date">
454    </div>        <div class="form-group field-restaurantreservationform-time">
455    <input type="hidden" id="restaurantreservationform-time" class="form-control" name="RestaurantReservationForm[time]" data-btn-id="reservation-time">
456    </div>

Source https://stackoverflow.com/questions/71126946

QUESTION

Module not found: Error: Can't resolve 'date-fns/addDays' in 'C:\Users\

Asked 2022-Feb-08 at 17:19

I want to use Date picker from MUI but I get this error and I don't know what exactly is wrong. here is my code:

1import TextField from "@mui/material/TextField";
2import DatePicker from "@mui/lab/DatePicker";
3import AdapterDateFns from "@mui/lab/AdapterDateFns";
4import LocalizationProvider from "@mui/lab/LocalizationProvider";
5
6const ExpenseForm = () => {
7  return (
8    <Box component="form" noValidate autoComplete="off">
9      <LocalizationProvider dateAdapter={AdapterDateFns}>
10        <DatePicker
11          label="Basic example"
12          onChange={(newValue) => {}}
13          renderInput={(params) => <TextField {...params} />}
14        />
15      </LocalizationProvider>
16    </Box>
17  );
18};
19
20export default ExpenseForm;
21

and my package.json:

1import TextField from "@mui/material/TextField";
2import DatePicker from "@mui/lab/DatePicker";
3import AdapterDateFns from "@mui/lab/AdapterDateFns";
4import LocalizationProvider from "@mui/lab/LocalizationProvider";
5
6const ExpenseForm = () => {
7  return (
8    <Box component="form" noValidate autoComplete="off">
9      <LocalizationProvider dateAdapter={AdapterDateFns}>
10        <DatePicker
11          label="Basic example"
12          onChange={(newValue) => {}}
13          renderInput={(params) => <TextField {...params} />}
14        />
15      </LocalizationProvider>
16    </Box>
17  );
18};
19
20export default ExpenseForm;
21"dependencies": {
22    "@date-io/date-fns": "^2.13.1",
23    "@emotion/react": "^11.7.1",
24    "@emotion/styled": "^11.6.0",
25    "@mui/icons-material": "^5.3.1",
26    "@mui/lab": "^5.0.0-alpha.68",
27    "@mui/material": "^5.4.0",
28    "@testing-library/jest-dom": "^5.16.1",
29    "@testing-library/react": "^12.1.2",
30    "@testing-library/user-event": "^13.5.0",
31    "react": "^17.0.2",
32    "react-dom": "^17.0.2",
33    "react-scripts": "5.0.0",
34    "web-vitals": "^2.1.4"
35  },
36

but everytime I get these errors:

1import TextField from "@mui/material/TextField";
2import DatePicker from "@mui/lab/DatePicker";
3import AdapterDateFns from "@mui/lab/AdapterDateFns";
4import LocalizationProvider from "@mui/lab/LocalizationProvider";
5
6const ExpenseForm = () => {
7  return (
8    <Box component="form" noValidate autoComplete="off">
9      <LocalizationProvider dateAdapter={AdapterDateFns}>
10        <DatePicker
11          label="Basic example"
12          onChange={(newValue) => {}}
13          renderInput={(params) => <TextField {...params} />}
14        />
15      </LocalizationProvider>
16    </Box>
17  );
18};
19
20export default ExpenseForm;
21"dependencies": {
22    "@date-io/date-fns": "^2.13.1",
23    "@emotion/react": "^11.7.1",
24    "@emotion/styled": "^11.6.0",
25    "@mui/icons-material": "^5.3.1",
26    "@mui/lab": "^5.0.0-alpha.68",
27    "@mui/material": "^5.4.0",
28    "@testing-library/jest-dom": "^5.16.1",
29    "@testing-library/react": "^12.1.2",
30    "@testing-library/user-event": "^13.5.0",
31    "react": "^17.0.2",
32    "react-dom": "^17.0.2",
33    "react-scripts": "5.0.0",
34    "web-vitals": "^2.1.4"
35  },
36Compiled with problems:
37
38ERROR in ./node_modules/@date-io/date-fns/build/index.esm.js 1:0-39
39
40Module not found: Error: Can't resolve 'date-fns/addDays' in 'C:\Users\Amir\Desktop\React\React-apps\expense-tracker\node_modules\@date-io\date-fns\build'
41
42
43ERROR in ./node_modules/@date-io/date-fns/build/index.esm.js 2:0-45
44
45Module not found: Error: Can't resolve 'date-fns/addSeconds' in 'C:\Users\Amir\Desktop\React\React-apps\expense-tracker\node_modules\@date-io\date-fns\build'
46
47
48ERROR in ./node_modules/@date-io/date-fns/build/index.esm.js 3:0-45
49
50Module not found: Error: Can't resolve 'date-fns/addMinutes' in 'C:\Users\Amir\Desktop\React\React-apps\expense-tracker\node_modules\@date-io\date-fns\build'
51
52
53ERROR in ./node_modules/@date-io/date-fns/build/index.esm.js 4:0-41
54
55Module not found: Error: Can't resolve 'date-fns/addHours' in 'C:\Users\Amir\Desktop\React\React-apps\expense-tracker\node_modules\@date-io\date-fns\build'
56
57
58ERROR in ./node_modules/@date-io/date-fns/build/index.esm.js 5:0-41
59
60Module not found: Error: Can't resolve 'date-fns/addWeeks' in 'C:\Users\Amir\Desktop\React\React-apps\expense-tracker\node_modules\@date-io\date-fns\build'
61
62
63ERROR in ./node_modules/@date-io/date-fns/build/index.esm.js 6:0-43
64
65Module not found: Error: Can't resolve 'date-fns/addMonths' in 'C:\Users\Amir\Desktop\React\React-apps\expense-tracker\node_modules\@date-io\date-fns\build'
66
67
68ERROR in ./node_modules/@date-io/date-fns/build/index.esm.js 7:0-41
69
70Module not found: Error: Can't resolve 'date-fns/addYears' in 'C:\Users\Amir\Desktop\React\React-apps\expense-tracker\node_modules\@date-io\date-fns\build'
71
72
73ERROR in ./node_modules/@date-io/date-fns/build/index.esm.js 8:0-59
74
75Module not found: Error: Can't resolve 'date-fns/differenceInYears' in 'C:\Users\Amir\Desktop\React\React-apps\expense-tracker\node_modules\@date-io\date-fns\build'
76
77
78ERROR in ./node_modules/@date-io/date-fns/build/index.esm.js 9:0-65
79
80Module not found: Error: Can't resolve 'date-fns/differenceInQuarters' in 'C:\Users\Amir\Desktop\React\React-apps\expense-tracker\node_modules\@date-io\date-fns\build'
81
82
83ERROR in ./node_modules/@date-io/date-fns/build/index.esm.js 10:0-61
84
85Module not found: Error: Can't resolve 'date-fns/differenceInMonths' in 'C:\Users\Amir\Desktop\React\React-apps\expense-tracker\node_modules\@date-io\date-fns\build'
86
87
88ERROR in ./node_modules/@date-io/date-fns/build/index.esm.js 11:0-59
89
90Module not found: Error: Can't resolve 'date-fns/differenceInWeeks' in 'C:\Users\Amir\Desktop\React\React-apps\expense-tracker\node_modules\@date-io\date-fns\build'
91
92
93ERROR in ./node_modules/@date-io/date-fns/build/index.esm.js 12:0-57
94
95Module not found: Error: Can't resolve 'date-fns/differenceInDays' in 'C:\Users\Amir\Desktop\React\React-apps\expense-tracker\node_modules\@date-io\date-fns\build'
96
97
98ERROR in ./node_modules/@date-io/date-fns/build/index.esm.js 13:0-59
99
100Module not found: Error: Can't resolve 'date-fns/differenceInHours' in 'C:\Users\Amir\Desktop\React\React-apps\expense-tracker\node_modules\@date-io\date-fns\build'
101
102
103ERROR in ./node_modules/@date-io/date-fns/build/index.esm.js 14:0-63
104
105Module not found: Error: Can't resolve 'date-fns/differenceInMinutes' in 'C:\Users\Amir\Desktop\React\React-apps\expense-tracker\node_modules\@date-io\date-fns\build'
106
107
108ERROR in ./node_modules/@date-io/date-fns/build/index.esm.js 15:0-63
109
110Module not found: Error: Can't resolve 'date-fns/differenceInSeconds' in 'C:\Users\Amir\Desktop\React\React-apps\expense-tracker\node_modules\@date-io\date-fns\build'
111
112
113ERROR in ./node_modules/@date-io/date-fns/build/index.esm.js 16:0-73
114
115Module not found: Error: Can't resolve 'date-fns/differenceInMilliseconds' in 'C:\Users\Amir\Desktop\React\React-apps\expense-tracker\node_modules\@date-io\date-fns\build'
116
117
118ERROR in ./node_modules/@date-io/date-fns/build/index.esm.js 17:0-59
119
120Module not found: Error: Can't resolve 'date-fns/eachDayOfInterval' in 'C:\Users\Amir\Desktop\React\React-apps\expense-tracker\node_modules\@date-io\date-fns\build'
121
122
123ERROR in ./node_modules/@date-io/date-fns/build/index.esm.js 18:0-41
124
125Module not found: Error: Can't resolve 'date-fns/endOfDay' in 'C:\Users\Amir\Desktop\React\React-apps\expense-tracker\node_modules\@date-io\date-fns\build'
126
127
128ERROR in ./node_modules/@date-io/date-fns/build/index.esm.js 19:0-43
129
130Module not found: Error: Can't resolve 'date-fns/endOfWeek' in 'C:\Users\Amir\Desktop\React\React-apps\expense-tracker\node_modules\@date-io\date-fns\build'
131
132
133ERROR in ./node_modules/@date-io/date-fns/build/index.esm.js 20:0-43
134
135Module not found: Error: Can't resolve 'date-fns/endOfYear' in 'C:\Users\Amir\Desktop\React\React-apps\expense-tracker\node_modules\@date-io\date-fns\build'
136
137
138ERROR in ./node_modules/@date-io/date-fns/build/index.esm.js 21:0-37
139
140Module not found: Error: Can't resolve 'date-fns/format' in 'C:\Users\Amir\Desktop\React\React-apps\expense-tracker\node_modules\@date-io\date-fns\build'
141
142
143ERROR in ./node_modules/@date-io/date-fns/build/index.esm.js 22:0-41
144
145Module not found: Error: Can't resolve 'date-fns/getHours' in 'C:\Users\Amir\Desktop\React\React-apps\expense-tracker\node_modules\@date-io\date-fns\build'
146
147
148ERROR in ./node_modules/@date-io/date-fns/build/index.esm.js 23:0-45
149
150Module not found: Error: Can't resolve 'date-fns/getSeconds' in 'C:\Users\Amir\Desktop\React\React-apps\expense-tracker\node_modules\@date-io\date-fns\build'
151
152
153ERROR in ./node_modules/@date-io/date-fns/build/index.esm.js 24:0-39
154
155Module not found: Error: Can't resolve 'date-fns/getYear' in 'C:\Users\Amir\Desktop\React\React-apps\expense-tracker\node_modules\@date-io\date-fns\build'
156
157
158ERROR in ./node_modules/@date-io/date-fns/build/index.esm.js 25:0-39
159
160Module not found: Error: Can't resolve 'date-fns/isAfter' in 'C:\Users\Amir\Desktop\React\React-apps\expense-tracker\node_modules\@date-io\date-fns\build'
161
162
163ERROR in ./node_modules/@date-io/date-fns/build/index.esm.js 26:0-41
164
165Module not found: Error: Can't resolve 'date-fns/isBefore' in 'C:\Users\Amir\Desktop\React\React-apps\expense-tracker\node_modules\@date-io\date-fns\build'
166
167
168ERROR in ./node_modules/@date-io/date-fns/build/index.esm.js 27:0-39
169
170Module not found: Error: Can't resolve 'date-fns/isEqual' in 'C:\Users\Amir\Desktop\React\React-apps\expense-tracker\node_modules\@date-io\date-fns\build'
171
172
173ERROR in ./node_modules/@date-io/date-fns/build/index.esm.js 28:0-43
174
175Module not found: Error: Can't resolve 'date-fns/isSameDay' in 'C:\Users\Amir\Desktop\React\React-apps\expense-tracker\node_modules\@date-io\date-fns\build'
176
177
178ERROR in ./node_modules/@date-io/date-fns/build/index.esm.js 29:0-45
179
180Module not found: Error: Can't resolve 'date-fns/isSameYear' in 'C:\Users\Amir\Desktop\React\React-apps\expense-tracker\node_modules\@date-io\date-fns\build'
181
182
183ERROR in ./node_modules/@date-io/date-fns/build/index.esm.js 30:0-47
184
185Module not found: Error: Can't resolve 'date-fns/isSameMonth' in 'C:\Users\Amir\Desktop\React\React-apps\expense-tracker\node_modules\@date-io\date-fns\build'
186
187
188ERROR in ./node_modules/@date-io/date-fns/build/index.esm.js 31:0-45
189
190Module not found: Error: Can't resolve 'date-fns/isSameHour' in 'C:\Users\Amir\Desktop\React\React-apps\expense-tracker\node_modules\@date-io\date-fns\build'
191
192
193ERROR in ./node_modules/@date-io/date-fns/build/index.esm.js 32:0-39
194
195Module not found: Error: Can't resolve 'date-fns/isValid' in 'C:\Users\Amir\Desktop\React\React-apps\expense-tracker\node_modules\@date-io\date-fns\build'
196
197
198ERROR in ./node_modules/@date-io/date-fns/build/index.esm.js 33:0-42
199
200Module not found: Error: Can't resolve 'date-fns/parse' in 'C:\Users\Amir\Desktop\React\React-apps\expense-tracker\node_modules\@date-io\date-fns\build'
201
202
203ERROR in ./node_modules/@date-io/date-fns/build/index.esm.js 34:0-41
204
205Module not found: Error: Can't resolve 'date-fns/setHours' in 'C:\Users\Amir\Desktop\React\React-apps\expense-tracker\node_modules\@date-io\date-fns\build'
206
207
208ERROR in ./node_modules/@date-io/date-fns/build/index.esm.js 35:0-45
209
210Module not found: Error: Can't resolve 'date-fns/setMinutes' in 'C:\Users\Amir\Desktop\React\React-apps\expense-tracker\node_modules\@date-io\date-fns\build'
211
212
213ERROR in ./node_modules/@date-io/date-fns/build/index.esm.js 36:0-41
214
215Module not found: Error: Can't resolve 'date-fns/setMonth' in 'C:\Users\Amir\Desktop\React\React-apps\expense-tracker\node_modules\@date-io\date-fns\build'
216
217
218ERROR in ./node_modules/@date-io/date-fns/build/index.esm.js 37:0-37
219
220Module not found: Error: Can't resolve 'date-fns/getDay' in 'C:\Users\Amir\Desktop\React\React-apps\expense-tracker\node_modules\@date-io\date-fns\build'
221
222
223ERROR in ./node_modules/@date-io/date-fns/build/index.esm.js 38:0-53
224
225Module not found: Error: Can't resolve 'date-fns/getDaysInMonth' in 'C:\Users\Amir\Desktop\React\React-apps\expense-tracker\node_modules\@date-io\date-fns\build'
226
227
228ERROR in ./node_modules/@date-io/date-fns/build/index.esm.js 39:0-45
229
230Module not found: Error: Can't resolve 'date-fns/setSeconds' in 'C:\Users\Amir\Desktop\React\React-apps\expense-tracker\node_modules\@date-io\date-fns\build'
231
232
233ERROR in ./node_modules/@date-io/date-fns/build/index.esm.js 40:0-39
234
235Module not found: Error: Can't resolve 'date-fns/setYear' in 'C:\Users\Amir\Desktop\React\React-apps\expense-tracker\node_modules\@date-io\date-fns\build'
236
237
238ERROR in ./node_modules/@date-io/date-fns/build/index.esm.js 41:0-45
239
240Module not found: Error: Can't resolve 'date-fns/startOfDay' in 'C:\Users\Amir\Desktop\React\React-apps\expense-tracker\node_modules\@date-io\date-fns\build'
241
242
243ERROR in ./node_modules/@date-io/date-fns/build/index.esm.js 42:0-49
244
245Module not found: Error: Can't resolve 'date-fns/startOfMonth' in 'C:\Users\Amir\Desktop\React\React-apps\expense-tracker\node_modules\@date-io\date-fns\build'
246
247
248ERROR in ./node_modules/@date-io/date-fns/build/index.esm.js 43:0-45
249
250Module not found: Error: Can't resolve 'date-fns/endOfMonth' in 'C:\Users\Amir\Desktop\React\React-apps\expense-tracker\node_modules\@date-io\date-fns\build'
251
252
253ERROR in ./node_modules/@date-io/date-fns/build/index.esm.js 44:0-47
254
255Module not found: Error: Can't resolve 'date-fns/startOfWeek' in 'C:\Users\Amir\Desktop\React\React-apps\expense-tracker\node_modules\@date-io\date-fns\build'
256
257
258ERROR in ./node_modules/@date-io/date-fns/build/index.esm.js 45:0-47
259
260Module not found: Error: Can't resolve 'date-fns/startOfYear' in 'C:\Users\Amir\Desktop\React\React-apps\expense-tracker\node_modules\@date-io\date-fns\build'
261
262
263ERROR in ./node_modules/@date-io/date-fns/build/index.esm.js 46:0-41
264
265Module not found: Error: Can't resolve 'date-fns/parseISO' in 'C:\Users\Amir\Desktop\React\React-apps\expense-tracker\node_modules\@date-io\date-fns\build'
266
267
268ERROR in ./node_modules/@date-io/date-fns/build/index.esm.js 47:0-43
269
270Module not found: Error: Can't resolve 'date-fns/formatISO' in 'C:\Users\Amir\Desktop\React\React-apps\expense-tracker\node_modules\@date-io\date-fns\build'
271
272
273ERROR in ./node_modules/@date-io/date-fns/build/index.esm.js 48:0-57
274
275Module not found: Error: Can't resolve 'date-fns/isWithinInterval' in 'C:\Users\Amir\Desktop\React\React-apps\expense-tracker\node_modules\@date-io\date-fns\build'
276
277
278ERROR in ./node_modules/@date-io/date-fns/build/index.esm.js 49:0-65
279
280Module not found: Error: Can't resolve 'date-fns/_lib/format/longFormatters' in 'C:\Users\Amir\Desktop\React\React-apps\expense-tracker\node_modules\@date-io\date-fns\build'
281
282
283ERROR in ./node_modules/@date-io/date-fns/build/index.esm.js 50:0-50
284
285Module not found: Error: Can't resolve 'date-fns/locale/en-US' in 'C:\Users\Amir\Desktop\React\React-apps\expense-tracker\node_modules\@date-io\date-fns\build'
286

I searched the web but couldn't find something useful . also some StackOverflow similar posts that suggested to restart the server I tried but didn't actually solve my problem.

ANSWER

Answered 2022-Feb-08 at 17:19

You need to install the date-fns package from NPM using npm install --save date-fns.

Source https://stackoverflow.com/questions/71037974

QUESTION

Why does MUI DatePicker prevent rendering in my project (working sandbox MRE included?)

Asked 2022-Feb-01 at 08:42

I created a codesandbox with a minimal working implementation of MUI's Datepicker:

https://codesandbox.io/s/proud-pond-fb4rm?file=/src/App.js

*Edited to add my index.tsx:

1import React from 'react';
2import ReactDOM from 'react-dom';
3import {DatePicker, LocalizationProvider} from "@mui/lab";
4import {TextField} from "@mui/material";
5import AdapterDateFns from "@mui/lab/AdapterDateFns";
6
7ReactDOM.render(
8  <LocalizationProvider dateAdapter={AdapterDateFns}>
9    <DatePicker
10      renderInput={(props) => <TextField {...props} />}
11      value={null}
12      onChange={() => null}
13    />
14  </LocalizationProvider>
15  , document.getElementById('root')
16)
17

This implementation throws errors in my project (prevents rendering), although I have the same versions installed. I linked my package-lock file for good measure in case I'm wrong.

Clearly not a bug, and seemingly not a mismatch in package versions, what else could be causing this?

package-lock.json

screenshot of errors thrown

ANSWER

Answered 2022-Feb-01 at 08:42

As suspected, the clue was in my package-lock.json. Note to self: Always a good idea to have a look there when issue has been isolated and confirmed unique to a given project!

I had two different versions of @date-io/date-fns installed:

  • 1.x.x (entry in package-json)
  • 2.x.x (installed as dependency)

Source https://stackoverflow.com/questions/70497026

QUESTION

Using the MUI DatePicker with yup and react-hook-form - the error prop doesn't work as intended

Asked 2022-Jan-09 at 13:32

I'm working on a registration form made with yup, react-hook-form and MUI DatePicker/TextField. I'd like to have a date of birth field that checks if the user is above 18 years old. The error message is displayed correcly but the red color of the error state works only if the input is empty (and not when the age is below 18). I'm console logging the value of "invalid" that dictates the red color, and it is set to true when it should.

Here is a sandbox link: https://codesandbox.io/s/datepicker-yup-validation-8rod3?file=/src/App.js

ANSWER

Answered 2022-Jan-09 at 06:04

this solution was wrote with formik , yup and material datepicker :

1    import "./styles.css";
2import LocalizationProvider from "@mui/lab/LocalizationProvider";
3import AdapterDateFns from "@mui/lab/AdapterDateFns";
4import DateTimePicker from "@mui/lab/DateTimePicker";
5import * as Yup from "yup";
6import { useFormik } from "formik";
7import { Button, TextField } from "@mui/material";
8import moment from "moment";
9var y = new Date();
10y.setFullYear(y.getFullYear() - 18);
11
12const validationSchema = Yup.object().shape({
13  voyageNumber: Yup.number(),
14  voyageStartDate: Yup.date(),
15  voyageEndDate: Yup.date().when("voyageStartDate", (voyageStartDate, schema) =>
16    moment(voyageStartDate).isValid() ? schema.max(voyageStartDate) : schema
17  )
18});
19export default function App() {
20  const formik = useFormik({
21    initialValues: {
22      voyageStartDate: moment().add(-18, "years"),
23      voyageEndDate: null
24    },
25    validationSchema: validationSchema,
26    onSubmit: (values) => {
27      console.log(values);
28    }
29  });
30  return (
31    <div className="App">
32      <form autoComplete="off">
33        <LocalizationProvider dateAdapter={AdapterDateFns}>
34          <DateTimePicker
35            renderInput={(props) => (
36              <TextField
37                variant="standard"
38                className="w-100"
39                name="voyageEndDate"
40                required
41                {...props}
42                error={
43                  formik.touched?.voyageEndDate &&
44                  !!formik.errors?.voyageEndDate
45                }
46                helperText={
47                  formik.touched?.voyageEndDate && formik.errors?.voyageEndDate
48                }
49              />
50            )}
51            name="voyageEndDate"
52            label="Voyage End"
53            value={formik.values?.voyageEndDate}
54            onChange={(newValue) => {
55              console.log(
56                moment(newValue).format("YYYY-MM-DD HH:mm:ss"),
57                moment(y).format("YYYY-MM-DD HH:mm:ss"),
58                formik.errors
59              );
60              formik.setFieldTouched("voyageEndDate");
61              formik.setFieldValue(
62                "voyageEndDate",
63                moment(newValue).format("YYYY-MM-DD HH:mm:ss")
64              );
65            }}
66            onKeyPress={() => formik.setFieldTouched("voyageEndDate")}
67          />
68        </LocalizationProvider>
69        <div style={{ marginTop: "15px" }}>
70          <Button variant="contained" color="primary" type="submit">
71            Add Voyage
72          </Button>
73        </div>
74      </form>
75    </div>
76  );
77}
78

Source https://stackoverflow.com/questions/70634443

QUESTION

JavaFX: Exception in Application Start Method java.lang.reflect.InvocationTargetException

Asked 2021-Dec-10 at 19:28

I am literally desperate. I don’t know why but every time I try to run my program this error comes out. I am using Netbeans, with Java 10.0.2 in order to have already installed JavaFX. I think it’s due to some problem with the FXML file. Can you help me?

1java.lang.reflect.InvocationTargetException
2    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
3    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
4    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
5    at java.base/java.lang.reflect.Method.invoke(Method.java:564)
6    at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:473)
7    at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:372)
8    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
9    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
10    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
11    at java.base/java.lang.reflect.Method.invoke(Method.java:564)
12    at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:941)
13Caused by: java.lang.RuntimeException: Exception in Application start method
14    at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:973)
15    at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:198)
16    at java.base/java.lang.Thread.run(Thread.java:844)
17Caused by: javafx.fxml.LoadException: Root hasn't been set. Use method setRoot() before load.
18file:/C:/Users/User/Documents/NetBeansProjects/gruppo71/dist/run2124011701/gruppo71.jar!/gruppo71/FXMLDocument.fxml:13
19
20    at javafx.fxml/javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2621)
21    at javafx.fxml/javafx.fxml.FXMLLoader.access$100(FXMLLoader.java:105)
22    at javafx.fxml/javafx.fxml.FXMLLoader$RootElement.constructValue(FXMLLoader.java:1338)
23    at javafx.fxml/javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:754)
24    at javafx.fxml/javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2722)
25    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2552)
26    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2466)
27    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3253)
28    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3210)
29    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3179)
30    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3152)
31    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3129)
32    at javafx.fxml/javafx.fxml.FXMLLoader.load(FXMLLoader.java:3122)
33    at gruppo71.Gruppo71.start(Gruppo71.java:21)
34    at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:919)
35    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$11(PlatformImpl.java:449)
36    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$9(PlatformImpl.java:418)
37    at java.base/java.security.AccessController.doPrivileged(Native Method)
38    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:417)
39    at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
40    at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
41    at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:175)
42    ... 1 more
43Exception running application gruppo71.Gruppo71
44Java Result: 1
45

My main is this:

1java.lang.reflect.InvocationTargetException
2    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
3    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
4    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
5    at java.base/java.lang.reflect.Method.invoke(Method.java:564)
6    at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:473)
7    at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:372)
8    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
9    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
10    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
11    at java.base/java.lang.reflect.Method.invoke(Method.java:564)
12    at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:941)
13Caused by: java.lang.RuntimeException: Exception in Application start method
14    at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:973)
15    at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:198)
16    at java.base/java.lang.Thread.run(Thread.java:844)
17Caused by: javafx.fxml.LoadException: Root hasn't been set. Use method setRoot() before load.
18file:/C:/Users/User/Documents/NetBeansProjects/gruppo71/dist/run2124011701/gruppo71.jar!/gruppo71/FXMLDocument.fxml:13
19
20    at javafx.fxml/javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2621)
21    at javafx.fxml/javafx.fxml.FXMLLoader.access$100(FXMLLoader.java:105)
22    at javafx.fxml/javafx.fxml.FXMLLoader$RootElement.constructValue(FXMLLoader.java:1338)
23    at javafx.fxml/javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:754)
24    at javafx.fxml/javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2722)
25    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2552)
26    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2466)
27    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3253)
28    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3210)
29    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3179)
30    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3152)
31    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3129)
32    at javafx.fxml/javafx.fxml.FXMLLoader.load(FXMLLoader.java:3122)
33    at gruppo71.Gruppo71.start(Gruppo71.java:21)
34    at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:919)
35    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$11(PlatformImpl.java:449)
36    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$9(PlatformImpl.java:418)
37    at java.base/java.security.AccessController.doPrivileged(Native Method)
38    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:417)
39    at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
40    at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
41    at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:175)
42    ... 1 more
43Exception running application gruppo71.Gruppo71
44Java Result: 1
45
46import javafx.application.Application;
47import javafx.fxml.FXMLLoader;
48import javafx.scene.Parent;
49import javafx.scene.Scene;
50import javafx.stage.Stage;
51
52/**
53 *
54 * @author User
55 */
56public class Gruppo71 extends Application {
57    
58    @Override
59    public void start(Stage stage) throws Exception {
60        Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
61        
62        Scene scene = new Scene(root);
63        
64        stage.setScene(scene);
65        stage.show();
66    }
67
68    /**
69     * @param args the command line arguments
70     */
71    public static void main(String[] args) {
72        launch(args);
73    }
74} 
75

My FXML code is:

1java.lang.reflect.InvocationTargetException
2    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
3    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
4    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
5    at java.base/java.lang.reflect.Method.invoke(Method.java:564)
6    at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:473)
7    at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:372)
8    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
9    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
10    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
11    at java.base/java.lang.reflect.Method.invoke(Method.java:564)
12    at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:941)
13Caused by: java.lang.RuntimeException: Exception in Application start method
14    at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:973)
15    at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:198)
16    at java.base/java.lang.Thread.run(Thread.java:844)
17Caused by: javafx.fxml.LoadException: Root hasn't been set. Use method setRoot() before load.
18file:/C:/Users/User/Documents/NetBeansProjects/gruppo71/dist/run2124011701/gruppo71.jar!/gruppo71/FXMLDocument.fxml:13
19
20    at javafx.fxml/javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2621)
21    at javafx.fxml/javafx.fxml.FXMLLoader.access$100(FXMLLoader.java:105)
22    at javafx.fxml/javafx.fxml.FXMLLoader$RootElement.constructValue(FXMLLoader.java:1338)
23    at javafx.fxml/javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:754)
24    at javafx.fxml/javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2722)
25    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2552)
26    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2466)
27    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3253)
28    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3210)
29    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3179)
30    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3152)
31    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3129)
32    at javafx.fxml/javafx.fxml.FXMLLoader.load(FXMLLoader.java:3122)
33    at gruppo71.Gruppo71.start(Gruppo71.java:21)
34    at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:919)
35    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$11(PlatformImpl.java:449)
36    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$9(PlatformImpl.java:418)
37    at java.base/java.security.AccessController.doPrivileged(Native Method)
38    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:417)
39    at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
40    at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
41    at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:175)
42    ... 1 more
43Exception running application gruppo71.Gruppo71
44Java Result: 1
45
46import javafx.application.Application;
47import javafx.fxml.FXMLLoader;
48import javafx.scene.Parent;
49import javafx.scene.Scene;
50import javafx.stage.Stage;
51
52/**
53 *
54 * @author User
55 */
56public class Gruppo71 extends Application {
57    
58    @Override
59    public void start(Stage stage) throws Exception {
60        Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
61        
62        Scene scene = new Scene(root);
63        
64        stage.setScene(scene);
65        stage.show();
66    }
67
68    /**
69     * @param args the command line arguments
70     */
71    public static void main(String[] args) {
72        launch(args);
73    }
74} 
75
76<?import javafx.scene.control.Button?>
77<?import javafx.scene.control.ContextMenu?>
78<?import javafx.scene.control.DatePicker?>
79<?import javafx.scene.control.MenuItem?>
80<?import javafx.scene.control.SplitPane?>
81<?import javafx.scene.control.TableColumn?>
82<?import javafx.scene.control.TableView?>
83<?import javafx.scene.control.TextField?>
84<?import javafx.scene.layout.AnchorPane?>
85
86<fx:root id="AnchorPane" prefHeight="300.0" prefWidth="450.0" type="AnchorPane" xmlns="http://javafx.com/javafx/10.0.2" xmlns:fx="http://javafx.com/fxml/1" fx:controller="gruppo71.FXMLDocumentController">
87   <children>
88      <SplitPane dividerPositions="0.13087248322147652" layoutX="28.0" orientation="VERTICAL" prefHeight="200.0" prefWidth="320.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
89        <items>
90          <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="100.0" prefWidth="160.0">
91               <children>
92                  <Button fx:id="aggiungiButton" layoutX="10.0" layoutY="5.0" mnemonicParsing="false" onAction="#addEvento" text="Aggiungi Evento" AnchorPane.bottomAnchor="5.0" AnchorPane.leftAnchor="10.0" AnchorPane.topAnchor="5.0" />
93                  <DatePicker fx:id="dataPicker" layoutX="114.0" layoutY="6.0" prefHeight="26.0" prefWidth="150.0" AnchorPane.bottomAnchor="5.0" AnchorPane.leftAnchor="124.0" AnchorPane.topAnchor="5.0" />
94                  <TextField fx:id="descriptionField" layoutX="285.0" layoutY="6.0" text="aggiungi descrizione..." AnchorPane.bottomAnchor="5.0" AnchorPane.leftAnchor="284.0" AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="5.0" />
95               </children>
96            </AnchorPane>
97          <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="100.0" prefWidth="160.0">
98               <children>
99                  <TableView fx:id="mainTab" layoutX="14.0" prefHeight="256.0" prefWidth="448.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
100                    <columns>
101                      <TableColumn fx:id="dataColumn" prefWidth="136.0" text="Data" />
102                      <TableColumn fx:id="eventColumn" prefWidth="311.0" text="Evento" />
103                    </columns>
104                     <contextMenu>
105                        <ContextMenu>
106                           <items>
107                              <MenuItem fx:id="removeButton" mnemonicParsing="false" onAction="#removeEvent" text="Rimuovi Evento" />
108                              <MenuItem fx:id="importaButton" mnemonicParsing="false" onAction="#importCSV" text="Importa CSV" />
109                              <MenuItem fx:id="exportButton" mnemonicParsing="false" onAction="#exportCSV" text="Esporta CSV" />
110                           </items>
111                        </ContextMenu>
112                     </contextMenu>
113                  </TableView>
114               </children>
115            </AnchorPane>
116        </items>
117      </SplitPane>
118   </children>
119</fx:root>
120

All help would be greatly appreciated!!!

ANSWER

Answered 2021-Dec-10 at 19:28

Just to mark this as answered: See @James_D' comment for the solution.

Replace <fx:root> in the FXML file with <AnchorPane> or set the root on the FXMLLoader before calling load() for example like this:

1java.lang.reflect.InvocationTargetException
2    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
3    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
4    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
5    at java.base/java.lang.reflect.Method.invoke(Method.java:564)
6    at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:473)
7    at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:372)
8    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
9    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
10    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
11    at java.base/java.lang.reflect.Method.invoke(Method.java:564)
12    at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:941)
13Caused by: java.lang.RuntimeException: Exception in Application start method
14    at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:973)
15    at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:198)
16    at java.base/java.lang.Thread.run(Thread.java:844)
17Caused by: javafx.fxml.LoadException: Root hasn't been set. Use method setRoot() before load.
18file:/C:/Users/User/Documents/NetBeansProjects/gruppo71/dist/run2124011701/gruppo71.jar!/gruppo71/FXMLDocument.fxml:13
19
20    at javafx.fxml/javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2621)
21    at javafx.fxml/javafx.fxml.FXMLLoader.access$100(FXMLLoader.java:105)
22    at javafx.fxml/javafx.fxml.FXMLLoader$RootElement.constructValue(FXMLLoader.java:1338)
23    at javafx.fxml/javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:754)
24    at javafx.fxml/javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2722)
25    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2552)
26    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2466)
27    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3253)
28    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3210)
29    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3179)
30    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3152)
31    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3129)
32    at javafx.fxml/javafx.fxml.FXMLLoader.load(FXMLLoader.java:3122)
33    at gruppo71.Gruppo71.start(Gruppo71.java:21)
34    at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:919)
35    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$11(PlatformImpl.java:449)
36    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$9(PlatformImpl.java:418)
37    at java.base/java.security.AccessController.doPrivileged(Native Method)
38    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:417)
39    at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
40    at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
41    at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:175)
42    ... 1 more
43Exception running application gruppo71.Gruppo71
44Java Result: 1
45
46import javafx.application.Application;
47import javafx.fxml.FXMLLoader;
48import javafx.scene.Parent;
49import javafx.scene.Scene;
50import javafx.stage.Stage;
51
52/**
53 *
54 * @author User
55 */
56public class Gruppo71 extends Application {
57    
58    @Override
59    public void start(Stage stage) throws Exception {
60        Parent root = FXMLLoader.load(getClass().getResource(&quot;FXMLDocument.fxml&quot;));
61        
62        Scene scene = new Scene(root);
63        
64        stage.setScene(scene);
65        stage.show();
66    }
67
68    /**
69     * @param args the command line arguments
70     */
71    public static void main(String[] args) {
72        launch(args);
73    }
74} 
75
76&lt;?import javafx.scene.control.Button?&gt;
77&lt;?import javafx.scene.control.ContextMenu?&gt;
78&lt;?import javafx.scene.control.DatePicker?&gt;
79&lt;?import javafx.scene.control.MenuItem?&gt;
80&lt;?import javafx.scene.control.SplitPane?&gt;
81&lt;?import javafx.scene.control.TableColumn?&gt;
82&lt;?import javafx.scene.control.TableView?&gt;
83&lt;?import javafx.scene.control.TextField?&gt;
84&lt;?import javafx.scene.layout.AnchorPane?&gt;
85
86&lt;fx:root id=&quot;AnchorPane&quot; prefHeight=&quot;300.0&quot; prefWidth=&quot;450.0&quot; type=&quot;AnchorPane&quot; xmlns=&quot;http://javafx.com/javafx/10.0.2&quot; xmlns:fx=&quot;http://javafx.com/fxml/1&quot; fx:controller=&quot;gruppo71.FXMLDocumentController&quot;&gt;
87   &lt;children&gt;
88      &lt;SplitPane dividerPositions=&quot;0.13087248322147652&quot; layoutX=&quot;28.0&quot; orientation=&quot;VERTICAL&quot; prefHeight=&quot;200.0&quot; prefWidth=&quot;320.0&quot; AnchorPane.bottomAnchor=&quot;0.0&quot; AnchorPane.leftAnchor=&quot;0.0&quot; AnchorPane.rightAnchor=&quot;0.0&quot; AnchorPane.topAnchor=&quot;0.0&quot;&gt;
89        &lt;items&gt;
90          &lt;AnchorPane minHeight=&quot;0.0&quot; minWidth=&quot;0.0&quot; prefHeight=&quot;100.0&quot; prefWidth=&quot;160.0&quot;&gt;
91               &lt;children&gt;
92                  &lt;Button fx:id=&quot;aggiungiButton&quot; layoutX=&quot;10.0&quot; layoutY=&quot;5.0&quot; mnemonicParsing=&quot;false&quot; onAction=&quot;#addEvento&quot; text=&quot;Aggiungi Evento&quot; AnchorPane.bottomAnchor=&quot;5.0&quot; AnchorPane.leftAnchor=&quot;10.0&quot; AnchorPane.topAnchor=&quot;5.0&quot; /&gt;
93                  &lt;DatePicker fx:id=&quot;dataPicker&quot; layoutX=&quot;114.0&quot; layoutY=&quot;6.0&quot; prefHeight=&quot;26.0&quot; prefWidth=&quot;150.0&quot; AnchorPane.bottomAnchor=&quot;5.0&quot; AnchorPane.leftAnchor=&quot;124.0&quot; AnchorPane.topAnchor=&quot;5.0&quot; /&gt;
94                  &lt;TextField fx:id=&quot;descriptionField&quot; layoutX=&quot;285.0&quot; layoutY=&quot;6.0&quot; text=&quot;aggiungi descrizione...&quot; AnchorPane.bottomAnchor=&quot;5.0&quot; AnchorPane.leftAnchor=&quot;284.0&quot; AnchorPane.rightAnchor=&quot;10.0&quot; AnchorPane.topAnchor=&quot;5.0&quot; /&gt;
95               &lt;/children&gt;
96            &lt;/AnchorPane&gt;
97          &lt;AnchorPane minHeight=&quot;0.0&quot; minWidth=&quot;0.0&quot; prefHeight=&quot;100.0&quot; prefWidth=&quot;160.0&quot;&gt;
98               &lt;children&gt;
99                  &lt;TableView fx:id=&quot;mainTab&quot; layoutX=&quot;14.0&quot; prefHeight=&quot;256.0&quot; prefWidth=&quot;448.0&quot; AnchorPane.bottomAnchor=&quot;0.0&quot; AnchorPane.leftAnchor=&quot;0.0&quot; AnchorPane.rightAnchor=&quot;0.0&quot; AnchorPane.topAnchor=&quot;0.0&quot;&gt;
100                    &lt;columns&gt;
101                      &lt;TableColumn fx:id=&quot;dataColumn&quot; prefWidth=&quot;136.0&quot; text=&quot;Data&quot; /&gt;
102                      &lt;TableColumn fx:id=&quot;eventColumn&quot; prefWidth=&quot;311.0&quot; text=&quot;Evento&quot; /&gt;
103                    &lt;/columns&gt;
104                     &lt;contextMenu&gt;
105                        &lt;ContextMenu&gt;
106                           &lt;items&gt;
107                              &lt;MenuItem fx:id=&quot;removeButton&quot; mnemonicParsing=&quot;false&quot; onAction=&quot;#removeEvent&quot; text=&quot;Rimuovi Evento&quot; /&gt;
108                              &lt;MenuItem fx:id=&quot;importaButton&quot; mnemonicParsing=&quot;false&quot; onAction=&quot;#importCSV&quot; text=&quot;Importa CSV&quot; /&gt;
109                              &lt;MenuItem fx:id=&quot;exportButton&quot; mnemonicParsing=&quot;false&quot; onAction=&quot;#exportCSV&quot; text=&quot;Esporta CSV&quot; /&gt;
110                           &lt;/items&gt;
111                        &lt;/ContextMenu&gt;
112                     &lt;/contextMenu&gt;
113                  &lt;/TableView&gt;
114               &lt;/children&gt;
115            &lt;/AnchorPane&gt;
116        &lt;/items&gt;
117      &lt;/SplitPane&gt;
118   &lt;/children&gt;
119&lt;/fx:root&gt;
120FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource(&quot;FXMLDocument.fxml&quot;));
121fxmlLoader.setRoot(new AnchorPane());
122Parent root = fxmlLoader.load();
123

Source https://stackoverflow.com/questions/70308258

Community Discussions contain sources that include Stack Exchange Network

Tutorials and Learning Resources in Datepicker

Tutorials and Learning Resources are not available at this moment for Datepicker

Share this Page

share link

Get latest updates on Datepicker