Commit e1af7026 by fukai

支持多行文本输入

parent 8474dcb8
<template>
<el-input ref="input" :id="id" type="textarea"
:cols="cols"
:rows="rows"
v-bind="attrs" v-bind:disabled="isDisable"
:value="value"
@input="onInput($event,value)"
>
<template v-slot:suffix>
<slot name="suffix"></slot>
</template>
</el-input>
</template>
<script>
const SP_STR = "✌";
const SP_CHAR=SP_STR.charCodeAt(0);
const LINE_CHAR="\n"
const SWIFT_CHARS = " \r'()+,-./01234567890:?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
const SWIFTZ_CHARS = " \r!\"#%&'()+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz{";
const CHARSET = ["","",SWIFT_CHARS,SWIFTZ_CHARS]
export default {
props: {
value: {
type: [String, Number],
default: undefined
},
disabled: {
type: Boolean,
default: false
},
id: {
type: String,
default: undefined
},
cols:{
type:Number,
default:1
},
rows:{
type:Number,
default:1
},
chsbit:{
type:Number,
default:2
},
charmod:{
type:Number,
default:0 //0任意模式,1英文模式,2 swift模式 3 swiftz模式
}
},
computed: {
model: {
get () {
return this.value
},
set (newVal) {
newVal = this.formatVal(newVal);
console.log(newVal)
this.$emit('input', newVal)
setTimeout(()=>{
this.setCursorPosition(this.$position)
},0)
}
},
mode () {
return this.$store.state.Status.mode
},
isDisable: {
get () {
return this.mode === 'display' || this.disabled
}
},
highlight () {
return this.$store.state.Status.highlights.indexOf(this.id) !== -1
},
highlightChanges () {
return this.$store.state.Status.highlightChanges.indexOf(this.id) !== -1
},
attrs(){
if(this.mode === 'display' || this.disabled)
{
let {placeholder,...rest} = this.$attrs
return rest
}
return this.$attrs
}
},
methods:{
formatVal(oriVal){
let val = oriVal;
if(!val){
return val;
}
let position = this.getCursorPosition();
val = val.substring(0,position)+SP_STR+val.substring(position)
let arr = val.split(/\r?\n|\r/g);
let arrNew = [];
arr.forEach(line=>{
let lineArr = this.formatLine(line);
arrNew.push(...lineArr);
});
if(arrNew.length > this.rows){
let obj = this.getTextarea();
//内容已经输满了
if(obj.selectionStart == obj.selectionEnd && oriVal.length == this.value.length+1){
this.$position = position - 1;
return this.value;
}
arrNew = arrNew.slice(0,this.rows);
}
let result = arrNew.join(LINE_CHAR);
position = result.indexOf(SP_STR);
result = result.substring(0,position)+result.substring(position+1);
this.$position = position
return result;
},
formatLine(val){
if(!val){
return [""];
}
if(val == SP_STR){
return [SP_STR]
}
let valCopy = val;
let newVal = [];
while(valCopy && valCopy!=SP_STR){
let length = 0;
let i=0;
let spCnt =0;
let autoLine = "";
for(; i<valCopy.length && i<this.cols+spCnt && length<this.cols; i++) {
var c = valCopy.charCodeAt(i);
let cStr = valCopy.charAt(i);
if(c == SP_CHAR){
spCnt++;
autoLine+=SP_STR;
continue;
}
else if ((c >= 0x0001 && c <= 0x007e) || ( c >= 0xff60 && c <= 0xff9f )){
//判断字符集
if(this.charmod>1 && CHARSET[this.charmod].indexOf(cStr)==-1){
spCnt++;
//非法字符集
continue;
}
length ++;
autoLine+=cStr;
}
else if(length <= this.cols - this.chsbit){
//中文字符
if(this.charmod){
spCnt++;
//非法字符集
continue;
}
length += this.chsbit;
autoLine+=cStr;
}
else{
break;
}
}
//autoLine = valCopy.substring(0,i);
newVal.push(autoLine);
valCopy = valCopy.substring(i);
}
//不要丢失光标
if(valCopy == SP_STR){
newVal[newVal.length - 1] = newVal[newVal.length - 1]+SP_STR;
}
return newVal;
},
getTextarea(){
return this.$refs.input.$el.children[0];
},
getCursorPosition(){
let obj = this.getTextarea();
let position = obj.selectionStart
return position;
},
setCursorPosition(position){
let obj = this.getTextarea();
if(obj.createTextRange) {
var tr = obj.createTextRange();
tr.collapse(true);
tr.moveStart('character', position);
tr.select();
}
else if (obj.setSelectionRange)
obj.setSelectionRange(position, position);
},
onInput(newVal){
let extraCnt = 0;
if(this.value && newVal.length == this.value.length -1 ){
let obj = this.getTextarea();
if(obj.selectionStart == obj.selectionEnd && obj.selectionStart<newVal.length && this.value.charAt(obj.selectionStart)=="\n"){
//删除中间换行符,额外再筛除一个字符,避免被重新格式化
newVal = newVal.substring(0,obj.selectionStart - 1)+newVal.substring(obj.selectionStart)
extraCnt = -2;
}
}
newVal = this.formatVal(newVal);
console.log(newVal)
this.$emitNewValue = newVal;
this.$emit('input', newVal)
setTimeout(()=>{
this.setCursorPosition(this.$position+extraCnt)
},0)
}
},
watch:{
cols(){
let newVal = this.formatVal(this.value);
this.$emitNewValue = newVal;
this.$emit('input', newVal)
},
rows(){
let newVal = this.formatVal(this.value);
this.$emitNewValue = newVal;
this.$emit('input', newVal)
},
value(val,oldval){
if(val == this.$emitNewValue){
return;
}
let newVal = this.formatVal(val);
this.$emit('input', newVal);
}
}
}
</script>
<style>
/* .el-input.highlight .el-input__inner{
border-color: red;
}
.el-textarea.highlight .el-textarea__inner {
border-color: red;
}
.el-input.change-light .el-input__inner{
border-color: #E6A23C;
}
.el-textarea.change-light .el-textarea__inner {
border-color: #E6A23C;
} */
</style>
\ No newline at end of file
......@@ -54,6 +54,7 @@ import CompareTable from "./CompareTable"
import InputXml from "./InputXml.vue"
import PagingTable from "./PagingTable.vue";
import MulRowInput from "./MulRowInput.vue"
export default {
install(Vue) {
......@@ -109,5 +110,6 @@ export default {
Vue.component("c-compare-table", CompareTable)
Vue.component("c-input-xml", InputXml)
Vue.component("c-paging-table", PagingTable)
Vue.component("c-mul-row-input", MulRowInput)
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment