c5_labsci/fapp/ciyon_ap/components/ciy-inputdatetime/ciy-inputdatetime.vue

543 lines
13 KiB
Vue
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view style="position: relative;">
<input type="hidden" :name="name" :value="tostamp(tvalue)" style="display:none;" />
<input v-if="hasmore" type="hidden" :name="name+'_date'" :value="todatetime(tvalue,btime?'':(selectmonth?'m':'d'))" style="display:none;" />
<view class="_show" :class="{_left:left,_disabled:disabled}" @tap="showpop" v-if="tostamp(tvalue)==0" style="color:var(--txt1)">{{placeholder===undefined?lang('placeholder.select'):placeholder}}</view>
<view class="_show" :class="{_left:left,_disabled:disabled}" @tap="showpop" v-else>{{todatetime(tvalue,btime?'':(selectmonth?'m':'d'))}}</view>
<view class="_mask" v-if="popclass" @tap="hidepop"></view>
<view class="_pop" :animation="anidatapop" v-if="popclass" :class="popclass">
<view class="_main" :class="popclass">
<view class="ciy-hr" style="flex:none;"></view>
<ciy-calendar :selectmonth="selectmonth" :value="vdate" @change="chgcalendar" v-if="cpage == 0" name="tp" :mindate="mindate" :maxdate="maxdate" :weekmonday="weekmonday" :selectbg="selectbg" :bordercolor="bordercolor" :selecttextcolor="selecttextcolor" :clearbtn="clearbtn"></ciy-calendar>
<view v-if="cpage == 1" class="_shour">
<view class="itm" v-for="(_,val) in 24" @tap="clkhour(val)" :style="val==vhour?'font-weight:bolder;color:var(--man5);':''">
{{val}}
</view>
</view>
<view v-if="cpage == 2" class="_smin" :class="popclass">
<view class="_smin2">
<view class="itm" v-for="(_,val) in 10" @tap="clkmin2(val)" :style="val==vminute2?'font-weight:bolder;color:var(--man5);':''">
{{val}}
</view>
</view>
<view class="ciy-hr"></view>
<view class="_smin1">
<view class="itm" v-for="(_,val) in 6" @tap="clkmin1(val)" :style="val==vminute1?'font-weight:bolder;color:var(--man5);':''">
{{val*10}}
</view>
</view>
</view>
<view class="_selcard" v-if="btime">
<view class="itm" :class="{_sel:cpage==0}" @tap="clkpage(0)">
<view>{{todatetime(vdate,'y', ' ')}}</view>
<view>{{todatetime(vdate,'x', ' ')}}</view>
<view class="_txt">{{lang('inputdate.date')}}</view>
</view>
<view class="itm" :class="{_sel:cpage==1}" @tap="clkpage(1)">
<view style="font-size:2em;">{{topad0(vhour,2)}}</view>
<view class="_txt">{{lang('inputdate.hour')}}</view>
</view>
<view class="itm" :class="{_sel:cpage==2}" @tap="clkpage(2)">
<view style="font-size:2em;">{{topad0(vminute1*10+vminute2,2)}}</view>
<view class="_txt">{{lang('inputdate.minute')}}</view>
</view>
<view class="itm _bbtn" :class="popclass">
<view class="btn def" @tap="today">{{lang('inputdate.now')}}</view>
<view class="btn" @tap="done">{{lang('inputdate.done')}}</view>
</view>
</view>
<view class="ciy-hr"></view>
</view>
</view>
</view>
</template>
<script>
export default {
behaviors: ['uni://form-field-group'],
emits: ['change', 'update:modelValue'],
props: {
name: {
type: String
},
modelValue: {
type: [String, Number, Date],
default: ''
},
value: {
type: [String, Number, Date],
default: ''
},
disabled: {
type: Boolean,
default: false
},
initevent: {
type: Boolean,
default: false
},
hasmore: {
type: Boolean,
default: false
},
placeholder: {
type: String
},
btime: {
type: Boolean,
default: false
},
left: {
type: Boolean,
default: false
},
bordercolor: {
type: String,
default: 'var(--bg6)'
},
selecttextcolor: {
type: String,
default: 'var(--man5)'
},
selectbg: {
type: String,
default: 'var(--bg1)'
},
selectmonth: {
type: Boolean,
default: false
},
weekmonday: {
type: Boolean,
default: false
},
mindate: {
type: [String, Number, Date],
default: ''
},
maxdate: {
type: [String, Number, Date],
default: ''
},
clearbtn: {
type: Boolean,
default: false
},
diastema: { //间隙
type: Number,
default: 16
},
},
data() {
return {
v: '',
vdate: 0,
vhour: 0,
vminute1: 0,
vminute2: 0,
cpage: 0,
anidatapop: {},
popclass: ''
};
},
watch: {
value: {
handler(newD, oldD) {
if (newD || oldD)
this.v = 'value';
},
immediate: true
},
modelValue: {
handler(newD, oldD) {
if (newD || oldD)
this.v = 'modelValue';
},
immediate: true
}
},
computed: {
tvalue() {
var val = '';
if (this.v == 'modelValue') {
if (typeof(this.modelValue) == 'number')
val = new Date(this.modelValue * 1000);
else if (this.modelValue)
val = this.modelValue;
} else if (this.v == 'value') {
if (typeof(this.value) == 'number')
val = new Date(this.value * 1000);
else if (this.value)
val = this.value;
} else {
val = this.v;
}
if (!(val instanceof Date)) {
if (val.indexOf('-') > -1 || val.indexOf('/') > -1) {
val = this.str2date(val);
} else {
val = this.toint(val);
val = new Date(val * 1000);
}
} else if (isNaN(val.getTime()))
val = new Date();
return val;
},
max() {
var val = this.maxdate;
if (val instanceof Date) {
if (isNaN(val.getTime()))
val = null;
} else if (typeof(val) == 'number') {
val = new Date(val * 1000);
} else if (val.indexOf('-') > -1 || val.indexOf('/') > -1) {
val = this.str2date(val);
} else if (val == 'now') {
val = new Date();
} else {
val = this.toint(val);
if (val == 0)
val = null;
else
val = new Date(val * 1000);
}
return val;
},
min() {
var val = this.mindate;
if (val instanceof Date) {
if (isNaN(val.getTime()))
val = null;
} else if (typeof(val) == 'number') {
val = new Date(val * 1000);
} else if (val.indexOf('-') > -1 || val.indexOf('/') > -1) {
val = this.str2date(val);
} else if (val == 'now') {
val = new Date();
} else {
val = this.toint(val);
if (val == 0)
val = null;
else
val = new Date(val * 1000);
}
return val;
}
},
mounted() {
// var vd = new Date(this.tvalue.getFullYear(), this.tvalue.getMonth(), this.tvalue.getDate());
// vd.setMinutes(-vd.getTimezoneOffset());
// this.vdate = this.tostamp(vd);
var date = this.tostamp(this.onlydate(this.tvalue));
this.vdate = date;
this.vhour = this.tvalue.getHours();
var minute = this.tvalue.getMinutes();
this.vminute1 = parseInt(minute / 10);
this.vminute2 = minute - this.vminute1 * 10;
if (this.vdate == 0 && this.vhour == 8)
this.vhour = 0;
if (this.initevent) {
this.emit('init', this.tvalue, true);
}
},
methods: {
onlydate(val) {
var dt = new Date(val.toLocaleDateString());
dt.setMinutes(-dt.getTimezoneOffset());
return dt;
},
chgcalendar(e) {
var from = 'calendar'; //false 同步value到父
if (!this.btime || e.from == 'today' || e.from == 'nodate')
from = 'done';
if (from == 'done') {
setTimeout(() => {
this.hidepop();
}, 300);
}
if (e.from == 'nodate') {
this.vhour = 0;
this.vminute1 = 0;
this.vminute2 = 0;
}
this.vdate = e.value;
this.updatevalue(from);
},
updatevalue(from) {
var d = new Date(this.vdate * 1000);
if (this.vdate != 0) {
d.setHours(this.vhour);
d.setMinutes(this.vminute1 * 10 + this.vminute2);
}
if (d.getTime() == this.tvalue.getTime())
return;
this.emit(from, d);
},
emit(from, date) {
if (!this.btime) {
var date = new Date(date.getTime());
if (date.getTime() != 0) {
date.setHours(0);
date.setMinutes(0);
date.setSeconds(0);
}
}
// if (date.getFullYear() == 1970 && date.getMonth() == 0 && date.getDate() == 1)
// date.setMinutes(-date.getTimezoneOffset());
var stramp = this.tostamp(date);
if (from == 'done') {
this.$emit('update:modelValue', stramp);
this.v = date;
}
this.$emit('change', {
name: this.name,
from: from,
value: stramp,
date: date
});
},
today() {
var dt = new Date();
this.vhour = dt.getHours();
var min = dt.getMinutes();
this.vminute1 = parseInt(min / 10);
this.vminute2 = min - parseInt(min / 10) * 10;
dt.setSeconds(0);
this.vdate = this.tostamp(dt);
//this.updatevalue('today', this.vdate, true);
},
done() {
var date = new Date(this.vdate * 1000);
if (this.vdate != 0) {
date.setHours(this.vhour);
date.setMinutes(this.vminute1 * 10 + this.vminute2);
date.setSeconds(0);
}
this.emit('done', date);
this.hidepop();
},
clkhour(val) {
this.vhour = val;
this.updatevalue('hour');
},
clkmin1(val) {
this.vminute1 = val;
this.updatevalue('minute');
},
clkmin2(val) {
this.vminute2 = val;
this.updatevalue('minute');
},
clkpage(page) {
this.cpage = page;
},
hidepop() {
var app = getApp();
var animation = uni.createAnimation({});
animation.translateX('100vw');
animation.opacity(0);
animation.step({
duration: 200
});
this.anidatapop = animation.export();
setTimeout(() => {
this.popclass = '';
}, 300);
},
async showpop() {
if (this.disabled)
return;
if (this.popclass) {
return this.hidepop();
}
var app = getApp();
app.globalData.scrollcbs['com_datetime'] = e => {
delete app.globalData.scrollcbs['com_datetime'];
this.hidepop();
};
const {
headerheight,
footerheight
} = await this.com_gethdft();
var fixtop = 0;
if (this.fix) {
//向上遍历页面中带fixed和absolute的父元素累加top。
}
this.cpage = 0;
// if (this.tvalue.getTime() == 0)
// this.vdate = this.tostamp();
var showrect = await this.getrect('._show');
if (!showrect) {
return;
}
this.popclass = 'temp';
var mainrect = await this.getrect('._main');
if (!mainrect)
return;
this.vdate = this.tostamp(this.tvalue);
if (this.vdate != 0) {
this.vhour = this.tvalue.getHours();
var minute = this.tvalue.getMinutes();
this.vminute1 = parseInt(minute / 10);
this.vminute2 = minute - this.vminute1 * 10;
} else {
this.vhour = 0;
this.vminute1 = 0;
this.vminute2 = 0;
}
var bott = app.globalData._sysinfo.windowHeight - showrect.bottom - footerheight - this.diastema;
var topcls = '_btm';
var sytop = showrect.bottom + this.diastema - fixtop;
if (bott < mainrect.height) {
sytop = showrect.top - this.diastema - mainrect.height;
if (sytop < headerheight + fixtop)
sytop = headerheight + fixtop;
topcls = '_top';
}
this.popclass = topcls;
this.$nextTick(() => {
var animation = uni.createAnimation({});
animation.translateX(0);
animation.top(sytop);
animation.opacity(1);
animation.step({
duration: 200
});
this.anidatapop = animation.export();
});
}
}
}
</script>
<style scoped>
._show {
white-space: nowrap;
}
._show._left {
text-align: left;
}
._show._disabled {
color: var(--bg7);
}
._smin {
display: flex;
flex-wrap: wrap;
width: 100%;
}
._smin1 {
display: flex;
flex-wrap: wrap;
line-height: 7em;
width: 100%;
}
._smin1>.itm {
text-align: center;
flex: 0 0 16.667%;
}
._smin2 {
display: flex;
flex-wrap: wrap;
line-height: 7em;
width: 100%;
}
._smin2>.itm {
text-align: center;
flex: 0 0 20%;
}
._shour {
display: flex;
flex-wrap: wrap;
line-height: 5.5em;
width: 100%;
}
._shour>.itm {
text-align: center;
flex: 0 0 16.6666%;
}
._selcard {
display: flex;
width: calc(100% - 1em);
margin: 0.5em;
white-space: nowrap;
gap: 0.3em;
}
._selcard ._sel {
background: linear-gradient(33deg, var(--bg1), var(--bg4));
border-radius: 0.5em;
border: 1px solid var(--bg6);
}
._selcard ._txt {
color: var(--txt1);
}
._selcard>.itm {
flex: 1;
text-align: center;
padding: 0.5em 0;
border: 1px solid transparent;
transition: all 0.3s;
height: 5em;
display: flex;
flex-direction: column;
justify-content: flex-end;
}
._selcard ._bbtn {
position: relative;
padding: 0;
display: flex;
flex-direction: column;
flex: none;
}
._pop {
position: fixed;
display: flex;
flex-direction: column;
align-items: flex-start;
transform: translateX(100vw);
opacity: 0;
left: 0;
right: 0;
z-index: 50001;
}
._pop ._main {
background: var(--bg2);
width: 100%;
display: flex;
flex-direction: column;
}
._btm,
._pop ._main._btm,
._selcard ._bbtn._btm {
justify-content: flex-end;
flex-direction: column-reverse;
}
._mask {
position: fixed;
left: 0;
right: 0;
bottom: 0;
top: 0;
z-index: 50001;
flex: 1;
backgroundx: #f3abec99;
}
</style>