feat:add checkbox control interface
This commit is contained in:
@@ -39,6 +39,7 @@ import { Control } from './control/Control'
|
||||
import { zipElementList } from '../../utils/element'
|
||||
import { CheckboxParticle } from './particle/CheckboxParticle'
|
||||
import { DeepRequired } from '../../interface/Common'
|
||||
import { ControlComponent } from '../../dataset/enum/Control'
|
||||
|
||||
export class Draw {
|
||||
|
||||
@@ -567,7 +568,10 @@ export class Draw {
|
||||
element.width = innerWidth
|
||||
metrics.width = innerWidth
|
||||
metrics.height = this.options.defaultSize
|
||||
} else if (element.type === ElementType.CHECKBOX) {
|
||||
} else if (
|
||||
element.type === ElementType.CHECKBOX ||
|
||||
element.controlComponent === ControlComponent.CHECKBOX
|
||||
) {
|
||||
const { width, height, gap } = this.options.checkbox
|
||||
const elementWidth = (width + gap * 2) * scale
|
||||
element.width = elementWidth
|
||||
@@ -707,7 +711,10 @@ export class Draw {
|
||||
if (this.mode !== EditorMode.CLEAN) {
|
||||
this.pageBreakParticle.render(ctx, element, x, y)
|
||||
}
|
||||
} else if (element.type === ElementType.CHECKBOX) {
|
||||
} else if (
|
||||
element.type === ElementType.CHECKBOX ||
|
||||
element.controlComponent === ControlComponent.CHECKBOX
|
||||
) {
|
||||
this.textParticle.complete()
|
||||
this.checkboxParticle.render(ctx, element, x, y + offsetY)
|
||||
} else {
|
||||
|
||||
@@ -7,6 +7,7 @@ import { pickElementAttr, zipElementList } from '../../../utils/element'
|
||||
import { Listener } from '../../listener/Listener'
|
||||
import { RangeManager } from '../../range/RangeManager'
|
||||
import { Draw } from '../Draw'
|
||||
import { CheckboxControl } from './checkbox/CheckboxControl'
|
||||
import { SelectControl } from './select/SelectControl'
|
||||
import { TextControl } from './text/TextControl'
|
||||
|
||||
@@ -103,6 +104,8 @@ export class Control {
|
||||
const selectControl = new SelectControl(element, this)
|
||||
this.activeControl = selectControl
|
||||
selectControl.awake()
|
||||
} else if (control.type === ControlType.CHECKBOX) {
|
||||
this.activeControl = new CheckboxControl(element, this)
|
||||
}
|
||||
// 激活控件回调
|
||||
setTimeout(() => {
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
import { ControlComponent } from '../../../../dataset/enum/Control'
|
||||
import { KeyMap } from '../../../../dataset/enum/Keymap'
|
||||
import { IControlInstance } from '../../../../interface/Control'
|
||||
import { IElement } from '../../../../interface/Element'
|
||||
import { Control } from '../Control'
|
||||
|
||||
export class CheckboxControl implements IControlInstance {
|
||||
|
||||
private element: IElement
|
||||
private control: Control
|
||||
|
||||
constructor(element: IElement, control: Control) {
|
||||
this.element = element
|
||||
this.control = control
|
||||
}
|
||||
|
||||
public getElement(): IElement {
|
||||
return this.element
|
||||
}
|
||||
|
||||
public getCode(): string | null {
|
||||
return this.element.control?.code || null
|
||||
}
|
||||
|
||||
public getValue(): IElement[] {
|
||||
const elementList = this.control.getElementList()
|
||||
const { startIndex } = this.control.getRange()
|
||||
const startElement = elementList[startIndex]
|
||||
const data: IElement[] = []
|
||||
// 向左查找
|
||||
let preIndex = startIndex
|
||||
while (preIndex > 0) {
|
||||
const preElement = elementList[preIndex]
|
||||
if (
|
||||
preElement.controlId !== startElement.controlId ||
|
||||
preElement.controlComponent === ControlComponent.PREFIX
|
||||
) {
|
||||
break
|
||||
}
|
||||
if (preElement.controlComponent === ControlComponent.VALUE) {
|
||||
data.unshift(preElement)
|
||||
}
|
||||
preIndex--
|
||||
}
|
||||
// 向右查找
|
||||
let nextIndex = startIndex + 1
|
||||
while (nextIndex < elementList.length) {
|
||||
const nextElement = elementList[nextIndex]
|
||||
if (
|
||||
nextElement.controlId !== startElement.controlId ||
|
||||
nextElement.controlComponent === ControlComponent.POSTFIX
|
||||
) {
|
||||
break
|
||||
}
|
||||
if (nextElement.controlComponent === ControlComponent.VALUE) {
|
||||
data.push(nextElement)
|
||||
}
|
||||
nextIndex++
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
public setValue(): number {
|
||||
const { endIndex } = this.control.getRange()
|
||||
return endIndex
|
||||
}
|
||||
|
||||
public keydown(evt: KeyboardEvent): number {
|
||||
const range = this.control.getRange()
|
||||
// 收缩边界到Value内
|
||||
this.control.shrinkBoundary()
|
||||
const { startIndex, endIndex } = range
|
||||
// 删除
|
||||
if (evt.key === KeyMap.Backspace || evt.key === KeyMap.Delete) {
|
||||
return this.control.removeControl(startIndex)
|
||||
}
|
||||
return endIndex
|
||||
}
|
||||
|
||||
public cut(): number {
|
||||
const { endIndex } = this.control.getRange()
|
||||
return endIndex
|
||||
}
|
||||
|
||||
}
|
||||
@@ -202,6 +202,7 @@ export class CanvasEvent {
|
||||
// 设置位置上下文
|
||||
this.position.setPositionContext({
|
||||
isTable: isTable || false,
|
||||
isCheckbox: isCheckbox || false,
|
||||
isControl: isControl || false,
|
||||
index,
|
||||
trIndex,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { ElementType } from '../..'
|
||||
import { ZERO } from '../../dataset/constant/Common'
|
||||
import { ControlComponent } from '../../dataset/enum/Control'
|
||||
import { IEditorOption } from '../../interface/Editor'
|
||||
import { IElementPosition } from '../../interface/Element'
|
||||
import { ICurrentPosition, IGetPositionByXYPayload, IPositionContext } from '../../interface/Position'
|
||||
@@ -97,7 +98,8 @@ export class Position {
|
||||
const tdValueElement = td.value[tdValueIndex]
|
||||
return {
|
||||
index,
|
||||
isCheckbox: tdValueElement.type === ElementType.CHECKBOX,
|
||||
isCheckbox: tdValueElement.type === ElementType.CHECKBOX ||
|
||||
tdValueElement.controlComponent === ControlComponent.CHECKBOX,
|
||||
isControl: tdValueElement.type === ElementType.CONTROL,
|
||||
isImage: tablePosition.isImage,
|
||||
isDirectHit: tablePosition.isDirectHit,
|
||||
@@ -121,7 +123,10 @@ export class Position {
|
||||
isImage: true
|
||||
}
|
||||
}
|
||||
if (element.type === ElementType.CHECKBOX) {
|
||||
if (
|
||||
element.type === ElementType.CHECKBOX ||
|
||||
element.controlComponent === ControlComponent.CHECKBOX
|
||||
) {
|
||||
return {
|
||||
index: curPositionIndex,
|
||||
isDirectHit: true,
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
export enum ControlType {
|
||||
TEXT = 'text',
|
||||
SELECT = 'select'
|
||||
SELECT = 'select',
|
||||
CHECKBOX = 'checkbox'
|
||||
}
|
||||
|
||||
export enum ControlComponent {
|
||||
PREFIX = 'prefix',
|
||||
POSTFIX = 'postfix',
|
||||
PLACEHOLDER = 'placeholder',
|
||||
VALUE = 'value'
|
||||
VALUE = 'value',
|
||||
CHECKBOX = 'checkbox'
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
import { ControlType } from '../dataset/enum/Control'
|
||||
import { ICheckbox } from './Checkbox'
|
||||
import { IElement } from './Element'
|
||||
|
||||
export interface IValueSet {
|
||||
@@ -11,6 +12,14 @@ export interface IControlSelect {
|
||||
valueSets: IValueSet[];
|
||||
}
|
||||
|
||||
export interface IControlCheckbox {
|
||||
code: string | null;
|
||||
min?: number;
|
||||
max?: number;
|
||||
valueSets: IValueSet[];
|
||||
checkbox?: ICheckbox;
|
||||
}
|
||||
|
||||
export interface IControlBasic {
|
||||
type: ControlType;
|
||||
value: IElement[] | null;
|
||||
@@ -20,7 +29,10 @@ export interface IControlBasic {
|
||||
postfix?: string;
|
||||
}
|
||||
|
||||
export type IControl = IControlBasic & Partial<IControlSelect>
|
||||
export type IControl = IControlBasic
|
||||
& Partial<IControlSelect>
|
||||
& Partial<IControlCheckbox>
|
||||
|
||||
|
||||
export interface IControlOption {
|
||||
placeholderColor?: string;
|
||||
|
||||
@@ -29,6 +29,7 @@ export interface IGetPositionByXYPayload {
|
||||
|
||||
export interface IPositionContext {
|
||||
isTable: boolean;
|
||||
isCheckbox?: boolean;
|
||||
isControl?: boolean;
|
||||
index?: number;
|
||||
trIndex?: number;
|
||||
|
||||
@@ -97,9 +97,43 @@ export function formatElementList(elementList: IElement[], options: IFormatEleme
|
||||
// 值
|
||||
if (
|
||||
(value && value.length) ||
|
||||
type === ControlType.CHECKBOX ||
|
||||
(type === ControlType.SELECT && code && (!value || !value.length))
|
||||
) {
|
||||
let valueList: IElement[] = value || []
|
||||
if (type === ControlType.CHECKBOX) {
|
||||
const codeList = code ? code.split(',') : []
|
||||
if (Array.isArray(valueSets) && valueSets.length) {
|
||||
for (let v = 0; v < valueSets.length; v++) {
|
||||
const valueSet = valueSets[v]
|
||||
// checkbox组件
|
||||
elementList.splice(i, 0, {
|
||||
controlId,
|
||||
value: '',
|
||||
type: el.type,
|
||||
control: el.control,
|
||||
controlComponent: ControlComponent.CHECKBOX,
|
||||
checkbox: {
|
||||
value: codeList.includes(valueSet.code)
|
||||
}
|
||||
})
|
||||
i++
|
||||
// 文本
|
||||
const valueStrList = valueSet.value.split('')
|
||||
for (let e = 0; e < valueStrList.length; e++) {
|
||||
const value = valueStrList[e]
|
||||
elementList.splice(i, 0, {
|
||||
controlId,
|
||||
value,
|
||||
type: el.type,
|
||||
control: el.control,
|
||||
controlComponent: ControlComponent.VALUE
|
||||
})
|
||||
i++
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!value || !value.length) {
|
||||
if (Array.isArray(valueSets) && valueSets.length) {
|
||||
const valueSet = valueSets.find(v => v.code === code)
|
||||
@@ -126,6 +160,7 @@ export function formatElementList(elementList: IElement[], options: IFormatEleme
|
||||
i++
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// placeholder
|
||||
const thePlaceholderArgs: Pick<IElement, 'color'> = {}
|
||||
|
||||
+12
-10
@@ -250,18 +250,20 @@ elementList.push({
|
||||
elementList.push(...<IElement[]>[{
|
||||
value: '是否同意以上内容:'
|
||||
}, {
|
||||
type: ElementType.CHECKBOX,
|
||||
checkbox: {
|
||||
value: true
|
||||
type: ElementType.CONTROL,
|
||||
control: {
|
||||
type: ControlType.CHECKBOX,
|
||||
code: '98175',
|
||||
value: '',
|
||||
valueSets: [{
|
||||
value: '同意',
|
||||
code: '98175'
|
||||
}, {
|
||||
value: '否定',
|
||||
code: '98176'
|
||||
}]
|
||||
},
|
||||
value: ''
|
||||
}, {
|
||||
value: '同意'
|
||||
}, {
|
||||
type: ElementType.CHECKBOX,
|
||||
value: ''
|
||||
}, {
|
||||
value: '否定'
|
||||
}, {
|
||||
value: '\n'
|
||||
}])
|
||||
|
||||
Reference in New Issue
Block a user