Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rendering incorrect when used within toggable tabs #376

Closed
Adspectus opened this issue Nov 9, 2014 · 18 comments
Closed

Rendering incorrect when used within toggable tabs #376

Adspectus opened this issue Nov 9, 2014 · 18 comments
Assignees
Labels
Milestone

Comments

@Adspectus
Copy link

When using it within toggable tabs, on the invisible tabs the rendering is not correct:

    <div class="container">
      <div class="tab-content">
        <div class="tab-pane active" id="start">
          <p>Hallo Welt</p>
          <input type="checkbox" name="test" checked>
        </div>
        <div class="tab-pane" id="test1">
          <p>Test 1</p>
        </div>
        <div class="tab-pane" id="test2">
          <p>Test 2</p>
        </div>
        <div class="tab-pane" id="test3">
          <p>Test 3</p>
        </div>
        <div class="tab-pane" id="debug">
          <p class="text-center visible-xs-block">Current Device: Extra Small</p>
          <p class="text-center visible-sm-block">Current Device: Small</p>
          <p class="text-center visible-md-block">Current Device: Medium</p>
          <p class="text-center visible-lg-block">Current Device: Large</p>
          <input type="checkbox" name="test" checked>
        </div>
      </div>
    </div>

Only the first checkbox is rendered correct, checkboxes on all other tabs are rendered as a vertical line. I examined the code and noticed, that all widths are set to 0px. For example, instead of

<div class="bootstrap-switch-container" style="width: 159px; margin-left: -53px;">

the code is generated as:

<div class="bootstrap-switch-container" style="width: 0px; margin-left: 0px;">

I am using bootstrap 3.2.0 and jQuery 2.1.1

@salt-istanbul
Copy link

I have same problem when using inside collapse.

@fribergr
Copy link

Same problem inside a div with display: none.
Using jQuery 1.11.1, Bootstrap 3.2.0 and Bootstrap Switch 3.2.1

@LostCrew
Copy link
Member

thanks for submitting the issue.
this happens because during bootstrap switch init, if the switch is not visible, the logic that calculate and apply the width to the switch's elements does not work.
as temporary workaround, you can call the internal method _width() on tab changing, like this:

// on tab changing
$('#my-switch').bootstrapSwitch('_width');

let me know if it helps.

@fribergr
Copy link

Seems to work. However, could the way the width is calculated possibly be changed? I guess I'll end up with a lot of excessive code otherwise :)

Currently have this at every page that has tabs:

$('a[data-toggle="tab"]').on('shown.bs.tab', function(e) {
    $('.create-switch').bootstrapSwitch('_width');
});

@fribergr
Copy link

For some reason, the _width-workaround worked fine when using tabs, but not when using a <div style="display: none">
For that I used:

$('.create-switch').bootstrapSwitch('destroy');
$('.create-switch').bootstrapSwitch();

When the .show() is triggered on the div.

@Adspectus
Copy link
Author

I can confirm that the following code renders switches correct - on first sight:

$( "[name='test']" ).bootstrapSwitch();

$('a[data-toggle="tab"]').on('shown.bs.tab', function(e) {
    $( "[name='test']" ).bootstrapSwitch('_width');
});

However, unchecked and indeterminated states are not correctly set when navigating to the other tabs. When using this HTML:

    <div class="container">
      <div class="tab-content">
        <div class="tab-pane active" id="start">
          <p>Hallo Welt</p>
          <input type="checkbox" name="test" checked="true"  data-on-text="Ja" data-on-color="success" data-off-text="Nein" data-off-color="danger">
          <input type="checkbox" name="test" data-on-text="Ja" data-on-color="success" data-off-text="Nein" data-off-color="danger">
          <input type="checkbox" name="test" data-on-text="Ja" data-on-color="success" data-off-text="Nein" data-off-color="danger" data-indeterminate="true">
        </div>
        <div class="tab-pane" id="test1">
          <p>Test 1</p>
        </div>
        <div class="tab-pane" id="test2">
          <p>Test 2</p>
          <input type="checkbox" name="test" checked="true"  data-on-text="Ja" data-on-color="success" data-off-text="Nein" data-off-color="danger">
          <input type="checkbox" name="test" data-on-text="Ja" data-on-color="success" data-off-text="Nein" data-off-color="danger">
          <input type="checkbox" name="test" data-on-text="Ja" data-on-color="success" data-off-text="Nein" data-off-color="danger" data-indeterminate="true">
        </div>
        <div class="tab-pane" id="test3">
          <p>Test 3</p>
        </div>
        <div class="tab-pane" id="debug">
          <p class="text-center visible-xs-block">Current Device: Extra Small</p>
          <p class="text-center visible-sm-block">Current Device: Small</p>
          <p class="text-center visible-md-block">Current Device: Medium</p>
          <p class="text-center visible-lg-block">Current Device: Large</p>
          <input type="checkbox" name="test" checked="true"  data-on-text="Ja" data-on-color="success" data-off-text="Nein" data-off-color="danger">
          <input type="checkbox" name="test" data-on-text="Ja" data-on-color="success" data-off-text="Nein" data-off-color="danger">
          <input type="checkbox" name="test" data-on-text="Ja" data-on-color="success" data-off-text="Nein" data-off-color="danger" data-indeterminate="true">
        </div>
      </div>
    </div>

