@@ -12,23 +12,41 @@ ko.bindingHandlers.popover = {
12
12
ko . bindingHandlers . popover . initPopover ( element , valueAccessor ) ;
13
13
} ,
14
14
update : function ( element , valueAccessor ) {
15
+ var $element = $ ( element ) ,
16
+ instance = $element . data ( 'bs.popover' ) ,
17
+ popOptions = ko . bindingHandlers . popover . getOptions ( valueAccessor ) ,
18
+ combinedOptions = popOptions . combinedOptions ,
19
+ options = popOptions . options ;
20
+
21
+ if ( ! instance ) {
22
+ ko . bindingHandlers . popover . initPopover ( element , valueAccessor ) ;
23
+ instance = $element . data ( 'bs.popover' ) ;
24
+ }
25
+
26
+ if ( ! instance )
27
+ return ;
28
+
29
+ // if view model has changed, update the popover
30
+ instance . config . title = combinedOptions . title || "" ;
31
+ instance . config . content = combinedOptions . content ;
15
32
16
- var $element = $ ( element ) ;
17
- $element . popover ( 'dispose' ) ;
18
- var options = ko . bindingHandlers . popover . initPopover ( element , valueAccessor ) ;
19
33
if ( options . autoShow ) {
20
34
if ( $element . data ( 'firstPopover' ) === false ) {
21
- $element . popover ( ' show' ) ;
35
+ instance . show ( ) ;
22
36
$ ( 'body' ) . on ( 'click' , function ( e ) {
23
-
24
37
if ( e . target != element && $element . find ( e . target ) . length == 0 ) {
25
- $element . popover ( 'dispose' ) ;
38
+ instance . hide ( ) ;
26
39
}
27
40
} ) ;
28
41
}
42
+
29
43
$element . data ( 'firstPopover' , false ) ;
30
44
}
31
45
46
+ // refresh popover content
47
+ if ( ko . bindingHandlers . popover . isPopoverShown ( element ) ) {
48
+ instance . show ( ) ;
49
+ }
32
50
} ,
33
51
34
52
defaultOptions : {
@@ -39,23 +57,41 @@ ko.bindingHandlers.popover = {
39
57
} ,
40
58
41
59
initPopover : function ( element , valueAccessor ) {
42
- var options = ko . utils . unwrapObservable ( valueAccessor ( ) ) ;
60
+ var popOptions = ko . bindingHandlers . popover . getOptions ( valueAccessor ) ,
61
+ options = popOptions . options ,
62
+ combinedOptions = popOptions . combinedOptions ;
63
+ $ ( element ) . popover ( combinedOptions ) ;
64
+ ko . utils . domNodeDisposal . addDisposeCallback ( element , function ( ) {
65
+ $ ( element ) . popover ( "dispose" ) ;
66
+ } ) ;
43
67
44
- if ( typeof ( options . content ) === "undefined" ) {
68
+ return options ;
69
+ } ,
70
+ /**
71
+ * constructs the options object from valueAccessor
72
+ * @param valueAccessor
73
+ * @returns {{combinedOptions: any, options: any} }
74
+ */
75
+ getOptions : function ( valueAccessor ) {
76
+ var options = ko . utils . unwrapObservable ( valueAccessor ( ) ) ;
77
+ if ( typeof ( options . content ) === "undefined" ) {
45
78
options . content = ""
46
79
}
47
80
48
81
var combinedOptions = ko . utils . extend ( { } , ko . bindingHandlers . popover . defaultOptions ) ;
49
82
var content = ko . utils . unwrapObservable ( options . content ) ;
50
83
ko . utils . extend ( combinedOptions , options ) ;
51
84
combinedOptions . description = content ;
52
-
53
- $ ( element ) . popover ( combinedOptions ) ;
54
-
55
- ko . utils . domNodeDisposal . addDisposeCallback ( element , function ( ) {
56
- $ ( element ) . popover ( "dispose" ) ;
57
- } ) ;
58
- return options ;
85
+ return { combinedOptions : combinedOptions , options : options } ;
86
+ } ,
87
+ /**
88
+ * id of the popover is stored in the element's aria-describedby attribute
89
+ * @param element
90
+ * @returns {boolean }
91
+ */
92
+ isPopoverShown : function isPopoverShown ( element ) {
93
+ const popoverId = $ ( element ) . attr ( "aria-describedby" ) ;
94
+ return $ ( "#" + popoverId ) . length > 0 ;
59
95
}
60
96
} ;
61
97
0 commit comments