@@ -12,6 +12,8 @@ interface ValidateFnParam {
1212 isFormTag : boolean
1313 message : string
1414 messageShowType : MessageShowType
15+ dfcUID : string
16+ popPosition : PopPosition | Array < BasePopPosition >
1517}
1618
1719interface CustomValidatorRuleObject {
@@ -24,6 +26,7 @@ interface DirectiveValidateRuleOptions {
2426 updateOn ?: UpdateOn
2527 errorStrategy ?: ErrorStrategy
2628 asyncDebounceTime ?: number
29+ popPosition ?: PopPosition | Array < BasePopPosition >
2730}
2831
2932interface DirectiveBindingValue {
@@ -38,9 +41,18 @@ interface DirectiveCustomRuleItem extends RuleItem {
3841 asyncValidators : CustomValidatorRuleObject [ ]
3942}
4043
44+ export interface ShowPopoverErrorMessageEventData {
45+ showPopover ?: boolean
46+ message ?: string
47+ uid ?: string ,
48+ popPosition ?: PopPosition
49+ }
50+
4151type MessageShowType = 'popover' | 'text' | 'none' | 'toast' ;
4252type UpdateOn = 'input' | 'focus' | 'change' | 'blur' | 'submit' ;
4353type ErrorStrategy = 'dirty' | 'pristine' ;
54+ type BasePopPosition = 'left' | 'right' | 'top' | 'bottom' ;
55+ type PopPosition = BasePopPosition | 'left-top' | 'left-bottom' | 'top-left' | 'top-right' | 'right-top' | 'right-bottom' | 'bottom-left' | 'bottom-right' ;
4456
4557enum ErrorStrategyEnum {
4658 dirty = 'dirty' ,
@@ -198,14 +210,20 @@ function handleErrorStrategyPass(el: HTMLElement): void {
198210 el . setAttribute ( 'class' , classList . join ( ' ' ) ) ;
199211}
200212
201- function handleValidateError ( { el, tipEl, message, isFormTag, messageShowType} : Partial < ValidateFnParam > ) : void {
213+ function handleValidateError ( { el, tipEl, message, isFormTag, messageShowType, dfcUID , popPosition = 'right-bottom' } : Partial < ValidateFnParam > ) : void {
202214 // 如果该指令用在form标签上,这里做特殊处理
203215 if ( isFormTag && messageShowType === MessageShowTypeEnum . toast ) {
204216 // todo:待替换为toast
205217 alert ( message ) ;
206218 return ;
207219 }
208220
221+ // messageShowType为popover时,设置popover
222+ if ( MessageShowTypeEnum . popover === messageShowType ) {
223+ EventBus . emit ( "showPopoverErrorMessage" , { showPopover : true , message, uid : dfcUID , popPosition} as ShowPopoverErrorMessageEventData ) ;
224+ return ;
225+ }
226+
209227 tipEl . innerText = '' + message ;
210228 tipEl . style . display = 'inline-flex' ;
211229 tipEl . setAttribute ( 'class' , 'd-validate-tip' ) ;
@@ -225,7 +243,7 @@ function getFormName(binding: DirectiveBinding): string {
225243}
226244
227245// 校验处理函数
228- function validateFn ( { validator, modelValue, el, tipEl, isFormTag, messageShowType} : Partial < ValidateFnParam > ) {
246+ function validateFn ( { validator, modelValue, el, tipEl, isFormTag, messageShowType, dfcUID , popPosition } : Partial < ValidateFnParam > ) {
229247 validator . validate ( { modelName : modelValue } ) . then ( ( ) => {
230248 handleValidatePass ( el , tipEl ) ;
231249 } ) . catch ( ( err ) => {
@@ -240,13 +258,22 @@ function validateFn({validator, modelValue, el, tipEl, isFormTag, messageShowTyp
240258 msg = errors [ 0 ] . message ;
241259 }
242260
243- handleValidateError ( { el, tipEl, message : msg , isFormTag, messageShowType} ) ;
261+ handleValidateError ( { el, tipEl, message : msg , isFormTag, messageShowType, dfcUID , popPosition } ) ;
244262 } )
245263}
246264
265+ // 检测popover的position是否是正确值
266+ function checkValidPopsition ( positionStr : string ) : boolean {
267+ const validPosition = [ 'left' , 'right' , 'top' , 'bottom' , 'left-top' , 'left-bottom' , 'top-left' , 'top-right' , 'right-top' , 'right-bottom' , 'bottom-left' , 'bottom-right' ] ;
268+ const isValid = validPosition . includes ( positionStr ) ;
269+ ! isValid && console . warn ( `invalid popPosition value '${ positionStr } '.` ) ;
270+ return isValid
271+ }
272+
247273export default {
248274 mounted ( el : HTMLElement , binding : DirectiveBinding , vnode : VNode ) : void {
249275 const isFormTag = el . tagName === 'FORM' ;
276+ const dfcUID = el . parentNode . parentNode . parentElement . dataset . uid ;
250277
251278 const hasOptions = isObject ( binding . value ) && hasKey ( binding . value , 'options' ) ;
252279
@@ -259,12 +286,25 @@ export default {
259286 let { errorStrategy } : DirectiveBindingValue = binding . value ;
260287
261288 // errorStrategy可配置在options对象中
262- const {
289+ let {
263290 updateOn = UpdateOnEnum . change ,
264291 errorStrategy : ErrorStrategy = ErrorStrategyEnum . dirty ,
265- asyncDebounceTime = 300
292+ asyncDebounceTime = 300 ,
293+ popPosition = [ 'right' , 'bottom' ]
266294 } : DirectiveValidateRuleOptions = options ;
267295
296+ // 设置popover的位置
297+ if ( messageShowType === MessageShowTypeEnum . popover ) {
298+ if ( Array . isArray ( popPosition ) ) {
299+ popPosition = ( popPosition . length > 1 ? popPosition . join ( '-' ) : popPosition [ 0 ] ) as PopPosition ;
300+ if ( ! checkValidPopsition ( popPosition ) ) {
301+ popPosition = 'right-bottom' ;
302+ }
303+ } else if ( ! checkValidPopsition ( popPosition ) ) {
304+ popPosition = 'right-bottom' ;
305+ }
306+ }
307+
268308 if ( ! errorStrategy ) {
269309 errorStrategy = ErrorStrategy ;
270310 }
@@ -340,7 +380,10 @@ export default {
340380
341381 const htmlEventValidateHandler = ( e ) => {
342382 const modelValue = e . target . value ;
343- validateFn ( { validator, modelValue, el, tipEl, isFormTag : false , messageShowType} ) ;
383+ if ( messageShowType === MessageShowTypeEnum . popover ) {
384+ EventBus . emit ( "showPopoverErrorMessage" , { showPopover : false , message : "" , uid : dfcUID } as ShowPopoverErrorMessageEventData ) ;
385+ }
386+ validateFn ( { validator, modelValue, el, tipEl, isFormTag : false , messageShowType, dfcUID, popPosition} ) ;
344387 }
345388
346389 // 监听事件验证
0 commit comments