410 lines
9.2 KiB
Vue
410 lines
9.2 KiB
Vue
<template>
|
||
<view style="width:100%;">
|
||
<input type="hidden" :name="name" :value="tvalue.value" style="display:none;" />
|
||
<template v-if="hasmore">
|
||
<checkbox-group :name="name+'_name'" style="display:none;">
|
||
<checkbox v-for="(item,index) in tvalue.names" :key="index" :value="item" checked />
|
||
</checkbox-group>
|
||
<checkbox-group :name="name+'_id'" style="display:none;">
|
||
<checkbox v-for="(item,index) in tvalue.ids" :key="index" :value="item" checked />
|
||
</checkbox-group>
|
||
</template>
|
||
<view class="_show" @tap="showhide(true)" :class="{_disabled:disabled}">
|
||
<slot name="list" :data="{value:tvalue, range:range}">
|
||
<view class="_defshow" :class="{_left:left}">
|
||
<template v-for="(item,index) in tvalue.sels" :key="index">
|
||
<view style="padding-left:0.3em;" v-if="index>0">~</view>
|
||
<view class="itm" v-if="item.id > 0">{{item.name}}</view>
|
||
</template>
|
||
<view class="itm" v-if="tvalue.sels.length == 0">{{placeholder?placeholder:lang('placeholder.select')}}</view>
|
||
</view>
|
||
</slot>
|
||
</view>
|
||
<ciy-anipop v-model="popsh">
|
||
<view class="_pop">
|
||
<view class="_op">
|
||
<view class="_cata">
|
||
<template v-for="(item,index) in openvalue.sels" :key="index">
|
||
<view v-if="item.high" class="itm _level">{{item.name}}</view>
|
||
<view v-else @tap="sellevel(index)" class="itm">{{item.name}}</view>
|
||
</template>
|
||
</view>
|
||
<view>
|
||
<button class="btn sm def" @tap="selclear" v-if="clearbtn">{{lang('selcas.clear')}}</button>
|
||
<button class="btn sm" @tap="seldone">{{lang('selcas.done')}}</button>
|
||
</view>
|
||
</view>
|
||
<view class="_list">
|
||
<template v-for="(item,index) in range" :key="index">
|
||
<view class="itm" @tap="selandnext(index)" v-if="(!chkuse || item.isuse != 2) && item.upid == openvalue.upval" :class="{select:item.id == openvalue.value}">
|
||
{{item.name}}
|
||
</view>
|
||
</template>
|
||
</view>
|
||
</view>
|
||
</ciy-anipop>
|
||
</view>
|
||
</template>
|
||
|
||
<style scoped>
|
||
._defshow {
|
||
display: flex;
|
||
justify-content: flex-end;
|
||
flex-wrap: wrap;
|
||
}
|
||
|
||
._defshow._left {
|
||
justify-content: flex-start;
|
||
}
|
||
|
||
._defshow>.itm {
|
||
padding-left: 0.3em;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
._show._disabled {
|
||
color: #cccccc;
|
||
}
|
||
|
||
._pop {
|
||
display: flex;
|
||
z-index: 1;
|
||
flex-direction: column;
|
||
background: var(--bg2);
|
||
border-top: 1px solid var(--bg6);
|
||
padding: 0.5em;
|
||
border-radius: 1em 1em 0 0;
|
||
height: 60vh;
|
||
}
|
||
|
||
._pop ._op {
|
||
display: flex;
|
||
}
|
||
|
||
._pop ._op ._cata {
|
||
flex: 1;
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
margin-top: 0.3em;
|
||
}
|
||
|
||
._pop ._op ._cata>.itm {
|
||
white-space: nowrap;
|
||
}
|
||
|
||
._pop ._op ._cata>.itm:first-child::before {
|
||
content: "";
|
||
display: none;
|
||
}
|
||
|
||
._pop ._op ._cata>.itm::before {
|
||
content: "";
|
||
vertical-align: middle;
|
||
display: inline-block;
|
||
width: 0.7em;
|
||
height: 0.7em;
|
||
background-image: url("data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMTAyNCAxMDI0IiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgZGF0YS1zcG0tYW5jaG9yLWlkPSJhMzEzeC5zZWFyY2hfaW5kZXguMC5pMy40MTE0M2E4MThFZlpjRiI+PHBhdGggZD0iTTM1OC42NzggODJMMjk2IDE0NC42NDZsMzUxLjg3IDM1MS42OTNjNy45ODggNy45ODQgOC42MDMgMjAuNTQ3IDEuODQzIDI5LjIzNmwtMS44NDMgMi4wODdMMjk2IDg3OS4zNTQgMzU4LjY3OCA5NDJsMzUxLjg3LTM1MS42OTJjNDEuOTU4LTQxLjkzOCA0My4yMy0xMDkuMTQyIDMuODE0LTE1Mi42MTFsLTMuODE0LTQuMDA1TDM1OC42NzggODJ6IiBkYXRhLXNwbS1hbmNob3ItaWQ9ImEzMTN4LnNlYXJjaF9pbmRleC4wLmkxLjQxMTQzYTgxOEVmWmNGIiBmaWxsPSIjNzc3Nzc3Ij48L3BhdGg+PC9zdmc+");
|
||
}
|
||
|
||
._pop ._op ._cata ._level {
|
||
color: var(--man5);
|
||
}
|
||
|
||
|
||
._pop ._list {
|
||
flex: 1;
|
||
text-align: left;
|
||
overflow: auto;
|
||
padding: 1em 0.5em 0 0.5em;
|
||
}
|
||
|
||
._pop ._list>.itm {
|
||
min-height: 3em;
|
||
}
|
||
|
||
._pop ._list>.itm.select {
|
||
color: var(--man5);
|
||
}
|
||
</style>
|
||
<script>
|
||
export default {
|
||
behaviors: ['uni://form-field-group'],
|
||
emits: ['change', 'update:modelValue', 'loaddata'],
|
||
props: {
|
||
name: {
|
||
type: String
|
||
},
|
||
modelValue: {
|
||
type: [String, Number],
|
||
default: ''
|
||
},
|
||
value: {
|
||
type: [String, Number],
|
||
default: ''
|
||
},
|
||
initevent: {
|
||
type: Boolean,
|
||
default: false
|
||
},
|
||
hasmore: {
|
||
type: Boolean,
|
||
default: false
|
||
},
|
||
chkuse: {
|
||
type: Boolean,
|
||
default: false
|
||
},
|
||
range: {
|
||
type: Array,
|
||
default: []
|
||
},
|
||
left: {
|
||
type: Boolean,
|
||
default: false
|
||
},
|
||
disabled: {
|
||
type: Boolean,
|
||
default: false
|
||
},
|
||
placeholder: {
|
||
type: String
|
||
},
|
||
clearbtn: {
|
||
type: Boolean,
|
||
default: false
|
||
},
|
||
rootupid: {
|
||
type: [String, Number],
|
||
default: undefined
|
||
},
|
||
asyncdata: {
|
||
type: Boolean,
|
||
default: false
|
||
},
|
||
allowpart: { //允许选择部分
|
||
type: Boolean,
|
||
default: false
|
||
}
|
||
},
|
||
data() {
|
||
return {
|
||
v: '',
|
||
editval: {
|
||
value: 0,
|
||
enext: false
|
||
}, //当前值,用于openvalue计算
|
||
popsh: false
|
||
};
|
||
},
|
||
watch: {
|
||
value: {
|
||
handler(newD, oldD) {
|
||
if (newD || oldD)
|
||
this.v = 'value';
|
||
if (newD) {
|
||
this.$emit('update:modelValue', newD);
|
||
if (this.initevent) {
|
||
this.$emit('change', {
|
||
name: this.name,
|
||
from: 'init',
|
||
value: newD,
|
||
selvalue: {}
|
||
});
|
||
}
|
||
}
|
||
},
|
||
immediate: true
|
||
},
|
||
modelValue: {
|
||
handler(newD, oldD) {
|
||
if (newD || oldD)
|
||
this.v = 'modelValue';
|
||
if (newD) {
|
||
this.$emit('update:modelValue', newD);
|
||
if (this.initevent) {
|
||
this.$emit('change', {
|
||
name: this.name,
|
||
from: 'init',
|
||
value: newD,
|
||
selvalue: {}
|
||
});
|
||
}
|
||
}
|
||
},
|
||
immediate: true
|
||
}
|
||
},
|
||
computed: {
|
||
tvalue() { //当前选项链
|
||
var val = '';
|
||
if (this.v == 'modelValue') {
|
||
val = this.modelValue;
|
||
} else if (this.v == 'value') {
|
||
val = this.value;
|
||
} else {
|
||
val = this.v;
|
||
}
|
||
var vals = [];
|
||
var tval = {};
|
||
var fillvid = id => {
|
||
for (var i in this.range) {
|
||
if (this.range[i].id == id) {
|
||
fillvid(this.range[i].upid);
|
||
vals.push({
|
||
...this.range[i]
|
||
});
|
||
}
|
||
}
|
||
}
|
||
fillvid(val);
|
||
tval.sels = vals;
|
||
tval.value = val;
|
||
if (vals.length == 0) {
|
||
tval.upval = this.rootupid;
|
||
} else {
|
||
tval.upval = vals[vals.length - 1].upid;
|
||
}
|
||
var idarr = [];
|
||
var namearr = [];
|
||
for (var i in tval.sels) {
|
||
idarr.push(tval.sels[i].id + '');
|
||
namearr.push(tval.sels[i].name + '');
|
||
}
|
||
tval.names = namearr;
|
||
tval.ids = idarr;
|
||
return tval;
|
||
},
|
||
openvalue() { //中间数据
|
||
var val = this.editval.value;
|
||
var oval = {};
|
||
var vals = [];
|
||
var fillvid = id => {
|
||
for (var i in this.range) {
|
||
if (this.range[i].id == id) {
|
||
fillvid(this.range[i].upid);
|
||
vals.push({
|
||
...this.range[i]
|
||
});
|
||
}
|
||
}
|
||
}
|
||
fillvid(val);
|
||
if (this.editval.enext) {
|
||
var hasnext = this.arrayfind(this.range, this.editval.value, 'upid');
|
||
if (hasnext > -1)
|
||
vals.push({
|
||
id: this.editval.value,
|
||
upid: this.editval.value,
|
||
high: true,
|
||
name: this.placeholder
|
||
});
|
||
else
|
||
vals[vals.length - 1].high = true;
|
||
} else {
|
||
if (vals.length > 0)
|
||
vals[vals.length - 1].high = true;
|
||
else
|
||
vals.push({
|
||
id: this.editval.value,
|
||
upid: this.rootupid,
|
||
high: true,
|
||
name: this.placeholder
|
||
});
|
||
}
|
||
if (vals.length == 0) {
|
||
oval.upval = this.rootupid;
|
||
val = this.rootupid;
|
||
} else {
|
||
oval.upval = vals[vals.length - 1].upid;
|
||
}
|
||
oval.sels = vals;
|
||
oval.value = val;
|
||
return oval;
|
||
}
|
||
},
|
||
mounted() {},
|
||
methods: {
|
||
showhide(bsh) {
|
||
if (this.disabled)
|
||
return;
|
||
this.popsh = !this.popsh;
|
||
if (this.popsh) {
|
||
this._runajax = false;
|
||
this.editval = {
|
||
value: this.tvalue.value,
|
||
enext: false
|
||
};
|
||
}
|
||
},
|
||
sellevel(idx) {
|
||
this._runajax = false;
|
||
this.editval = {
|
||
value: this.openvalue.sels[idx].id,
|
||
enext: false
|
||
};
|
||
},
|
||
selandnext(idx) {
|
||
this._runajax = false;
|
||
if (this.asyncdata) {
|
||
if (!this.range[idx]._ajax) {
|
||
this.range[idx]._ajax = true;
|
||
var hasnext = this.arrayfind(this.range, this.range[idx].id, 'upid');
|
||
if (hasnext == -1) {
|
||
(index => {
|
||
this._runajax = true;
|
||
this.$emit('loaddata', {
|
||
range: this.range[index],
|
||
success: () => {
|
||
if (this._runajax)
|
||
this.selandnext(index);
|
||
},
|
||
fail: () => {
|
||
this.range[index]._ajax = false;
|
||
}
|
||
});
|
||
})(idx);
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
this.editval = {
|
||
value: this.range[idx].id,
|
||
enext: true
|
||
};
|
||
},
|
||
selclear() {
|
||
this.$emit('update:modelValue', 0);
|
||
this.$emit('change', {
|
||
name: this.name,
|
||
from: 'clear',
|
||
value: 0,
|
||
selvalue: {}
|
||
});
|
||
this.v = 0;
|
||
this.popsh = false;
|
||
},
|
||
seldone() {
|
||
for (var i = this.openvalue.sels.length - 1; i >= 0; i--) {
|
||
if (this.openvalue.sels[i].id == 0)
|
||
continue;
|
||
var hasnext = this.arrayfind(this.range, this.openvalue.sels[i].id, 'upid');
|
||
if (hasnext > -1 && !this.allowpart)
|
||
return this.selandnext(hasnext);
|
||
var thisv = this.openvalue.sels[i];
|
||
this.$emit('update:modelValue', thisv.id);
|
||
this.$emit('change', {
|
||
name: this.name,
|
||
from: 'done',
|
||
value: thisv.id,
|
||
selvalue: {
|
||
...thisv
|
||
}
|
||
});
|
||
this.v = thisv.id;
|
||
this.popsh = false;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</script> |