Skip to content

Commit

Permalink
Merge pull request #365 from qor5/feat-datepicker-format
Browse files Browse the repository at this point in the history
feat: support default formatted modelValue and timeSelect functional …
  • Loading branch information
danni-cool authored Dec 18, 2024
2 parents 754ebe7 + 5fe24e3 commit 4e1bf6f
Show file tree
Hide file tree
Showing 11 changed files with 214 additions and 128 deletions.
4 changes: 4 additions & 0 deletions ui/vuetifyx/scroll-iframe.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ func (b *VXScrollIframeBuilder) virtualElementHeight(v int) (r *VXScrollIframeBu
b.tag.Attr(":virtual-element-height", h.JSONString(v))
return b
}
func (b *VXScrollIframeBuilder) BackgroundColor(v string) (r *VXScrollIframeBuilder) {
b.tag.Attr(":background-color", h.JSONString(v))
return b
}

func (b *VXScrollIframeBuilder) SetAttr(k string, v interface{}) {
b.tag.SetAttr(k, v)
Expand Down
2 changes: 1 addition & 1 deletion ui/vuetifyx/vuetifyxjs/dist/assets/vuetifyx.min.css

Large diffs are not rendered by default.

74 changes: 37 additions & 37 deletions ui/vuetifyx/vuetifyxjs/dist/vuetifyx.min.js

Large diffs are not rendered by default.

28 changes: 14 additions & 14 deletions ui/vuetifyx/vuetifyxjs/docs/Components/VXDatePicker/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@

### 值类型

- 组件拥有很强的传入值适应性,可以传入各种类型的值并格式化字符串、时间戳、日期类型都可
- 组件拥有很强的传入值适应性,可以传入各种类型的值并格式化字符串、时间戳、日期类型都可,最终都会被格式化成默认格式或者传入的format格式
- vx-range-picker 可以切换值选中模式,当 `needConfirm``true` 时,需要点击确认按钮值才生效

:::demo
Expand Down Expand Up @@ -89,9 +89,9 @@
<script setup lang="ts">
import { ref } from 'vue'
import Datepicker from '@/lib/Datepicker.vue'
const value1 = ref(new Date())
const value2 = ref(Date.now())
const value2 = ref(1733390010891)
const value3 = ref('2024/11/1')
const value4 = ref(['2024/11/1', '2024/12/1 12:21'])
const value5 = ref(['', ''])
Expand All @@ -111,17 +111,18 @@ const value5 = ref(['', ''])
<v-row>
<v-col cols="6">
<vx-date-picker v-model="value" label="vx-date-picker (datepicker)" placeholder="Start at" />
<div>selected value: {{ value ? new Date(value) : 'unselected' }}</div>
<div>selected value: {{ value || 'unselected' }}</div>
</v-col>
<v-col cols="6">
<vx-date-picker
v-model="valueDateTime"
label="vx-date-picker (datetimepicker)"
format="YYYY-MM-DD HH:mm"
type="datetimepicker"
placeholder="Choose Datetime"
/>
<div>selected value: {{ valueDateTime ? new Date(valueDateTime) : 'unselected' }}</div>
<div>selected value: {{ valueDateTime || 'unselected' }}</div>
</v-col>
<v-col cols="6">
Expand Down Expand Up @@ -160,8 +161,8 @@ const rangeValueDateTime = ref(['', ''])
### 日期格式化 format

- datepicker 默认格式是 YYYY-MM-DD
- datetimepicker 默认格式是 YYYY-MM-DD HH:mm
- format 不仅影响展示,也影响选择以后格式化的值,原则是格式化未覆盖到的值会被重置成0(time部分)
- datetimepicker 默认格式是 YYYY-MM-DD HH:mm:ss
- **format 不仅影响展示也影响组件的可选项,以及绑定的 modelValue**

:::demo

Expand All @@ -172,27 +173,26 @@ const rangeValueDateTime = ref(['', ''])
<vx-date-picker
v-model="value"
format="YYYY/MM-DD"
label="vx-date-picker (datepicker)"
label="type: datepicker (YYYY/MM-DD)"
placeholder="Start at"
/>
<div>selected value: {{ value ? new Date(value) : 'unselected' }}</div>
<div>selected value: {{ value || 'unselected' }}</div>
</v-col>
<v-col cols="6">
<vx-date-picker
v-model="valueDateTime"
label="vx-date-picker (datetimepicker)"
label="type: datetimepicker (default format)"
type="datetimepicker"
format="YYYY/MM/DD/HH/mm/ss"
placeholder="Choose Datetime"
/>
<div>selected value: {{ valueDateTime ? new Date(valueDateTime) : 'unselected' }}</div>
<div>selected value: {{ valueDateTime || 'unselected' }}</div>
</v-col>
<v-col cols="6">
<vx-range-picker
v-model="rangeValueDate"
label="vx-range-picker (datepicker)"
label="type: datepicker(default format YYYY-MM-DD)"
:placeholder="['Start at', 'End at']"
/>
<div>selected value: {{ rangeValueDate ? rangeValueDate : 'unselected' }}</div>
Expand All @@ -201,7 +201,7 @@ const rangeValueDateTime = ref(['', ''])
<v-col cols="6">
<vx-range-picker
v-model="rangeValueDateTime"
label="vx-range-picker (datetimepicker)"
label="type:datetimepicker (YYYY/MM/DD HH:mm)"
format="YYYY/MM/DD HH:mm"
type="datetimepicker"
:placeholder="['Start at', 'End at']"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
:model-value="datePickerValue"
:type="type"
@update:modelValue="emitDatePickerValue"
:format-str="formatStr"
:datePickerProps="datePickerProps"
/>
</v-overlay>
Expand Down Expand Up @@ -91,7 +92,7 @@ const minWidth = computed(() => ({
}))
watchEffect(() => {
convertValueForInputAndDatePicker(props.modelValue)
convertValueForInputAndDatePicker(props.modelValue, true)
})
function onInputBlur(obj: FocusEvent | string, closeMenu: boolean = false) {
Expand Down Expand Up @@ -140,7 +141,6 @@ function convertValueForInputAndDatePicker(
inputValue.value = formatStr ? dayjs(value).format(formatStr) : value
datePickerValue.value = value ? dayjs(value).valueOf() : ''
}
shouldEmit && emitDatePickerValue(datePickerValue.value)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
<time-select
v-if="useTimeSelect"
class="time-select-wrap"
:formatStr="formatStr"
v-model="timeStr"
v-bind="propsForTimeSelect"
@update:modelValue="onTimeSelected"
Expand All @@ -27,6 +28,7 @@ import dayjs from 'dayjs'
import { ref, defineEmits, defineProps, PropType, computed, watch, Prop } from 'vue'
import TimeSelect from './TimeSelect.vue'
import { useFilteredAttrs } from '@/lib/composables/useFilteredAttrs'
import { format } from 'path'
const { filteredAttrs } = useFilteredAttrs()
const emit = defineEmits(['update:modelValue'])
const props = defineProps({
Expand All @@ -36,6 +38,7 @@ const props = defineProps({
default: 'datepicker'
},
datePickerProps: Object as PropType<any>,
formatStr: String,
disableSecond: Boolean,
disableMinute: Boolean,
disableHour: Boolean
Expand All @@ -45,6 +48,7 @@ const dateOfPicker = ref()
const dateStr = computed(() => dayjs(dateOfPicker.value).format('YYYY-MM-DD'))
const useTimeSelect = computed(() => props.type === 'datetimepicker')
watch(
() => props.modelValue,
(value) => {
Expand Down
29 changes: 21 additions & 8 deletions ui/vuetifyx/vuetifyxjs/src/lib/Form/VXDatePicker/RangePicker.vue
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@
<date-picker-base
class="d-inline-block overflow-hidden"
:model-value="datePickerValue[0]"
:format="format"
:format-str="formatStr"
:type="type"
@update:modelValue="onDatePickerValueChange($event, 0)"
:date-picker-props="datePickerProps[0]"
Expand All @@ -82,7 +82,7 @@
<date-picker-base
class="d-inline-block overflow-hidden"
:model-value="datePickerValue[1]"
:format="format"
:format-str="formatStr"
:type="type"
@update:modelValue="onDatePickerValueChange($event, 1)"
:date-picker-props="datePickerProps[1]"
Expand All @@ -100,7 +100,7 @@
</template>

<script setup lang="ts">
import { defineEmits, ref, computed, PropType, watch } from 'vue'
import { defineEmits, ref, computed, PropType, watch, watchEffect } from 'vue'
import { useFilteredAttrs } from '@/lib/composables/useFilteredAttrs'
import datePickerBase from './DatePickerBase.vue'
import { useDatePicker, datePickerType } from '@/lib/composables/useDatePicker'
Expand Down Expand Up @@ -163,14 +163,27 @@ const showClearIcon = computed(
inputValue.value.some((item) => Boolean(item))
)
// this flag is used to format initial modelValue with formatStr
let onceEmitFlag = true
watch(
() => props.modelValue,
() => {
convertValueForInputAndDatePicker(props.modelValue)
// debugger
convertValueForInputAndDatePicker(props.modelValue, onceEmitFlag)
onceEmitFlag = false
},
{ immediate: true }
)
// func: reset all temporal datepicker selected data when showMenu is false
watch(showMenu, (value) => {
// console.log(value, 'showMenu')
if (!value) {
setTimeout(() => convertValueForInputAndDatePicker(props.modelValue), 300)
}
})
watch(
() => tempData,
(value) => {
Expand All @@ -190,10 +203,12 @@ function onDatePickerValueChange(value: number, position: 0 | 1) {
if (position === 0) data[0] = value
else data.push(value)
} else {
datePickerValue.value[position] = value
data = datePickerValue.value.map((item, i) => (position === i ? value : item))
}
emitDatePickerValue(data, props.needConfirm)
emitDatePickerValue(data, { needConfirm: props.needConfirm })
}
function convertValueForInputAndDatePicker(value: (string | number)[], shouldEmit?: boolean) {
Expand All @@ -207,15 +222,13 @@ function convertValueForInputAndDatePicker(value: (string | number)[], shouldEmi
? value.map((item) => (item ? dayjs(item).format(formatStr) : ''))
: value
datePickerValue.value = value.map((item) => (item ? dayjs(item).valueOf() : item))
// console.log(inputValue.value)
} else {
inputValue.value = formatStr ? [dayjs(value).format(formatStr)] : ['']
datePickerValue.value = [value ? dayjs(value).valueOf() : value]
}
}
shouldEmit && emitDatePickerValue(datePickerValue.value, props.needConfirm)
shouldEmit && emitDatePickerValue(datePickerValue.value, { needConfirm: props.needConfirm })
}
function onInputBlur(obj: FocusEvent | string | number, position: 0 | 1) {
Expand Down
37 changes: 30 additions & 7 deletions ui/vuetifyx/vuetifyxjs/src/lib/Form/VXDatePicker/TimeSelect.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<template>
<div class="vx-time-select-wrap">
<vx-field
v-show="showArea.hour"
ref="inputFieldHour"
v-model="hourValue"
class="time-select"
Expand Down Expand Up @@ -34,9 +35,10 @@
</v-menu>
</vx-field>

<span class="separate mx-2">:</span>
<span v-if="showArea.minute" class="separate mx-2">:</span>

<vx-field
v-show="showArea.minute"
ref="inputFieldMinute"
v-model="minuteValue"
class="time-select minute-field"
Expand Down Expand Up @@ -70,9 +72,10 @@
</v-menu>
</vx-field>

<span class="separate mx-2">:</span>
<span v-if="showArea.second" class="separate mx-2">:</span>

<vx-field
v-show="showArea.second"
ref="inputFieldSecond"
v-model="secondValue"
class="time-select second-field"
Expand Down Expand Up @@ -109,13 +112,14 @@
</template>

<script setup lang="ts">
import { ref, defineProps, watch, defineEmits, computed, useTemplateRef } from 'vue'
import { ref, defineProps, watch, defineEmits, computed } from 'vue'
const props = defineProps({
modelValue: {
type: String,
default: '00:00:00'
},
formatStr: String,
disableSecond: Boolean,
disableMinute: Boolean,
disableHour: Boolean
Expand Down Expand Up @@ -147,14 +151,33 @@ watch(
{ immediate: true }
)
function padZero(num: number): string {
return num < 10 ? `0${num}` : `${num}`
}
const payloadValue = computed(
() => `${padZero(hourValue.value)}:${padZero(minuteValue.value)}:${padZero(secondValue.value)}`
)
const showArea = computed(() => {
// 分析当前的formatStr 是否包含hour、minute、second
const formatStr = props.formatStr
if (!formatStr) {
return {
hour: false,
minute: false,
second: false
}
}
return {
hour: formatStr.includes('H') || formatStr.includes('h'),
minute: formatStr.includes('m'),
second: formatStr.includes('s')
}
})
function padZero(num: number): string {
return num < 10 ? `0${num}` : `${num}`
}
function onChooseValue(type: 'hour' | 'minute' | 'second', value: number) {
// console.log(type, value)
if (type === 'hour') {
Expand Down
4 changes: 0 additions & 4 deletions ui/vuetifyx/vuetifyxjs/src/lib/LinkageSelectRemote/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -157,10 +157,6 @@ const changeStatus = (val: any, level: number) => {
//@ts-ignore
parentIDValue[i] = parentValue(i)
}
if (value.value.every((x) => !x)) {
emit('update:modelValue', [])
return
}
emit('update:modelValue', value.value)
}
const parentValue = (level: number): string => {
Expand Down
Loading

0 comments on commit 4e1bf6f

Please sign in to comment.