0

I'm trying to replicate a carousel type layout with fieldsets. To break down the form into more user friendly chunks, I want to show a fieldset with 12 fields at once, and there are 6 fieldsets. These are only checkboxes so it's not as bad as it sounds!

I've got everything working in terms of the scroll backwards and forwards, but if a click to move the position has taken place, then the window is resized, it layout breaks - you start to see different fieldsets that should not be visible - presumably due to the now incorrect position set by the JS now that the browser width has changed.

I appreciate there may well be a much better way of doing this. However, I wanted to have a slide effect where, because the whole div is moving, the fieldset sliding in happens exactly as the other slides out.

Unfortunately JSFiddle is not working due to viewport width (vw) css. Let me know if there is a way around this.

fiddle

See screenshots below - first one is before clicking 'Next' to move position, second one is after clicking next and then resizing browser. Note, you can resize the browser before clicking 'Next', and it still works fine when you then do click 'Next', it's just resizing after clicking that's causing the problem in the 2nd screenshot.

enter image description here

enter image description here

HTML

<div id="fieldset-container">
    <fieldset>

            <div class="field">
                <div class="checkbox">

                    <label data-container="body" data-toggle="popover" data-placement="top" data-trigger="hover" data-content="<?php echo ($field['definition']); ?>">

                        <input type="checkbox" name="<?php echo ($field['name']); ?>" value="<?php echo ($field['title']); ?>"> <?php echo ($field['title']); ?>

                    </label>

                </div>

            </div>

        <div class="field">
            <div class="checkbox">

                <label data-container="body" data-toggle="popover" data-placement="top" data-trigger="hover" data-content="<?php echo ($field['definition']); ?>">

                    <input type="checkbox" name="<?php echo ($field['name']); ?>" value="<?php echo ($field['title']); ?>"> <?php echo ($field['title']); ?>

                </label>

            </div>

        </div>

        <div class="field">
            <div class="checkbox">

                <label data-container="body" data-toggle="popover" data-placement="top" data-trigger="hover" data-content="<?php echo ($field['definition']); ?>">

                    <input type="checkbox" name="<?php echo ($field['name']); ?>" value="<?php echo ($field['title']); ?>"> <?php echo ($field['title']); ?>

                </label>

            </div>

        </div>

    </fieldset>

    <fieldset>

        <div class="field">
            <div class="checkbox">

                <label data-container="body" data-toggle="popover" data-placement="top" data-trigger="hover" data-content="<?php echo ($field['definition']); ?>">

                    <input type="checkbox" name="<?php echo ($field['name']); ?>" value="<?php echo ($field['title']); ?>"> <?php echo ($field['title']); ?>

                </label>

            </div>

        </div>

        <div class="field">
            <div class="checkbox">

                <label data-container="body" data-toggle="popover" data-placement="top" data-trigger="hover" data-content="<?php echo ($field['definition']); ?>">

                    <input type="checkbox" name="<?php echo ($field['name']); ?>" value="<?php echo ($field['title']); ?>"> <?php echo ($field['title']); ?>

                </label>

            </div>

        </div>

        <div class="field">
            <div class="checkbox">

                <label data-container="body" data-toggle="popover" data-placement="top" data-trigger="hover" data-content="<?php echo ($field['definition']); ?>">

                    <input type="checkbox" name="<?php echo ($field['name']); ?>" value="<?php echo ($field['title']); ?>"> <?php echo ($field['title']); ?>

                </label>

            </div>

        </div>

    </fieldset>

    <button class="fieldset-next">Next</button>
    <button class="fieldset-previous">Previous</button>

</div><!--/#fieldset-container-->

CSS

#fieldset-container {
    width: 600vw;
    overflow: hidden;
    white-space: nowrap;
    margin-right: 100vw;
    position: relative;
}
#fieldset-container fieldset {
    display: inline-block;
    overflow: hidden;
    width: 100vw;
    margin: 0 auto;
    padding: 0 100px;
}

JS

