Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to disable jQuery accordion conditionally

I want to enable and disable or better to add and remove jQuery accordion on my menu conditionally, is it possible to add or remove this on screen rotate or screen-size change ? I tried it but It does not seems to be working, The accordion is remaining for change in screen-size .

jQuery( document ).ready( function(){
    apply_accordion();
    jQuery(window).on("orientationchange",function(){
        apply_accordion();
    });
} );
function apply_accordion(){
    if (jQuery(window).width() < 540) {
        jQuery('.footer-area').accordion({
            icons: { "header": "icon-large ui-icon-carat-1-s", "activeHeader": "icon-large ui-icon-caret-1-n" },
            active: false,
            autoHeight: false,
            navigation: true,
            collapsible: true,
        });
    } else {
        //jQuery( '.footer-area' ).accordion( "disable" );
        //jQuery( '.footer-area' ).accordion( "destroy" );
        // jQuery( '.footer-area' ).accordion( "refresh" );
        jQuery( '.footer-area' ).accordion( "destroy" ).accordion();
    }
}

update

if else part will be,

} else {
    jQuery( '.footer-area' ).accordion( "destroy" );
    jQuery('.footer-area').accordion('option', 'active', 0);
}

when I starts with moving from portrait to landscape, it is working, but the reverse is not working , means when I am moving from landscape to portrait it is not working . And also gives error in console cannot call methods on accordion prior to initialization; attempted to call method 'destroy'

New jsfield

I would like to remove and add accordion with screen size.

Note:

jQuery version 1.11.4

check Techbreak's answer https://jsfiddle.net/voytfj2q/20/ it seems to be working but if you will check console it will generate " Uncaught Error: cannot call methods on accordion prior to initialization; attempted to call method 'destroy'" . and in actual implementation it does not work when I am moving from landscape to portrait.

And I have also posted an workaround, for now in my implementation it is working for me, but I know this is only a workaround.

Here is another fiddle if you will increase and decrease the screen-size slowly you can notice the issue.

Screenshot of issue, you can notice for few of them the accordion is disabled for increase in size and for some it is not disabled.

enter image description here

like image 755
Prafulla Kumar Sahu Avatar asked Dec 01 '16 05:12

Prafulla Kumar Sahu


2 Answers

You need to activate the accordian to expand when the size is big enough to expand the content or screen rotated completely as follows,

