@@ -32,9 +32,22 @@ QueryBuilder.define('filter-description', function(options) {
3232 }
3333 // POPOVER
3434 else if ( options . mode === 'popover' ) {
35- if ( ! $ . fn . popover || ! $ . fn . popover . Constructor || ! $ . fn . popover . Constructor . prototype . fixTitle ) {
36- Utils . error ( 'MissingLibrary' , 'Bootstrap Popover is required to use "filter-description" plugin. Get it here: http://getbootstrap.com' ) ;
37- }
35+ // Helper function to safely access Bootstrap Popover
36+ var getBootstrapPopover = function ( ) {
37+ var bootstrapObj = null ;
38+ try {
39+ if ( typeof window !== 'undefined' && window . bootstrap && typeof window . bootstrap . Popover === 'function' ) {
40+ return window . bootstrap . Popover ;
41+ } else if ( typeof bootstrap !== 'undefined' && typeof bootstrap . Popover === 'function' ) {
42+ return bootstrap . Popover ;
43+ }
44+ } catch ( e ) {
45+ // Handle any errors silently
46+ }
47+
48+ // If we get here, Bootstrap Popover is not available
49+ throw new Error ( 'Bootstrap Popover is not available. Make sure Bootstrap 5 is loaded.' ) ;
50+ } ;
3851
3952 this . on ( 'afterUpdateRuleFilter afterUpdateRuleOperator' , function ( e , rule ) {
4053 var $b = rule . $el . find ( 'button.filter-description' ) ;
@@ -43,31 +56,76 @@ QueryBuilder.define('filter-description', function(options) {
4356 if ( ! description ) {
4457 $b . hide ( ) ;
4558
46- if ( $b . data ( 'bs-popover' ) ) {
47- $b . popover ( 'hide' ) ;
59+ // Hide existing popover using Bootstrap 5 API
60+ try {
61+ var PopoverClass = getBootstrapPopover ( ) ;
62+ var existingPopover = PopoverClass . getInstance ( $b . get ( 0 ) ) ;
63+ if ( existingPopover ) {
64+ existingPopover . hide ( ) ;
65+ }
66+ } catch ( e ) {
67+ console . warn ( 'Failed to hide popover:' , e . message ) ;
4868 }
4969 }
5070 else {
5171 if ( $b . length === 0 ) {
5272 $b = $ ( $ . parseHTML ( '<button type="button" class="btn btn-sm btn-info filter-description" data-bs-toggle="popover"><i class="' + options . icon + '"></i></button>' ) ) ;
5373 $b . prependTo ( rule . $el . find ( QueryBuilder . selectors . rule_actions ) ) ;
54- const popover = new bootstrap . Popover ( $b . get ( 0 ) , {
55- placement : 'left' ,
56- container : 'body' ,
57- html : true
58- } )
59- $b . on ( 'mouseout' , function ( ) {
60- popover ( 'hide' ) ;
61- } ) ;
74+
75+ // Create Bootstrap 5 popover
76+ try {
77+ var PopoverClass = getBootstrapPopover ( ) ;
78+ var popover = new PopoverClass ( $b . get ( 0 ) , {
79+ placement : 'left' ,
80+ container : 'body' ,
81+ html : true ,
82+ content : description
83+ } ) ;
84+
85+ $b . on ( 'mouseout' , function ( ) {
86+ popover . hide ( ) ;
87+ } ) ;
88+ } catch ( e ) {
89+ console . warn ( 'Failed to create popover:' , e . message ) ;
90+ }
6291 }
6392 else {
6493 $b . css ( 'display' , '' ) ;
65- }
6694
67- $b . data ( 'bs-popover' ) . options . content = description ;
95+ // Update existing popover content
96+ try {
97+ var PopoverClass = getBootstrapPopover ( ) ;
98+ var existingPopover = PopoverClass . getInstance ( $b . get ( 0 ) ) ;
99+ if ( existingPopover ) {
100+ // Dispose and recreate with new content (Bootstrap 5 doesn't have easy content update)
101+ existingPopover . dispose ( ) ;
102+ var newPopover = new PopoverClass ( $b . get ( 0 ) , {
103+ placement : 'left' ,
104+ container : 'body' ,
105+ html : true ,
106+ content : description
107+ } ) ;
108+
109+ $b . on ( 'mouseout' , function ( ) {
110+ newPopover . hide ( ) ;
111+ } ) ;
112+ }
113+ } catch ( e ) {
114+ console . warn ( 'Failed to update popover:' , e . message ) ;
115+ }
116+ }
68117
118+ // Show popover if it should be visible
69119 if ( $b . attr ( 'aria-describedby' ) ) {
70- $b . popover ( 'show' ) ;
120+ try {
121+ var PopoverClass = getBootstrapPopover ( ) ;
122+ var currentPopover = PopoverClass . getInstance ( $b . get ( 0 ) ) ;
123+ if ( currentPopover ) {
124+ currentPopover . show ( ) ;
125+ }
126+ } catch ( e ) {
127+ console . warn ( 'Failed to show popover:' , e . message ) ;
128+ }
71129 }
72130 }
73131 } ) ;
0 commit comments