77import { typeCheckConfig } from '../util/index'
88import Messages from './messages'
99import Manipulator from '../dom/manipulator'
10+ import EventHandler from '../dom/event-handler'
1011
1112const NAME = 'field'
12- const TYPE_PLACEHOLDER = '{type}'
13- const CLASS_ERROR = `invalid-${ TYPE_PLACEHOLDER } `
14- const CLASS_INFO = `info-${ TYPE_PLACEHOLDER } `
15- const CLASS_SUCCESS = `valid-${ TYPE_PLACEHOLDER } `
13+ const DATA_KEY = 'bs.field'
14+ const EVENT_KEY = `.${ DATA_KEY } `
15+ const EVENT_INPUT = `input.${ EVENT_KEY } `
16+ const CLASS_PREFIX_ERROR = 'invalid'
17+ const CLASS_PREFIX_INFO = 'info'
18+ const CLASS_PREFIX_SUCCESS = 'valid'
1619const ARIA_DESCRIBED_BY = 'aria-describedby'
1720const Default = {
1821 name : null ,
1922 type : 'feedback' , // or tooltip
20- template : `<div class="field-${ TYPE_PLACEHOLDER } "></div>` ,
2123 valid : '' , // valid message to add
2224 invalid : '' // invalid message to add
2325}
2426
2527const DefaultType = {
2628 name : 'string' ,
2729 type : 'string' ,
28- template : 'string' ,
2930 valid : 'string' ,
3031 invalid : 'string'
3132}
@@ -37,25 +38,31 @@ class Field {
3738 throw new TypeError ( `field with id:${ this . _config . name } not found` )
3839 }
3940
40- this . _errorMessages = new Messages ( )
41- this . _helpMessages = new Messages ( )
42- this . _successMessages = new Messages ( )
4341 this . _config = this . _getConfig ( config )
42+
43+ this . _errorMessages = this . _getNewMessagesCollection ( CLASS_PREFIX_ERROR )
44+ this . _helpMessages = this . _getNewMessagesCollection ( CLASS_PREFIX_INFO )
45+ this . _successMessages = this . _getNewMessagesCollection ( CLASS_PREFIX_SUCCESS )
46+
47+ this . _initializeMessageCollections ( )
4448 this . _initialDescriptedBy = this . _element . getAttribute ( ARIA_DESCRIBED_BY )
45- this . _appended = null
49+ this . _appendedFeedback = null
50+ EventHandler . on ( this . _element , EVENT_INPUT , ( ) => {
51+ this . clearAppended ( )
52+ } )
4653 }
4754
4855 getElement ( ) {
4956 return this . _element
5057 }
5158
5259 clearAppended ( ) {
53- if ( ! this . _appended ) {
60+ if ( ! this . _appendedFeedback ) {
5461 return
5562 }
5663
57- this . _appended . remove ( )
58- this . _appended = null
64+ this . _appendedFeedback . remove ( )
65+ this . _appendedFeedback = null
5966 if ( this . _initialDescriptedBy ) {
6067 this . _element . setAttribute ( ARIA_DESCRIBED_BY , this . _initialDescriptedBy )
6168 } else {
@@ -81,70 +88,54 @@ class Field {
8188 return this . _successMessages
8289 }
8390
84- appendFirstErrorMsg ( ) {
85- return this . appendFeedback ( this . errorMessages ( ) . getFirst ( ) , CLASS_ERROR )
86- }
87-
88- appendFirstHelpMsg ( ) {
89- return this . appendFeedback ( this . helpMessages ( ) . getFirst ( ) , CLASS_INFO )
90- }
91-
92- appendFirstSuccessMsg ( ) {
93- return this . appendFeedback ( this . successMessages ( ) . getFirst ( ) , CLASS_SUCCESS )
94- }
95-
9691 _getConfig ( config ) {
9792 config = {
9893 ...Default ,
9994 ...Manipulator . getDataAttributes ( this . _element ) ,
10095 ...( typeof config === 'object' ? config : { } )
10196 }
10297
103- if ( config . invalid ) {
104- this . errorMessages ( ) . add ( config . invalid )
105- }
106-
107- if ( config . valid ) {
108- this . successMessages ( ) . add ( config . valid )
109- }
110-
11198 typeCheckConfig ( NAME , config , DefaultType )
11299 return config
113100 }
114101
115- appendFeedback ( text , classAttr = '' ) {
102+ _appendFeedback ( htmlElement ) {
116103 this . clearAppended ( )
117- if ( ! text ) {
104+ if ( ! htmlElement ) {
118105 return
119106 }
120107
121- const feedbackElement = this . _makeFeedbackElement ( text , classAttr )
108+ const feedbackElement = htmlElement
122109
123- this . _appended = feedbackElement
110+ this . _appendedFeedback = feedbackElement
124111
125112 this . _element . parentNode . insertBefore ( feedbackElement , this . _element . nextSibling )
126-
113+ feedbackElement . id = this . _getId ( )
127114 const describedBy = this . _initialDescriptedBy ? `${ this . _initialDescriptedBy } ` : ''
128115 this . _element . setAttribute ( ARIA_DESCRIBED_BY , `${ describedBy } ${ feedbackElement . id } ` )
129116 }
130117
131- _makeFeedbackElement ( text , classAttr ) {
132- const element = document . createElement ( 'div' )
133- element . innerHTML = this . _setProperClassType ( this . _config . template )
134- const feedback = element . children [ 0 ]
135- feedback . classList . add ( this . _setProperClassType ( classAttr ) )
136- feedback . id = this . _getId ( )
137- feedback . innerHTML = text
138-
139- return feedback
118+ _getId ( ) {
119+ return `${ this . _config . name } -formTip`
140120 }
141121
142- _setProperClassType ( classPrefix ) {
143- return classPrefix . replaceAll ( TYPE_PLACEHOLDER , this . _config . type )
122+ _getNewMessagesCollection ( classPrefix ) {
123+ const config = {
124+ appendFunction : html => this . _appendFeedback ( html ) ,
125+ type : this . _config . type ,
126+ classPrefix
127+ }
128+ return new Messages ( config )
144129 }
145130
146- _getId ( ) {
147- return `${ this . _config . name } -formTip`
131+ _initializeMessageCollections ( ) {
132+ if ( this . _config . invalid ) {
133+ this . errorMessages ( ) . add ( this . _config . invalid )
134+ }
135+
136+ if ( this . _config . valid ) {
137+ this . successMessages ( ) . add ( this . _config . valid )
138+ }
148139 }
149140}
150141
0 commit comments