jQuery(document).ready(function() {

  jQuery(window).on("resize", function() {
      if (jQuery(window).width() < 540) {

          jQuery('.footer-area').accordion({
              active: false, collapsible:true, active:true
          });
      } else {
          //reactivate the accordian so that it can be expanded again
          jQuery('.footer-area').accordion('option', 'active', 0);
      }
   });

Working fiddle for your example : https://jsfiddle.net/voytfj2q/18/ });

like image 145
ScanQR Avatar answered Oct 17 '22 13:10

ScanQR


OK. Actually, you have solved the issue with many different instances of the accordion, which wasn't in evidence from your original post, so the wrong selector .footer-area used here:

      jQuery('.footer-area').accordion({
          active: false, collapsible:true, active:true
      });

has been adjusted.

Issue #1:

As you need to create and destroy the widget based on the page size, we need to check for the existence of every widget instance before calling any method of the accordion, otherwise we will raise the infamous error: ...cannot call methods on *some-widget* prior to initialization.

This issue is solved by checking for the existence of the data which has been appended to the element at widget instance creation:

var isInstance1 = (typeof jQuery('#footer-widget-area-1 .footer-area').data("ui-accordion") != "undefined");

Issue #2:

When you are switching back to the unstyled menu, the page height will increase and the page will show the vertical scrollbar, which is resulting in a different page width. The page is resized again and your check for window.width will behave unstable.

This is the reason why you need to check for jQuery('body').width() + scrollbar_width(). Simply take the provided function to get the scrollbar width as-is, and include it in your snippet lbrary.

Fiddle: https://jsfiddle.net/Lgx4es86/6/

/* Calculates scrollbar width in pixels */
function scrollbar_width() {
    if( jQuery('body').height() > jQuery(window).height()) {

        /* Modified from: http://jdsharp.us/jQuery/minute/calculate-scrollbar-width.php */
        var calculation_content = jQuery('<div style="width:50px;height:50px;overflow:hidden;position:absolute;top:-200px;left:-200px;"><div style="height:100px;"></div>');
        jQuery('body').append( calculation_content );
        var width_one = jQuery('div', calculation_content).innerWidth();
        calculation_content.css('overflow-y', 'scroll');
        var width_two = jQuery('div', calculation_content).innerWidth();
        jQuery(calculation_content).remove();
        return ( width_one - width_two );
    }
    return 0;
}

jQuery( document ).ready( function(){
    apply_accordion();
    jQuery(window).resize(function() {
        apply_accordion();
    });
} );
function apply_accordion(){
  var ww = jQuery('body').width() + scrollbar_width();
    if (ww < 540) {
        jQuery('#footer-widget-area-1 .footer-area').accordion({
                active: false, collapsible:true
            });
        jQuery('#footer-widget-area-2 .footer-area').accordion({
                active: false, collapsible:true
            });
        jQuery('#footer-widget-area-3 .footer-area').accordion({
                active: false, collapsible:true
            });
        jQuery('#footer-widget-area-5 .footer-area').accordion({
                active: false, collapsible:true
            });
        jQuery('#footer-widget-area-6 .footer-area').accordion({
                active: false, collapsible:true
            });
        } else {
            var isInstance1 = (typeof jQuery('#footer-widget-area-1 .footer-area').data("ui-accordion") != "undefined");
            if (isInstance1) {
                jQuery('#footer-widget-area-1 .footer-area').accordion('option', 'active', 0);
                jQuery('#footer-widget-area-1 .footer-area').accordion("destroy");
            }
            var isInstance2 = (typeof jQuery('#footer-widget-area-2 .footer-area').data("ui-accordion") != "undefined");
            if (isInstance2) {
                jQuery('#footer-widget-area-2 .footer-area').accordion('option', 'active', 0);
                jQuery('#footer-widget-area-2 .footer-area').accordion("destroy");
            }
            var isInstance3 = (typeof jQuery('#footer-widget-area-3 .footer-area').data("ui-accordion") != "undefined");
            if (isInstance3) {
                jQuery('#footer-widget-area-3 .footer-area').accordion('option', 'active', 0);
                jQuery('#footer-widget-area-3 .footer-area').accordion("destroy");
            }
            var isInstance5 = (typeof jQuery('#footer-widget-area-5 .footer-area').data("ui-accordion") != "undefined");
            if (isInstance5) {
                jQuery('#footer-widget-area-5 .footer-area').accordion('option', 'active', 0);
                jQuery('#footer-widget-area-5 .footer-area').accordion("destroy");
            }
            var isInstance6 = (typeof jQuery('#footer-widget-area-6 .footer-area').data("ui-accordion") != "undefined");
            if (isInstance6) {
                jQuery('#footer-widget-area-6 .footer-area').accordion('option', 'active', 0);
                jQuery('#footer-widget-area-6 .footer-area').accordion("destroy");
            }
        // var isInstance = (typeof jQuery('.footer-area').data("ui-accordion") != "undefined");
        // if (isInstance){
        //  jQuery('.footer-area').accordion('option', 'active', 0);
        //  jQuery('.footer-area').accordion( "destroy" );
        // }
    }
}

Your workaround:

You are applying and removing the accordion styles, but not destroying the widget instances, so data event handlers are still there. You would need at least to move the jQuery('.footer-area').accordion part in another place to execute it just only one time. Moreover, beside this, the page width issue isn't solved by your workaround.

Scrollbar width function: credit Alex Mansfield (http://alexmansfield.com/javascript/css-jquery-screen-widths-scrollbars)

like image 29
deblocker Avatar answered Oct 17 '22 15:10

deblocker