<template>
|
<el-popover ref="input-select" v-model="showPopover" :disabled="disabled" :width="popoverWidth" :trigger="trigger" placement="bottom-start" popper-class="input-popover" @show="()=>{treeSuffixIcon='el-icon-yrt-xiangxiajiantou1 dropdown'}" @hide="()=>{treeSuffixIcon='el-icon-yrt-xiangxiajiantou1'}">
|
<el-input slot="reference" ref="input" v-model="currentValue" :style="{width: common.isNumber(inputWidth)?inputWidth+'px':inputWidth}" :placeholder="placeholder" :disabled="disabled" :suffix-icon="treeSuffixIcon" :size="size" class="input no-bg" @focus="(event)=>{onFocus($refs['input'], currentRow, event);}" @change="(val)=>{onInputChange($refs['input'], val);}" @keyup.native="(event)=>{onInputKeyup($refs['input'], event);}" @keydown.native="(event)=>{onInputKeydown($refs['input'], event);}">
|
</el-input>
|
<el-table ref="dropdownTable" :data="tableData" :max-height="tableMaxHeight" size="mini" highlight-current-row style="width: 100%" class="dropdown-table" @current-change="onCurrentChange" @row-click="onRowClick">
|
<el-table-column type="index" width="40" label="#">
|
</el-table-column>
|
<slot name="column">
|
<el-table-column v-for="(col, index) in columns" :key="index" :property="col.prop" :label="col.label" :width="col.width">
|
</el-table-column>
|
</slot>
|
</el-table>
|
</el-popover>
|
</template>
|
|
<script>
|
export default {
|
name: "input-select",
|
props: {
|
// 表单数据
|
formData: {
|
type: Object,
|
default: () => {
|
return {};
|
}
|
},
|
// 字段信息
|
field: {
|
type: Object,
|
default: () => {
|
return {};
|
}
|
},
|
// 下拉框绑定值
|
value: {
|
type: String,
|
default: null
|
},
|
// 字段中文名
|
label: {
|
type: String,
|
default: null
|
},
|
// 是否禁用
|
disabled: {
|
type: Boolean,
|
default: false
|
},
|
// 弹窗宽度
|
popoverWidth: {
|
type: [Number, String],
|
default: "400px"
|
},
|
// 表格宽度
|
tableMaxHeight: {
|
type: Number,
|
default: 300
|
},
|
// 输入框宽度
|
inputWidth: {
|
type: [Number, String],
|
default: "100%"
|
},
|
// 提示内容
|
placeholder: {
|
type: String,
|
default: null
|
},
|
// 配置选项
|
props: {
|
type: Object,
|
default: () => {
|
return {
|
label: "label",
|
value: "value"
|
};
|
}
|
},
|
// 表格数据
|
tableData: {
|
type: Array,
|
default: () => {
|
return [];
|
}
|
},
|
// 值字段名
|
valueField: {
|
type: String,
|
default: "value"
|
},
|
// 名称字段名
|
labelField: {
|
type: String,
|
default: "label"
|
},
|
// 输入框尺寸大小
|
size: {
|
type: String,
|
default: "medium"
|
},
|
// 弹出框触发事件方式
|
trigger: {
|
type: String,
|
default: "click"
|
},
|
// 字段列表
|
columns: {
|
type: Array,
|
default: () => {
|
return [];
|
}
|
}
|
},
|
data() {
|
return {
|
// TREE选择器右侧下拉框
|
treeSuffixIcon: "el-icon-yrt-xiangxiajiantou1",
|
// 是否显示下拉框
|
isShowPopover: false,
|
currentRow: null,
|
// 键盘按下时延时handle
|
searchHandle: null
|
};
|
},
|
computed: {
|
// 当前值
|
currentValue: {
|
get: function() {
|
return this.value;
|
},
|
set: function(val) {
|
this.$emit("input", val);
|
}
|
},
|
// 当前值
|
showPopover: {
|
get: function() {
|
return this.isShowPopover;
|
},
|
set: function(val) {
|
this.isShowPopover = val;
|
}
|
}
|
},
|
mounted() {
|
// 初始化下拉框数据
|
this.loadData(this.$refs.input, true);
|
},
|
methods: {
|
// input change事件
|
onInputChange(ref, val) {
|
this.$emit("on-change", ref, val);
|
},
|
// input keyup事件
|
onInputKeyup(ref, event) {
|
// Up key
|
if (event.keyCode === 38) {
|
let existIndex = this.tableData.findIndex(item => {
|
return item[this.labelField] === this.currentValue;
|
});
|
existIndex -= 1;
|
if (existIndex < 0) {
|
existIndex = this.tableData.length - 1;
|
}
|
const itemData = this.tableData.find((item, index) => {
|
return index === existIndex;
|
});
|
this.currentValue = itemData[this.labelField];
|
this.$refs.dropdownTable.setCurrentRow(itemData);
|
this.onRowChange(ref, itemData); // 自动设置值
|
this.$emit("on-row-change", ref, itemData, event);
|
return false;
|
}
|
// Down key
|
if (event.keyCode === 40) {
|
let existIndex = this.tableData.findIndex(item => {
|
return item[this.labelField] === this.currentValue;
|
});
|
existIndex += 1;
|
if (existIndex >= this.tableData.length) {
|
existIndex = 0;
|
}
|
const itemData = this.tableData.find((item, index) => {
|
return index === existIndex;
|
});
|
this.currentValue = itemData[this.labelField];
|
this.$refs.dropdownTable.setCurrentRow(itemData);
|
this.$emit("on-row-change", ref, itemData, event);
|
return false;
|
}
|
// Enter key
|
if (event.keyCode === 13) {
|
this.showPopover = !this.showPopover;
|
this.$refs.input.select();
|
this.$refs.input.focus();
|
return;
|
}
|
// 两次点击时差小于150ms,取消请求加载数据
|
if (this.searchHandle) {
|
clearTimeout(this.searchHandle);
|
this.searchHandle = null;
|
}
|
this.searchHandle = setTimeout(() => {
|
this.loadData(ref, event);
|
clearTimeout(this.searchHandle);
|
this.searchHandle = null;
|
}, 300);
|
this.$emit("on-key-up", ref, this.currentValue, event, this.tableData);
|
},
|
// input keydown事件
|
onInputKeydown(ref, event) {
|
this.$emit("on-key-down", ref, this.currentValue, event, this.tableData);
|
},
|
// 当值当前行
|
setCurrentIndex(existIndex) {
|
const itemData = this.tableData.find((item, index) => {
|
return index === existIndex;
|
});
|
if (itemData) {
|
this.currentValue = itemData[this.labelField];
|
this.$refs.dropdownTable.setCurrentRow(itemData);
|
}
|
// this.$refs["input-select"].doClose();
|
},
|
// 判断是否有选中项
|
getCurrrentIndex() {
|
const existIndex = this.tableData.findIndex(item => {
|
return item[this.labelField] === this.currentValue;
|
});
|
return existIndex;
|
},
|
// 关闭下拉框
|
doClose() {
|
this.$refs["input-select"].doClose();
|
},
|
// 获得焦点
|
onFocus(ref, val, event) {
|
var disabled = ref.$attrs.disabled;
|
if (disabled) return;
|
|
this.$emit("on-focus", ref, val, event);
|
},
|
// 当前行改变
|
onCurrentChange(val) {
|
if (!val) {
|
return;
|
}
|
this.currentRow = val;
|
this.currentValue = this.currentRow[this.labelField];
|
this.$emit("on-row-change", this.$refs.input, this.currentRow);
|
},
|
// 单击当前行
|
onRowClick(row, column, event) {
|
this.showPopover = false;
|
this.onRowChange(this.$refs.input, row); // 自动设置值
|
this.$emit("on-row-change", this.$refs.input, this.currentRow);
|
},
|
// 设置焦点
|
focus() {
|
this.$refs.input.focus();
|
},
|
// 下拉框输入改变后加载数据
|
loadData(ref, isInit) {
|
if (!this.field || !this.field.options) return;
|
|
const val = this.currentValue;
|
const url = this.field.options.url;
|
if (url) {
|
if (!val && !isInit) {
|
this.tableData = [];
|
return;
|
}
|
if (!this.field.options.searchFields) {
|
this.$message.error(`字段【${this.field.options.prop}】未设置查询字段!`);
|
return;
|
}
|
const params = {
|
name: val,
|
searchFields: this.field.options.searchFields.split(",")
|
};
|
this.common.ajax(url, params, res => {
|
this.common.showMsg(res);
|
this.tableData.length = 0;
|
if (res.result) {
|
res.data.forEach(item => {
|
this.$set(this.tableData, this.tableData.length, item);
|
});
|
}
|
});
|
}
|
},
|
// 物料名称下拉框行数据单击事件
|
onRowChange(ref, selectedRow) {
|
Object.keys(selectedRow).forEach(key => {
|
this.formData[key] = selectedRow[key];
|
});
|
}
|
}
|
};
|
</script>
|
|
<style lang="scss" scoped>
|
.input {
|
/deep/ .el-input__icon.el-icon-yrt-xiangxiajiantou1 {
|
transition: all 0.6s;
|
-moz-transition: all 0.6s; /* Firefox 4 */
|
-webkit-transition: all 0.6s; /* Safari and Chrome */
|
-o-transition: all 0.6s; /* Opera */
|
height: 36px;
|
&.dropdown {
|
transform: rotateZ(-180deg) translateY(3px);
|
-ms-transform: rotateZ(-180deg) translateY(3px); /* Internet Explorer */
|
-moz-transform: rotateZ(-180deg) translateY(3px); /* Firefox */
|
-webkit-transform: rotateZ(-180deg) translateY(3px); /* Safari 和 Chrome */
|
-o-transform: rotateZ(-180deg) translateY(3px); /* Opera */
|
}
|
}
|
&.el-input--mini {
|
/deep/ .el-input__icon.el-icon-yrt-xiangxiajiantou1 {
|
height: 33px;
|
}
|
}
|
/deep/ .el-input__suffix {
|
right: 1px;
|
}
|
}
|
.input-popover {
|
.el-popover__title {
|
margin-bottom: 0px;
|
}
|
.dropdown-table {
|
/deep/ .cell {
|
cursor: pointer;
|
}
|
}
|
}
|
</style>
|