1
+ // https://gist.github.com/chrismccord/c4c60328c6ac5ec29e167bb115315d82
2
+ // maintain backwards compatibility of phx-feedback-for, which was removed in LiveView 1.0
3
+ // find all phx-feedback-for containers and show/hide phx-no-feedback class based on used inputs
4
+ import { isUsedInput } from "phoenix_live_view"
5
+
6
+ let resetFeedbacks = ( container , feedbacks ) => {
7
+ feedbacks = feedbacks || Array . from ( container . querySelectorAll ( "[phx-feedback-for]" ) )
8
+ . map ( el => [ el , el . getAttribute ( "phx-feedback-for" ) ] )
9
+
10
+ feedbacks . forEach ( ( [ feedbackEl , name ] ) => {
11
+ let query = `[name="${ name } "], [name="${ name } []"]`
12
+ let isUsed = Array . from ( container . querySelectorAll ( query ) ) . find ( input => isUsedInput ( input ) )
13
+ if ( isUsed || ! feedbackEl . hasAttribute ( "phx-feedback-for" ) ) {
14
+ feedbackEl . classList . remove ( "phx-no-feedback" )
15
+ } else {
16
+ feedbackEl . classList . add ( "phx-no-feedback" )
17
+ }
18
+ } )
19
+ }
20
+
21
+ export default phxFeedbackDom = ( dom ) => {
22
+ window . addEventListener ( "reset" , e => resetFeedbacks ( document ) )
23
+ let feedbacks
24
+ let submitPending = false
25
+ let inputPending = false
26
+ window . addEventListener ( "submit" , e => submitPending = e . target )
27
+ window . addEventListener ( "input" , e => inputPending = e . target )
28
+ // extend provided dom options with our own.
29
+ // accumulate phx-feedback-for containers for each patch and reset feedbacks when patch ends
30
+ return {
31
+ onPatchStart ( container ) {
32
+ feedbacks = [ ]
33
+ dom . onPatchStart && dom . onPatchStart ( container )
34
+ } ,
35
+ onNodeAdded ( node ) {
36
+ if ( node . hasAttribute && node . hasAttribute ( "phx-feedback-for" ) ) {
37
+ feedbacks . push ( [ node , node . getAttribute ( "phx-feedback-for" ) ] )
38
+ }
39
+ dom . onNodeAdded && dom . onNodeAdded ( node )
40
+ } ,
41
+ onBeforeElUpdated ( from , to ) {
42
+ let fromFor = from . getAttribute ( "phx-feedback-for" )
43
+ let toFor = to . getAttribute ( "phx-feedback-for" )
44
+ if ( fromFor || toFor ) { feedbacks . push ( [ from , fromFor || toFor ] , [ to , toFor || fromFor ] ) }
45
+
46
+ dom . onBeforeElUpdated && dom . onBeforeElUpdated ( from , to )
47
+ } ,
48
+ onPatchEnd ( container ) {
49
+ resetFeedbacks ( container , feedbacks )
50
+ // we might not find some feedback nodes if they are skipped in the patch
51
+ // therefore we explicitly reset feedbacks for all nodes when the patch
52
+ // follows a submit or input event
53
+ if ( inputPending || submitPending ) {
54
+ resetFeedbacks ( container )
55
+ inputPending = null
56
+ submitPending = null
57
+ }
58
+ dom . onPatchEnd && dom . onPatchEnd ( container )
59
+ }
60
+ }
61
+ }
0 commit comments