feat:add checkbox control interface

pr675
黄云飞 4 years ago
parent 464c8e3c34
commit 4d48eb2cde

@ -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'> = {}

@ -250,18 +250,20 @@ elementList.push({
elementList.push(...<IElement[]>[{
value: '是否同意以上内容:'
}, {
type: ElementType.CHECKBOX,
checkbox: {
value: true
},
value: ''
}, {
value: '同意'
type: ElementType.CONTROL,
control: {
type: ControlType.CHECKBOX,
code: '98175',
value: '',
valueSets: [{
value: '同意',
code: '98175'
}, {
type: ElementType.CHECKBOX,
value: '否定',
code: '98176'
}]
},
value: ''
}, {
value: '否定'
}, {
value: '\n'
}])

Loading…
Cancel
Save