feat: add set and get control value api #278
This commit is contained in:
@@ -813,3 +813,13 @@ Usage:
|
||||
```javascript
|
||||
instance.command.executeLocationGroup(groupId: string)
|
||||
```
|
||||
|
||||
## executeSetControlValue
|
||||
|
||||
Feature: Set control value
|
||||
|
||||
Usage:
|
||||
|
||||
```javascript
|
||||
instance.command.executeSetControlValue(payload: ISetControlOption)
|
||||
```
|
||||
|
||||
@@ -178,3 +178,16 @@ Usage:
|
||||
```javascript
|
||||
const groupIds = await instance.command.getGroupIds()
|
||||
```
|
||||
|
||||
## getControlValue
|
||||
|
||||
Feature: Get control value
|
||||
|
||||
Usage:
|
||||
|
||||
```javascript
|
||||
const {
|
||||
value: string | null
|
||||
innerText: string | null
|
||||
} = await instance.command.getControlValue(payload: IGetControlValueOption)
|
||||
```
|
||||
|
||||
@@ -813,3 +813,13 @@ instance.command.executeDeleteGroup(groupId: string)
|
||||
```javascript
|
||||
instance.command.executeLocationGroup(groupId: string)
|
||||
```
|
||||
|
||||
## executeSetControlValue
|
||||
|
||||
功能:设置控件值
|
||||
|
||||
用法:
|
||||
|
||||
```javascript
|
||||
instance.command.executeSetControlValue(payload: ISetControlOption)
|
||||
```
|
||||
|
||||
@@ -178,3 +178,16 @@ const locale = await instance.command.getLocale()
|
||||
```javascript
|
||||
const groupIds = await instance.command.getGroupIds()
|
||||
```
|
||||
|
||||
## getControlValue
|
||||
|
||||
功能:获取控件值
|
||||
|
||||
用法:
|
||||
|
||||
```javascript
|
||||
const {
|
||||
value: string | null
|
||||
innerText: string | null
|
||||
} = await instance.command.getControlValue(payload: IGetControlValueOption)
|
||||
```
|
||||
|
||||
@@ -81,6 +81,7 @@ export class Command {
|
||||
public executeSetGroup: CommandAdapt['setGroup']
|
||||
public executeDeleteGroup: CommandAdapt['deleteGroup']
|
||||
public executeLocationGroup: CommandAdapt['locationGroup']
|
||||
public executeSetControlValue: CommandAdapt['setControlValue']
|
||||
public getCatalog: CommandAdapt['getCatalog']
|
||||
public getImage: CommandAdapt['getImage']
|
||||
public getOptions: CommandAdapt['getOptions']
|
||||
@@ -96,6 +97,7 @@ export class Command {
|
||||
public getSearchNavigateInfo: CommandAdapt['getSearchNavigateInfo']
|
||||
public getLocale: CommandAdapt['getLocale']
|
||||
public getGroupIds: CommandAdapt['getGroupIds']
|
||||
public getControlValue: CommandAdapt['getControlValue']
|
||||
|
||||
constructor(adapt: CommandAdapt) {
|
||||
// 全局命令
|
||||
@@ -201,5 +203,8 @@ export class Command {
|
||||
this.getSearchNavigateInfo = adapt.getSearchNavigateInfo.bind(adapt)
|
||||
this.getLocale = adapt.getLocale.bind(adapt)
|
||||
this.getGroupIds = adapt.getGroupIds.bind(adapt)
|
||||
// 控件
|
||||
this.executeSetControlValue = adapt.setControlValue.bind(adapt)
|
||||
this.getControlValue = adapt.getControlValue.bind(adapt)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,11 @@ import { TitleLevel } from '../../dataset/enum/Title'
|
||||
import { VerticalAlign } from '../../dataset/enum/VerticalAlign'
|
||||
import { ICatalog } from '../../interface/Catalog'
|
||||
import { DeepRequired } from '../../interface/Common'
|
||||
import {
|
||||
IGetControlValueOption,
|
||||
IGetControlValueResult,
|
||||
ISetControlOption
|
||||
} from '../../interface/Control'
|
||||
import {
|
||||
IAppendElementListOption,
|
||||
IDrawImagePayload,
|
||||
@@ -2004,4 +2009,16 @@ export class CommandAdapt {
|
||||
isSubmitHistory: false
|
||||
})
|
||||
}
|
||||
|
||||
public getControlValue(
|
||||
payload: IGetControlValueOption
|
||||
): IGetControlValueResult | null {
|
||||
return this.draw.getControl().getValueByConceptId(payload)
|
||||
}
|
||||
|
||||
public setControlValue(payload: ISetControlOption) {
|
||||
const isReadonly = this.draw.isReadonly()
|
||||
if (isReadonly) return
|
||||
this.draw.getControl().setValueByConceptId(payload)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,13 @@ import { ControlComponent, ControlType } from '../../../dataset/enum/Control'
|
||||
import { ElementType } from '../../../dataset/enum/Element'
|
||||
import {
|
||||
IControl,
|
||||
IControlContext,
|
||||
IControlInitOption,
|
||||
IControlInstance,
|
||||
IControlOption
|
||||
IControlOption,
|
||||
IGetControlValueOption,
|
||||
IGetControlValueResult,
|
||||
ISetControlOption
|
||||
} from '../../../interface/Control'
|
||||
import { IEditorData } from '../../../interface/Editor'
|
||||
import { IElement, IElementPosition } from '../../../interface/Element'
|
||||
@@ -13,6 +17,7 @@ import { IRange } from '../../../interface/Range'
|
||||
import { deepClone, nextTick, splitText } from '../../../utils'
|
||||
import {
|
||||
formatElementContext,
|
||||
formatElementList,
|
||||
pickElementAttr,
|
||||
zipElementList
|
||||
} from '../../../utils/element'
|
||||
@@ -402,4 +407,142 @@ export class Control {
|
||||
}
|
||||
return this.activeControl.cut()
|
||||
}
|
||||
|
||||
public getValueByConceptId(
|
||||
payload: IGetControlValueOption
|
||||
): IGetControlValueResult {
|
||||
const { conceptId } = payload
|
||||
const elementList = [
|
||||
...this.draw.getHeaderElementList(),
|
||||
...this.draw.getOriginalMainElementList(),
|
||||
...this.draw.getFooterElementList()
|
||||
]
|
||||
const result: IGetControlValueResult = []
|
||||
let i = 0
|
||||
while (i < elementList.length) {
|
||||
const element = elementList[i]
|
||||
i++
|
||||
if (element?.control?.conceptId !== conceptId) continue
|
||||
const { type, code, valueSets } = element.control!
|
||||
let j = i
|
||||
let textControlValue = ''
|
||||
while (j < elementList.length) {
|
||||
const nextElement = elementList[j]
|
||||
if (nextElement.controlId !== element.controlId) break
|
||||
if (
|
||||
type === ControlType.TEXT &&
|
||||
nextElement.controlComponent === ControlComponent.VALUE
|
||||
) {
|
||||
textControlValue += nextElement.value
|
||||
}
|
||||
j++
|
||||
}
|
||||
if (type === ControlType.TEXT) {
|
||||
result.push({
|
||||
value: textControlValue || null,
|
||||
innerText: textControlValue || null
|
||||
})
|
||||
} else if (type === ControlType.SELECT || type === ControlType.CHECKBOX) {
|
||||
const innerText = code
|
||||
?.split(',')
|
||||
.map(
|
||||
selectCode =>
|
||||
valueSets?.find(valueSet => valueSet.code === selectCode)?.value
|
||||
)
|
||||
.filter(Boolean)
|
||||
.join('')
|
||||
result.push({
|
||||
value: code || null,
|
||||
innerText: innerText || null
|
||||
})
|
||||
}
|
||||
i = j
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
public setValueByConceptId(payload: ISetControlOption) {
|
||||
const isReadonly = this.draw.isReadonly()
|
||||
if (isReadonly) return
|
||||
let isExistSet = false
|
||||
const { conceptId, value } = payload
|
||||
const data = [
|
||||
this.draw.getHeaderElementList(),
|
||||
this.draw.getOriginalMainElementList(),
|
||||
this.draw.getFooterElementList()
|
||||
]
|
||||
for (const elementList of data) {
|
||||
let i = 0
|
||||
while (i < elementList.length) {
|
||||
const element = elementList[i]
|
||||
i++
|
||||
if (element?.control?.conceptId !== conceptId) continue
|
||||
isExistSet = true
|
||||
const { type } = element.control!
|
||||
// 当前控件结束索引
|
||||
let currentEndIndex = i
|
||||
while (currentEndIndex < elementList.length) {
|
||||
const nextElement = elementList[currentEndIndex]
|
||||
if (nextElement.controlId !== element.controlId) break
|
||||
currentEndIndex++
|
||||
}
|
||||
// 模拟光标选区上下文
|
||||
const fakeRange = {
|
||||
startIndex: i - 1,
|
||||
endIndex: currentEndIndex - 2
|
||||
}
|
||||
const controlContext: IControlContext = {
|
||||
range: fakeRange,
|
||||
elementList
|
||||
}
|
||||
if (type === ControlType.TEXT) {
|
||||
const formatValue = [{ value }]
|
||||
formatElementList(formatValue, {
|
||||
isHandleFirstElement: false,
|
||||
editorOptions: this.draw.getOptions()
|
||||
})
|
||||
const text = new TextControl(element, this)
|
||||
if (value) {
|
||||
text.setValue(formatValue, controlContext)
|
||||
} else {
|
||||
text.clearValue(controlContext)
|
||||
}
|
||||
} else if (type === ControlType.SELECT) {
|
||||
const select = new SelectControl(element, this)
|
||||
if (value) {
|
||||
select.setSelect(value, controlContext)
|
||||
} else {
|
||||
select.clearSelect(controlContext)
|
||||
}
|
||||
} else if (type === ControlType.CHECKBOX) {
|
||||
const checkbox = new CheckboxControl(element, this)
|
||||
const checkboxElementList = elementList.slice(
|
||||
fakeRange.startIndex + 1,
|
||||
fakeRange.endIndex + 1
|
||||
)
|
||||
const codes = value?.split(',') || []
|
||||
for (const checkElement of checkboxElementList) {
|
||||
if (checkElement.controlComponent === ControlComponent.CHECKBOX) {
|
||||
const checkboxItem = checkElement.checkbox!
|
||||
checkboxItem.value = codes.includes(checkboxItem.code!)
|
||||
}
|
||||
}
|
||||
checkbox.setSelect(controlContext)
|
||||
}
|
||||
// 修改后控件结束索引
|
||||
let newEndIndex = i
|
||||
while (newEndIndex < elementList.length) {
|
||||
const nextElement = elementList[newEndIndex]
|
||||
if (nextElement.controlId !== element.controlId) break
|
||||
newEndIndex++
|
||||
}
|
||||
i = newEndIndex
|
||||
}
|
||||
}
|
||||
if (isExistSet) {
|
||||
this.draw.render({
|
||||
isSetCursor: false
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import { ControlComponent } from '../../../../dataset/enum/Control'
|
||||
import { KeyMap } from '../../../../dataset/enum/KeyMap'
|
||||
import { IControlInstance } from '../../../../interface/Control'
|
||||
import {
|
||||
IControlContext,
|
||||
IControlInstance
|
||||
} from '../../../../interface/Control'
|
||||
import { IElement } from '../../../../interface/Element'
|
||||
import { Control } from '../Control'
|
||||
|
||||
@@ -63,10 +66,10 @@ export class CheckboxControl implements IControlInstance {
|
||||
return -1
|
||||
}
|
||||
|
||||
public setSelect() {
|
||||
public setSelect(context: IControlContext = {}) {
|
||||
const { control } = this.element
|
||||
const elementList = this.control.getElementList()
|
||||
const { startIndex } = this.control.getRange()
|
||||
const elementList = context.elementList || this.control.getElementList()
|
||||
const { startIndex } = context.range || this.control.getRange()
|
||||
const startElement = elementList[startIndex]
|
||||
const data: string[] = []
|
||||
// 向左查找
|
||||
|
||||
@@ -6,7 +6,10 @@ import { EDITOR_ELEMENT_STYLE_ATTR } from '../../../../dataset/constant/Element'
|
||||
import { ControlComponent } from '../../../../dataset/enum/Control'
|
||||
import { EditorComponent } from '../../../../dataset/enum/Editor'
|
||||
import { KeyMap } from '../../../../dataset/enum/KeyMap'
|
||||
import { IControlInstance } from '../../../../interface/Control'
|
||||
import {
|
||||
IControlContext,
|
||||
IControlInstance
|
||||
} from '../../../../interface/Control'
|
||||
import { IElement } from '../../../../interface/Element'
|
||||
import { omitObject, splitText } from '../../../../utils'
|
||||
import { formatElementContext } from '../../../../utils/element'
|
||||
@@ -135,9 +138,9 @@ export class SelectControl implements IControlInstance {
|
||||
return this.clearSelect()
|
||||
}
|
||||
|
||||
public clearSelect(): number {
|
||||
const elementList = this.control.getElementList()
|
||||
const { startIndex } = this.control.getRange()
|
||||
public clearSelect(context: IControlContext = {}): number {
|
||||
const elementList = context.elementList || this.control.getElementList()
|
||||
const { startIndex } = context.range || this.control.getRange()
|
||||
const startElement = elementList[startIndex]
|
||||
let leftIndex = -1
|
||||
let rightIndex = -1
|
||||
@@ -177,7 +180,7 @@ export class SelectControl implements IControlInstance {
|
||||
return preIndex
|
||||
}
|
||||
|
||||
public setSelect(code: string) {
|
||||
public setSelect(code: string, context: IControlContext = {}) {
|
||||
const control = this.element.control!
|
||||
const valueSets = control.valueSets
|
||||
if (!Array.isArray(valueSets) || !valueSets.length) return
|
||||
@@ -185,10 +188,10 @@ export class SelectControl implements IControlInstance {
|
||||
const valueSet = valueSets.find(v => v.code === code)
|
||||
if (!valueSet) return
|
||||
// 清空选项
|
||||
const startIndex = this.clearSelect()
|
||||
const startIndex = this.clearSelect(context)
|
||||
this.control.removePlaceholder(startIndex)
|
||||
// 插入
|
||||
const elementList = this.control.getElementList()
|
||||
const elementList = context.elementList || this.control.getElementList()
|
||||
const startElement = elementList[startIndex]
|
||||
const anchorElement =
|
||||
startElement.controlComponent === ControlComponent.PREFIX
|
||||
@@ -206,12 +209,14 @@ export class SelectControl implements IControlInstance {
|
||||
formatElementContext(elementList, [newElement], startIndex)
|
||||
draw.spliceElementList(elementList, start + i, 0, newElement)
|
||||
}
|
||||
// render
|
||||
const newIndex = start + data.length - 1
|
||||
this.control.repaintControl(newIndex)
|
||||
// 设置状态
|
||||
this.element.control!.code = code
|
||||
this.destroy()
|
||||
// 重新渲染控件
|
||||
if (!context.range) {
|
||||
const newIndex = start + data.length - 1
|
||||
this.control.repaintControl(newIndex)
|
||||
this.destroy()
|
||||
}
|
||||
}
|
||||
|
||||
private _createSelectPopupDom() {
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import { EDITOR_ELEMENT_STYLE_ATTR } from '../../../../dataset/constant/Element'
|
||||
import { ControlComponent } from '../../../../dataset/enum/Control'
|
||||
import { KeyMap } from '../../../../dataset/enum/KeyMap'
|
||||
import { IControlInstance } from '../../../../interface/Control'
|
||||
import {
|
||||
IControlContext,
|
||||
IControlInstance
|
||||
} from '../../../../interface/Control'
|
||||
import { IElement } from '../../../../interface/Element'
|
||||
import { omitObject } from '../../../../utils'
|
||||
import { formatElementContext } from '../../../../utils/element'
|
||||
@@ -58,9 +61,9 @@ export class TextControl implements IControlInstance {
|
||||
return data
|
||||
}
|
||||
|
||||
public setValue(data: IElement[]): number {
|
||||
const elementList = this.control.getElementList()
|
||||
const range = this.control.getRange()
|
||||
public setValue(data: IElement[], context: IControlContext = {}): number {
|
||||
const elementList = context.elementList || this.control.getElementList()
|
||||
const range = context.range || this.control.getRange()
|
||||
// 收缩边界到Value内
|
||||
this.control.shrinkBoundary()
|
||||
const { startIndex, endIndex } = range
|
||||
@@ -91,6 +94,20 @@ export class TextControl implements IControlInstance {
|
||||
return start + data.length - 1
|
||||
}
|
||||
|
||||
public clearValue(context: IControlContext = {}): number {
|
||||
const elementList = context.elementList || this.control.getElementList()
|
||||
const range = context.range || this.control.getRange()
|
||||
const { startIndex, endIndex } = range
|
||||
this.control
|
||||
.getDraw()
|
||||
.spliceElementList(elementList, startIndex + 1, endIndex - startIndex)
|
||||
const value = this.getValue()
|
||||
if (!value.length) {
|
||||
this.control.addPlaceholder(startIndex)
|
||||
}
|
||||
return startIndex
|
||||
}
|
||||
|
||||
public keydown(evt: KeyboardEvent): number {
|
||||
const elementList = this.control.getElementList()
|
||||
const range = this.control.getRange()
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { ControlType } from '../dataset/enum/Control'
|
||||
import { ICheckbox } from './Checkbox'
|
||||
import { IElement } from './Element'
|
||||
import { IRange } from './Range'
|
||||
|
||||
export interface IValueSet {
|
||||
value: string
|
||||
@@ -65,3 +66,22 @@ export interface IControlInstance {
|
||||
|
||||
cut(): number
|
||||
}
|
||||
|
||||
export interface IControlContext {
|
||||
range?: IRange
|
||||
elementList?: IElement[]
|
||||
}
|
||||
|
||||
export interface IGetControlValueOption {
|
||||
conceptId: string
|
||||
}
|
||||
|
||||
export type IGetControlValueResult = {
|
||||
value: string | null
|
||||
innerText: string | null
|
||||
}[]
|
||||
|
||||
export interface ISetControlOption {
|
||||
conceptId: string
|
||||
value: string
|
||||
}
|
||||
|
||||
@@ -103,6 +103,7 @@ elementList.splice(12, 0, {
|
||||
type: ElementType.CONTROL,
|
||||
value: '',
|
||||
control: {
|
||||
conceptId: '1',
|
||||
type: ControlType.TEXT,
|
||||
value: null,
|
||||
placeholder: '其他补充',
|
||||
@@ -116,6 +117,7 @@ elementList.splice(94, 0, {
|
||||
type: ElementType.CONTROL,
|
||||
value: '',
|
||||
control: {
|
||||
conceptId: '2',
|
||||
type: ControlType.SELECT,
|
||||
value: null,
|
||||
code: null,
|
||||
@@ -337,6 +339,7 @@ elementList.push(
|
||||
{
|
||||
type: ElementType.CONTROL,
|
||||
control: {
|
||||
conceptId: '3',
|
||||
type: ControlType.CHECKBOX,
|
||||
code: '98175',
|
||||
value: '',
|
||||
@@ -406,6 +409,7 @@ elementList.push(
|
||||
type: ElementType.CONTROL,
|
||||
value: '',
|
||||
control: {
|
||||
conceptId: '4',
|
||||
type: ControlType.TEXT,
|
||||
value: null,
|
||||
placeholder: '',
|
||||
|
||||
Reference in New Issue
Block a user