$('.fieldset-next').click(function(e) {
        e.preventDefault();
        var right = parseInt($('#fieldset-container').css("right")) + parseInt($('#fieldset-container fieldset').outerWidth());
        $('#fieldset-container').animate({
            right: right
        },  1000)
});
$('.fieldset-previous').click(function(e) {
    e.preventDefault();
    var right = parseInt($('#fieldset-container').css("right")) - $( window ).width();
    $('#fieldset-container').animate({
        right: right
    },  1000)
});
DJC
  • 1,175
  • 1
  • 15
  • 39

1 Answers1

1

Using the limited resources you provided, I fixed your problem:

$('.fieldset-next').click(function(e) {
  e.preventDefault();
  slide(true);  // console.log(left, width, position);
});
$('.fieldset-previous').click(function(e) {
  e.preventDefault();
  slide(false);
});

function slide(direction) {
 var left = parseInt($('#fieldset-container fieldset').eq(0).offset().left),
      width = $(window).width(), 
      position = (-left/width) + ( direction ? 1 : -1 ),
      length = $('#fieldset-container fieldset').length,
      position = position > length -1 ? length -1 : position;
  slideTo(position);
}

function slideTo(n){
  $('#fieldset-container').css('transform', 'translateX(-'+(n * 100) +'vw)');
}
#fieldset-container {
    width: 300vw;
    overflow: hidden;
    white-space: nowrap;
    position: relative;
    transition: transform .5s cubic-bezier(.5,0,.3,1);
}
#fieldset-container fieldset {
    display: inline-block;
    overflow: hidden;
    margin: 0 auto;
    padding: 0 100px;
    width: calc(100vw - 2px);
    box-sizing: border-box;
   
}
body {
  overflow-x:hidden;
  margin: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="fieldset-container">
    <fieldset>
            <div class="field">
                <div class="checkbox">

                    <label data-container="body" data-toggle="popover" data-placement="top" data-trigger="hover" data-content="<?php echo ($field['definition']); ?>">

                        <input type="checkbox" name="<?php echo ($field['name']); ?>" value="<?php echo ($field['title']); ?>"> <?php echo ($field['title']); ?>

                    </label>

                </div>

            </div>

        <div class="field">
            <div class="checkbox">

                <label data-container="body" data-toggle="popover" data-placement="top" data-trigger="hover" data-content="<?php echo ($field['definition']); ?>">
                    <input type="checkbox" name="<?php echo ($field['name']); ?>" value="<?php echo ($field['title']); ?>"> <?php echo ($field['title']); ?>
                </label>
            </div>
        </div>
        <div class="field">
            <div class="checkbox">
                <label data-container="body" data-toggle="popover" data-placement="top" data-trigger="hover" data-content="<?php echo ($field['definition']); ?>">
                    <input type="checkbox" name="<?php echo ($field['name']); ?>" value="<?php echo ($field['title']); ?>"> <?php echo ($field['title']); ?>
                </label>
            </div>
        </div>
    </fieldset>
    <fieldset>
        <div class="field">
            <div class="checkbox">
                <label data-container="body" data-toggle="popover" data-placement="top" data-trigger="hover" data-content="<?php echo ($field['definition']); ?>">
                    <input type="checkbox" name="<?php echo ($field['name']); ?>" value="<?php echo ($field['title']); ?>"> <?php echo ($field['title']); ?>
                </label>
            </div>
        </div>
        <div class="field">
            <div class="checkbox">
                <label data-container="body" data-toggle="popover" data-placement="top" data-trigger="hover" data-content="<?php echo ($field['definition']); ?>">
                    <input type="checkbox" name="<?php echo ($field['name']); ?>" value="<?php echo ($field['title']); ?>"> <?php echo ($field['title']); ?>
                </label>
            </div>
        </div>
        <div class="field">
            <div class="checkbox">

                <label data-container="body" data-toggle="popover" data-placement="top" data-trigger="hover" data-content="<?php echo ($field['definition']); ?>">

                    <input type="checkbox" name="<?php echo ($field['name']); ?>" value="<?php echo ($field['title']); ?>"> <?php echo ($field['title']); ?>

                </label>
            </div>
        </div>
    </fieldset>
    <fieldset>
        <div class="field">
            <div class="checkbox">
                <label data-container="body" data-toggle="popover" data-placement="top" data-trigger="hover" data-content="<?php echo ($field['definition']); ?>">
                    <input type="checkbox" name="<?php echo ($field['name']); ?>" value="<?php echo ($field['title']); ?>"> <?php echo ($field['title']); ?>
                </label>
            </div>
        </div>
        <div class="field">
            <div class="checkbox">
                <label data-container="body" data-toggle="popover" data-placement="top" data-trigger="hover" data-content="<?php echo ($field['definition']); ?>">
                    <input type="checkbox" name="<?php echo ($field['name']); ?>" value="<?php echo ($field['title']); ?>"> <?php echo ($field['title']); ?>
                </label>
            </div>
        </div>
        <div class="field">
            <div class="checkbox">

                <label data-container="body" data-toggle="popover" data-placement="top" data-trigger="hover" data-content="<?php echo ($field['definition']); ?>">

                    <input type="checkbox" name="<?php echo ($field['name']); ?>" value="<?php echo ($field['title']); ?>"> <?php echo ($field['title']); ?>

                </label>
            </div>
        </div>
    </fieldset>
</div><!--/#fieldset-container-->
    <button class="fieldset-previous">Previous</button>
    <button class="fieldset-next">Next</button>

Please note I had to remove the buttons from the slider container. If you want them related, wrap them in a common container:

<wrapper>
  <slider-container>
  <controls>
</wrapper>

However, I believe your jQuery functions calculating correct positions are a bit off. Let me know if you want me to look into those.


Side note: I've answered today a question about creating a custom slider. It's not directly related but it might help: Trying to Code a Simple Carousel . You might want to skip directly to the example if you're in a rush, although some points noted there might be useful.

Community
  • 1
  • 1
tao
  • 82,996
  • 16
  • 114
  • 150
  • The vw units break the fiddle - it sets the width to the browser width, not the width of the section the result displays in. Unfortunately your fix didn't work - I've uploaded screenshots to show the issue. – DJC Feb 16 '17 at 14:22
  • @CIvemy I'll just delete my answer and wait for you to create the fiddle linking the minimal amount of assets to reproduce the problem. It's not that I can't do it, but it's not normal that I do. I hope you don't mind. – tao Feb 16 '17 at 14:24
  • that's fine - is there a way around the vw units though? As the fiddle is useless as it is. – DJC Feb 16 '17 at 14:24
  • I didn't have the patience, so I created it myself. See updated answer. :) – tao Feb 16 '17 at 14:38
  • What has changed? just the body css? – DJC Feb 16 '17 at 14:49
  • I already had the overflow: hidden. Unfortunately this hasn't made any difference - still shows bits when window is resized just like the screenshots – DJC Feb 16 '17 at 14:52
  • Use [`this`](https://jsfiddle.net/websiter/s3792eaL/) as base. Add resources to it. I can't help you if I can't inspect. – tao Feb 16 '17 at 14:54
  • The fiddle you provided has exactly the same issue. If you click next, when you then resize, the position is off, make the window larger and you start to see the next item, make it smaller and the current item goes off the page – DJC Feb 16 '17 at 14:57
  • You're hard-coding `right` value. That's your problem. Wait, I'll fix it. If you hard-code a value in `px` for right, you either have to recalculate on `resize` event or do your animation differently. – tao Feb 16 '17 at 14:59
  • appreciate the help! – DJC Feb 16 '17 at 14:59
  • Yeah I'd prefer not to have to run anything on resize, quite heavy I imagine – DJC Feb 16 '17 at 15:33
  • [Here it is](https://jsfiddle.net/websiter/s3792eaL/3/). I don't mean to impolite, but you should stop imagining and start reading. The only properties you want to ever animate are `opacity` and `transform`. – tao Feb 16 '17 at 15:46