the switches on the second and third instance are all set to "Ja". I had to extend the JavaScript code to the following to get it running:

$( "[name='test']" ).bootstrapSwitch();

$('a[data-toggle="tab"]').on('shown.bs.tab', function(e) {
    $( "[name='test']" ).bootstrapSwitch('_width');
    $( "input[name='test']:not(:checked)" ).bootstrapSwitch('state',false);
    $( "input[data-indeterminate='true'][name='test']" ).bootstrapSwitch('indeterminate',true);
});

@penihel
Copy link

penihel commented Nov 12, 2014

I have the same problem with bootstrap modal

@penihel
Copy link

penihel commented Nov 12, 2014

My workaround solution

    //bootstrap workaround modal with bootstrap-switch
    $(document).on('shown.bs.modal', '.modal', function (e) {
        $(e.target).find('input[type=checkbox]').each(function (index, chk) {
            if ($(chk).data('bootstrap-switch') != null) {
                $(chk).bootstrapSwitch('_width');
            }

        });
    });

@LostCrew
Copy link
Member

@Adspectus the second reported problem is, in fact, this #337 so join the discussion there. to avoid the problem, you could temporarily set different names to the checkboxes you are applying the switch to.

@penihel that's a good job, however we must consider it a workaround.

on the spot, i figured that the switch could automatically listen for change to its visibility status and call _width everytime it is visible. that has many chances to solve the issue.

@LostCrew LostCrew added this to the 3.2.2 milestone Nov 15, 2014
@LostCrew LostCrew added the bug label Nov 15, 2014
LostCrew pushed a commit that referenced this issue Nov 15, 2014
@LostCrew
Copy link
Member

fixed, included in 3.2.2.

@PaddySe
Copy link

PaddySe commented Nov 18, 2014

I'm still experiencing the problems with state and indeterminate being rendered incorrectly on non-displayed tabs in 3.2.2. Setting different names, as suggested in #337, doesn't help.
The width is correct, but they are always rendered as is they are checked, even if state is false or there is no checked attribute on the checkboxes.

@bcelik
Copy link

bcelik commented Nov 19, 2014

I also do have problem after updating from 3.0.2 to 3.2.2 that switch state is rendered wrong in non displayed tabs and in modals. If i do call bootstrapSwitch() with a timeout after showing modal it renders ok. What i also noticed is that bootstrapSwitch is now atleast 5x slower than 3.0.2. This is very noticable if you have like 20 switches. I have a table with 20 rows. calling bootstrapSwitch() on table took 40-50 ms on version 3.0.2, with version 3.2.2 it takes about 250-300ms

@LostCrew
Copy link
Member

@PaddySe the issue is not related. please do a search and open a new issue if there isn't any. don't forget to attach a playground link (jsfiddle, codepen..)

@bcelik it is slower because it makes calculation on init regarding the width to apply to the side handles and the centred label. the same calculation is also performed every time the switch is updated in a way that affect the width. i will try to reduce the time through avoiding DOM manipulation and optimizing the internal operations.

@PranayShah
Copy link

I have this issue as well. Setting states does not work.

@kulikovviktor
Copy link

Setting states does not work. +1

@LostCrew
Copy link
Member

@PranayShah @kulikovviktor you can try out develop branch or wait for v3.2.3 to be out (today). thanks.

@LostCrew LostCrew removed their assignment Dec 21, 2014
@LostCrew LostCrew self-assigned this Dec 21, 2014
@SamKirkland
Copy link

SamKirkland commented Sep 22, 2017

For anyone still having this issue calling the _width method only when the switch is visible resolves the issue for my use cases. Example below.

bootstrap switch version: v3.3.4 (latest)
bootstrap version: v3.3.7 (latest)

$(document).ready(function() {
    $('body').on('shown.bs.tab', function(e) {
        var $switches = $('.bootstrap-switch-container input');
        $switches.each(function(index, element) {
            var $element = $(element);
            if ($element.is(':visible')) {
                $element.bootstrapSwitch('_width');
            }
        });
    });
});

@utkuhalis
Copy link

For some reason, the _width-workaround worked fine when using tabs, but not when using a <div style="display: none">
For that I used:

$('.create-switch').bootstrapSwitch('destroy');
$('.create-switch').bootstrapSwitch();

When the .show() is triggered on the div.

Thanks a lot i fix with this code

    $('a[data-toggle="pill"]').on('shown.bs.tab', function (e) {
        $("input[data-bootstrap-switch]").each(function(){
            $(this).bootstrapSwitch('destroy');
            $(this).bootstrapSwitch();
            $(this).bootstrapSwitch('state', $(this).prop('checked'));
        });
    });

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests