add date picker
This commit is contained in:
parent
09a514ae86
commit
82f9b1aac2
8 changed files with 1044 additions and 55 deletions
|
|
@ -8,8 +8,8 @@ A highly flexible and configurable dynamic form component built with **PrimeVue*
|
|||
## ✨ New Features (PrimeVue Migration)
|
||||
|
||||
- **AutoComplete component** - Users can select from suggestions OR enter completely custom values
|
||||
- **Better date/time pickers** with calendar popup and time selection
|
||||
- **Improved accessibility** with ARIA support
|
||||
- **Enhanced Date/Time Pickers** - Comprehensive date handling with multiple formats, time selection, constraints, and smart defaults
|
||||
- **Better accessibility** with ARIA support
|
||||
- **More flexible styling** with CSS custom properties
|
||||
- **Enhanced mobile responsiveness** with CSS Grid
|
||||
|
||||
|
|
@ -363,41 +363,152 @@ Radio button group for single selection from multiple options.
|
|||
|
||||
### Date Input (`type: 'date'`)
|
||||
|
||||
Date picker input field.
|
||||
Enhanced date picker input field with comprehensive formatting and configuration options.
|
||||
|
||||
```javascript
|
||||
// Basic date input
|
||||
{
|
||||
name: 'birthDate',
|
||||
label: 'Birth Date',
|
||||
type: 'date',
|
||||
required: true,
|
||||
min: '1900-01-01',
|
||||
max: '2025-12-31'
|
||||
}
|
||||
|
||||
// Date with custom format
|
||||
{
|
||||
name: 'eventDate',
|
||||
label: 'Event Date',
|
||||
type: 'date',
|
||||
format: 'YYYY-MM-DD', // or 'mm/dd/yyyy', 'dd/mm/yyyy', etc.
|
||||
required: true,
|
||||
placeholder: 'Select event date'
|
||||
}
|
||||
|
||||
// Date with time picker
|
||||
{
|
||||
name: 'appointmentDateTime',
|
||||
label: 'Appointment Date & Time',
|
||||
type: 'date',
|
||||
showTime: true,
|
||||
hourFormat: '12', // '12' or '24'
|
||||
required: true,
|
||||
defaultToNow: true, // Set to current date/time by default
|
||||
}
|
||||
|
||||
// Time-only picker
|
||||
{
|
||||
name: 'preferredTime',
|
||||
label: 'Preferred Time',
|
||||
type: 'date',
|
||||
timeOnly: true,
|
||||
hourFormat: '12',
|
||||
stepMinute: 15, // 15-minute intervals
|
||||
defaultValue: 'now'
|
||||
}
|
||||
|
||||
// Advanced date configuration
|
||||
{
|
||||
name: 'projectDeadline',
|
||||
label: 'Project Deadline',
|
||||
type: 'date',
|
||||
format: 'dd/mm/yyyy',
|
||||
minDate: 'today', // Can't select past dates
|
||||
maxDate: '2025-12-31', // Maximum date
|
||||
defaultToToday: true,
|
||||
showButtonBar: true,
|
||||
yearNavigator: true,
|
||||
monthNavigator: true,
|
||||
yearRange: '2024:2030',
|
||||
helpText: 'Select a deadline for the project completion'
|
||||
}
|
||||
|
||||
// Inline date picker (always visible)
|
||||
{
|
||||
name: 'calendarDate',
|
||||
label: 'Calendar',
|
||||
type: 'date',
|
||||
inline: true,
|
||||
view: 'date', // 'date', 'month', 'year'
|
||||
showWeek: true,
|
||||
defaultValue: 'today'
|
||||
}
|
||||
```
|
||||
|
||||
**Additional Properties:**
|
||||
|
||||
- **`min`** (String) - Minimum allowed date (YYYY-MM-DD format)
|
||||
- **`max`** (String) - Maximum allowed date (YYYY-MM-DD format)
|
||||
- **`format`** (String) - Date format: `'YYYY-MM-DD'`, `'mm/dd/yyyy'`, `'dd/mm/yyyy'`, `'dd-mm-yyyy'`, `'mm-dd-yyyy'`
|
||||
- **`dateFormat`** (String) - PrimeVue-specific format string (overrides `format`)
|
||||
- **`showTime`** (Boolean, default: `false`) - Include time picker
|
||||
- **`timeOnly`** (Boolean, default: `false`) - Show only time picker (no date)
|
||||
- **`hourFormat`** (String, default: `'24'`) - Hour format: `'12'` or `'24'`
|
||||
- **`stepHour`** (Number, default: `1`) - Hour step increment
|
||||
- **`stepMinute`** (Number, default: `1`) - Minute step increment
|
||||
- **`showSeconds`** (Boolean, default: `false`) - Show seconds in time picker
|
||||
- **`stepSecond`** (Number, default: `1`) - Second step increment
|
||||
- **`minDate`** (String|Date) - Minimum selectable date
|
||||
- **`maxDate`** (String|Date) - Maximum selectable date
|
||||
- **`defaultToToday`** (Boolean, default: `false`) - Set default to today's date
|
||||
- **`defaultToNow`** (Boolean, default: `false`) - Set default to current date/time
|
||||
- **`showButtonBar`** (Boolean, default: `true`) - Show today/clear buttons
|
||||
- **`todayButtonLabel`** (String, default: `'Today'`) - Today button text
|
||||
- **`clearButtonLabel`** (String, default: `'Clear'`) - Clear button text
|
||||
- **`showWeek`** (Boolean, default: `false`) - Show week numbers
|
||||
- **`manualInput`** (Boolean, default: `true`) - Allow manual date entry
|
||||
- **`yearNavigator`** (Boolean, default: `false`) - Show year dropdown
|
||||
- **`monthNavigator`** (Boolean, default: `false`) - Show month dropdown
|
||||
- **`yearRange`** (String, default: `'1900:2100'`) - Available year range
|
||||
- **`inline`** (Boolean, default: `false`) - Display picker inline (always visible)
|
||||
- **`view`** (String, default: `'date'`) - Default view: `'date'`, `'month'`, `'year'`
|
||||
- **`touchUI`** (Boolean, default: `false`) - Optimize for touch devices
|
||||
- **`onDateChange`** (Function) - Custom date change handler
|
||||
- **Signature:** `(dateValue: Date) => any`
|
||||
|
||||
### DateTime Input (`type: 'datetime'`)
|
||||
|
||||
Date and time picker input field.
|
||||
**Default Value Options:**
|
||||
|
||||
```javascript
|
||||
// String values
|
||||
defaultValue: "today"; // Set to today's date
|
||||
defaultValue: "now"; // Set to current date/time
|
||||
defaultValue: "2024-12-25"; // Specific date string
|
||||
|
||||
// Boolean flags
|
||||
defaultToToday: true; // Set to today (date only)
|
||||
defaultToNow: true; // Set to current date/time
|
||||
|
||||
// Date object
|
||||
defaultValue: new Date(); // Specific Date object
|
||||
```
|
||||
|
||||
### DateTime Input (`type: 'datetime'`) - LEGACY
|
||||
|
||||
**⚠️ DEPRECATED:** Use `type: 'date'` with `showTime: true` instead.
|
||||
|
||||
Legacy date and time picker input field. This is maintained for backward compatibility.
|
||||
|
||||
```javascript
|
||||
// LEGACY - Use date with showTime instead
|
||||
{
|
||||
name: 'appointmentTime',
|
||||
label: 'Appointment Time',
|
||||
type: 'datetime',
|
||||
required: true
|
||||
}
|
||||
|
||||
// RECOMMENDED - Use this instead
|
||||
{
|
||||
name: 'appointmentTime',
|
||||
label: 'Appointment Time',
|
||||
type: 'date',
|
||||
showTime: true,
|
||||
required: true
|
||||
}
|
||||
```
|
||||
|
||||
**Additional Properties:**
|
||||
|
||||
- **`min`** (String) - Minimum allowed datetime
|
||||
- **`max`** (String) - Maximum allowed datetime
|
||||
- **`hourFormat`** (String, default: `'24'`) - Hour format: `'12'` or `'24'`
|
||||
|
||||
### File Input (`type: 'file'`)
|
||||
|
||||
|
|
@ -526,6 +637,18 @@ const contactFields = [
|
|||
format: "email",
|
||||
required: true,
|
||||
cols: 12,
|
||||
md: 6,
|
||||
},
|
||||
{
|
||||
name: "preferredContactDate",
|
||||
label: "Preferred Contact Date",
|
||||
type: "date",
|
||||
format: "mm/dd/yyyy",
|
||||
minDate: "today",
|
||||
defaultToToday: true,
|
||||
cols: 12,
|
||||
md: 6,
|
||||
helpText: "When would you like us to contact you?",
|
||||
},
|
||||
{
|
||||
name: "message",
|
||||
|
|
@ -675,6 +798,280 @@ const autoCompleteFields = [
|
|||
</template>
|
||||
```
|
||||
|
||||
### Enhanced Date Picker Examples
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
|
||||
const formData = ref({});
|
||||
|
||||
const dateFields = [
|
||||
// Basic date picker
|
||||
{
|
||||
name: "birthDate",
|
||||
label: "Birth Date",
|
||||
type: "date",
|
||||
format: "mm/dd/yyyy",
|
||||
required: true,
|
||||
cols: 6,
|
||||
},
|
||||
|
||||
// Date with time - appointment scheduling
|
||||
{
|
||||
name: "appointmentDateTime",
|
||||
label: "Appointment Date & Time",
|
||||
type: "date",
|
||||
showTime: true,
|
||||
hourFormat: "12",
|
||||
stepMinute: 15,
|
||||
defaultToNow: true,
|
||||
minDate: "today",
|
||||
cols: 6,
|
||||
helpText: "Select appointment date and time",
|
||||
},
|
||||
|
||||
// Project deadline with constraints
|
||||
{
|
||||
name: "projectDeadline",
|
||||
label: "Project Deadline",
|
||||
type: "date",
|
||||
format: "YYYY-MM-DD",
|
||||
minDate: "today",
|
||||
maxDate: "2025-12-31",
|
||||
defaultToToday: true,
|
||||
yearNavigator: true,
|
||||
monthNavigator: true,
|
||||
required: true,
|
||||
cols: 6,
|
||||
helpText: "Deadline cannot be in the past",
|
||||
},
|
||||
|
||||
// Time-only picker for preferences
|
||||
{
|
||||
name: "preferredTime",
|
||||
label: "Preferred Contact Time",
|
||||
type: "date",
|
||||
timeOnly: true,
|
||||
hourFormat: "12",
|
||||
stepMinute: 30,
|
||||
defaultValue: "09:00",
|
||||
cols: 6,
|
||||
helpText: "Best time to contact you",
|
||||
},
|
||||
|
||||
// Event date with week numbers
|
||||
{
|
||||
name: "eventDate",
|
||||
label: "Event Date",
|
||||
type: "date",
|
||||
format: "dd/mm/yyyy",
|
||||
showWeek: true,
|
||||
yearNavigator: true,
|
||||
monthNavigator: true,
|
||||
yearRange: "2024:2026",
|
||||
cols: 6,
|
||||
},
|
||||
|
||||
// Inline calendar for scheduling
|
||||
{
|
||||
name: "availableDate",
|
||||
label: "Available Dates",
|
||||
type: "date",
|
||||
inline: true,
|
||||
multiple: true, // Note: This would require custom implementation
|
||||
showButtonBar: true,
|
||||
cols: 12,
|
||||
helpText: "Click dates when you are available",
|
||||
},
|
||||
];
|
||||
|
||||
const handleSubmit = (data) => {
|
||||
console.log("Date form submitted:", data);
|
||||
|
||||
// Example of working with date values
|
||||
if (data.appointmentDateTime) {
|
||||
console.log(
|
||||
"Appointment scheduled for:",
|
||||
data.appointmentDateTime.toLocaleString(),
|
||||
);
|
||||
}
|
||||
|
||||
if (data.projectDeadline) {
|
||||
const deadline = new Date(data.projectDeadline);
|
||||
const daysUntilDeadline = Math.ceil(
|
||||
(deadline - new Date()) / (1000 * 60 * 60 * 24),
|
||||
);
|
||||
console.log(`Days until deadline: ${daysUntilDeadline}`);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Form
|
||||
:fields="dateFields"
|
||||
v-model:form-data="formData"
|
||||
@submit="handleSubmit"
|
||||
submit-button-text="Schedule"
|
||||
/>
|
||||
|
||||
<!-- Display current values -->
|
||||
<div v-if="Object.keys(formData).length" class="mt-4">
|
||||
<h3>Selected Dates:</h3>
|
||||
<div v-for="(value, key) in formData" :key="key" class="mb-2">
|
||||
<strong>{{ key }}:</strong>
|
||||
<span v-if="value instanceof Date">
|
||||
{{ value.toLocaleString() }}
|
||||
</span>
|
||||
<span v-else>{{ value }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
```
|
||||
|
||||
### Real-World Date Picker Scenarios
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
|
||||
const bookingData = ref({});
|
||||
|
||||
// Hotel booking form with date constraints
|
||||
const hotelBookingFields = [
|
||||
{
|
||||
name: "checkIn",
|
||||
label: "Check-in Date",
|
||||
type: "date",
|
||||
format: "mm/dd/yyyy",
|
||||
minDate: "today",
|
||||
defaultToToday: true,
|
||||
required: true,
|
||||
cols: 6,
|
||||
onDateChange: (date) => {
|
||||
// Auto-update checkout date to be at least 1 day later
|
||||
if (bookingData.value.checkOut && bookingData.value.checkOut <= date) {
|
||||
const nextDay = new Date(date);
|
||||
nextDay.setDate(nextDay.getDate() + 1);
|
||||
bookingData.value.checkOut = nextDay;
|
||||
}
|
||||
return date;
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "checkOut",
|
||||
label: "Check-out Date",
|
||||
type: "date",
|
||||
format: "mm/dd/yyyy",
|
||||
minDate: "today",
|
||||
required: true,
|
||||
cols: 6,
|
||||
validate: (value) => {
|
||||
if (
|
||||
value &&
|
||||
bookingData.value.checkIn &&
|
||||
value <= bookingData.value.checkIn
|
||||
) {
|
||||
return "Check-out date must be after check-in date";
|
||||
}
|
||||
return null;
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
// Meeting scheduler with business hours
|
||||
const meetingFields = [
|
||||
{
|
||||
name: "meetingDate",
|
||||
label: "Meeting Date",
|
||||
type: "date",
|
||||
format: "dd/mm/yyyy",
|
||||
minDate: "today",
|
||||
// Exclude weekends
|
||||
validate: (value) => {
|
||||
if (value) {
|
||||
const day = value.getDay();
|
||||
if (day === 0 || day === 6) {
|
||||
return "Please select a weekday";
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
cols: 6,
|
||||
},
|
||||
{
|
||||
name: "meetingTime",
|
||||
label: "Meeting Time",
|
||||
type: "date",
|
||||
timeOnly: true,
|
||||
hourFormat: "12",
|
||||
stepMinute: 30,
|
||||
// Business hours only: 9 AM to 5 PM
|
||||
validate: (value) => {
|
||||
if (value) {
|
||||
const hours = value.getHours();
|
||||
if (hours < 9 || hours >= 17) {
|
||||
return "Please select a time between 9:00 AM and 5:00 PM";
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
cols: 6,
|
||||
},
|
||||
];
|
||||
|
||||
// Birth date with age calculation
|
||||
const personalInfoFields = [
|
||||
{
|
||||
name: "birthDate",
|
||||
label: "Date of Birth",
|
||||
type: "date",
|
||||
format: "mm/dd/yyyy",
|
||||
maxDate: "today",
|
||||
yearNavigator: true,
|
||||
yearRange: "1920:2010",
|
||||
required: true,
|
||||
onDateChange: (date) => {
|
||||
// Calculate and display age
|
||||
if (date) {
|
||||
const today = new Date();
|
||||
const age = today.getFullYear() - date.getFullYear();
|
||||
const monthDiff = today.getMonth() - date.getMonth();
|
||||
|
||||
if (
|
||||
monthDiff < 0 ||
|
||||
(monthDiff === 0 && today.getDate() < date.getDate())
|
||||
) {
|
||||
age--;
|
||||
}
|
||||
|
||||
console.log(`Age: ${age} years`);
|
||||
}
|
||||
return date;
|
||||
},
|
||||
cols: 12,
|
||||
},
|
||||
];
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<h3>Hotel Booking</h3>
|
||||
<Form :fields="hotelBookingFields" v-model:form-data="bookingData" />
|
||||
|
||||
<h3 class="mt-6">Meeting Scheduler</h3>
|
||||
<Form :fields="meetingFields" />
|
||||
|
||||
<h3 class="mt-6">Personal Information</h3>
|
||||
<Form :fields="personalInfoFields" />
|
||||
</div>
|
||||
</template>
|
||||
```
|
||||
|
||||
```vue
|
||||
|
||||
```
|
||||
|
||||
### User Registration Form
|
||||
|
||||
```vue
|
||||
|
|
@ -1028,8 +1425,8 @@ The component has been completely migrated from Vuetify to PrimeVue. Here's what
|
|||
### ✨ What's New
|
||||
|
||||
- **AutoComplete component** - The star feature! Users can select from suggestions OR enter completely custom values
|
||||
- **Better date/time pickers** - Calendar popup, time selection, better formatting options
|
||||
- **Enhanced file uploads** - Drag & drop, better validation, file preview
|
||||
- **Enhanced Date/Time Pickers** - Multiple format support (`YYYY-MM-DD`, `mm/dd/yyyy`, etc.), smart defaults (`today`, `now`), time-only mode, inline calendars, business hour constraints, and comprehensive validation
|
||||
- **Better file uploads** - Drag & drop, better validation, file preview
|
||||
- **Improved accessibility** - Full ARIA support, better keyboard navigation
|
||||
- **Flexible styling** - CSS custom properties, easier theming
|
||||
- **Mobile-first responsive** - Better grid system, improved mobile UX
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue