ControlsContainer doesn't change location of the the nav controls #108

Closed
helgatheviking opened this Issue Apr 4, 2012 · 20 comments

Projects

None yet

3 participants

@helgatheviking

the nav elements end up in the .flexslider div no matter what I enter as the controlsContainer option

jQuery('#carousel').flexslider({
    animation: "slide",
    controlsContainer: "#container"
});

@tylerxo
Contributor
tylerxo commented Apr 4, 2012

How many sliders are being initialized on this page?

If it is just one, is the selector definitely correct?

@helgatheviking

http://www.brooksfabrics.com/test-home/

2 are being initialized. my next question will be how to "link" them so that the 2 use the same set of controls and that each pauses when the other is hovered over.

but back to this question...there is 100% a div with id = container. it isn't where i want the controls (want them in #featured-products) , but i just wanted to verify that I wasn't doing something wrong with the option.

@tylerxo
Contributor
tylerxo commented Apr 4, 2012

The controlsContainer works in an interesting way. When I release the extended documentation for v2.0, the reasoning/functionality behind this should be much clearer.

Due to free nature of the controlsContainer object living anywhere, as well as the ability for multiple sliders, the plugin does its best to follow along as more sliders are passed into one call.

So, in your flexslider initialization, the plugin is parsing this logic:

// First slider setup
$('#container').eq(0) //exists

// Second slider setup
$('#container').eq(1) //does not exist, there is only one #container element

Give me a few and I'll drop you a little template that will give you the functionality you're looking for.

@helgatheviking

i don't quite follow the logic yet, but i look forward to seeing what you come up with!

@tylerxo
Contributor
tylerxo commented Apr 4, 2012

Will the sliders share a controlNav (pagination)? Or will they just share directional navigation?

@helgatheviking

there will be no pagination for either slider. they'll also auto-rotate in sync with one another, which they already do.

@tylerxo
Contributor
tylerxo commented Apr 4, 2012

Here is a rough stab. I think it encapsulates all of the functionality you mentioned. Give it a go and let me know if you find a way to break it. :)

JS:

$('#driver').flexslider({
  animation: "slide",
  controlsContainer: "#featured-products",
  controlNav: false,
  pauseOnHover: true,
  pauseOnAction: false,
  start: function(slider){
    $('.passenger').hover(
      function(){
        slider.pause();
      },
      function(){
        slider.resume();
      }
    );
  }
});
$('.passenger').flexslider({
  animation: "slide",
  controlNav: false,
  directionNav: false,
  pauseOnHover: true,
  pauseOnAction: false,
  start: function(slider){
    $('#driver').hover(
      function(){
        slider.pause();
      },
      function(){
        slider.resume();
      }
    );
    $('.flex-direction-nav li a').click(function(event){
      event.preventDefault();
      var dir = $(this).text().toLowerCase();
      slider.flexAnimate(slider.getTarget(dir));
    });
  }
});

Markup:

<div id="featured-products"></div>
<div id="driver" class="flexslider">
  <ul class="slides">
    ...
  </ul>
</div>
<div class="flexslider passenger">
  <ul class="slides">
    ...
  </ul>
</div>
@helgatheviking

i changed the script to fit the IDs of my markup, but damn, i think that works.

http://www.brooksfabrics.com/test-home/

so far, haven't managed to break it. it pauses on hover, advances when prev/next are clicked and otherwise cycles together.

thanks!

@tylerxo
Contributor
tylerxo commented Apr 4, 2012

Great! You're quite welcome. :)

@helgatheviking

one thing, it doesn't stay paused when hovered over the arrows. idk if that is something that can be easily tweaked or not in the settings.

@tylerxo
Contributor
tylerxo commented Apr 4, 2012

Assuming you changed #driver to #carousel, change #carousel to #featured-products.

Edit: Sorry, make the change here: "$('#driver').hover(" -> $('#featured-products').hover(

@helgatheviking

i think the first suggestion worked too. it messed up some styling, but i was able to fix that with an

overflow:visible !important

declaration on #featured-products.

here's my final code following your 2nd suggestion. it didn't work at first, but that was b/c you assumed #driver was #carousel, when #driver was #slideshow in my markup and .passenger was #carousel

        $('#slider').flexslider({
                  animation: "fade",
                  controlsContainer: "#featured-products",
                  controlNav: false,
                  pauseOnHover: true,
                  pauseOnAction: false,
                  start: function(slider){
                    $('#featured-products').hover(
                      function(){
                        slider.pause();
                      },
                      function(){
                        slider.resume();
                      }
                    );
                  }
                });
                $('#carousel').flexslider({
                  animation: "slide",
                  controlNav: false,
                  directionNav: false,
                  pauseOnHover: true,
                  pauseOnAction: false,
                  start: function(slider){
                    $('#slider, #featured-products').hover(
                      function(){
                        slider.pause();
                      },
                      function(){
                        slider.resume();
                      }
                    );
                    $('.flex-direction-nav li a').click(function(event){
                      event.preventDefault();
                      var dir = $(this).text().toLowerCase();
                      slider.flexAnimate(slider.getTarget(dir));
                    });
                  }
                });

seems to be working. thanks again!

@helgatheviking

and i'm back. :)

while your code is working brilliantly on desktops, it isn't quite holding up on ipads.

clicking (tapping i suppose) on prev/next buttons don't cause the #carousel (#passenger) slider to advance.

and touching sweeping the #carousel div doesn't cause the #slideshow (#driver) div to advance.

out of curiousity what is .flexAnimate i didn't see that anywhere in the documentation?

@tylerxo
Contributor
tylerxo commented Apr 4, 2012

http://www.woothemes.com/flexslider/

  • Click the advanced tab
  • Scroll down a ways, or do a find for ".flexAnimate"

There are brief descriptions of variables available in the callback methods.

As for your problem, I can understand how those events aren't all encapsulated by the click handler on the passenger slider. I need to update the plugin to match a piece I've added into v2.0 to make this solution sound, across all events. I'll try and update it tonight, and then give you updated JS to wrap up this issue.

Sorry about that.

@helgatheviking

roger that. i thought it was the .click handler not working w/ touch events. hope you can get it updated.... that'll be sweet.

@tylerxo
Contributor
tylerxo commented Apr 5, 2012

Alright, the new code is updated. Make sure you download the new code or this will not work. The solution is actually much simpler now, and should be bulletproof, famous last words.

$('#carousel').flexslider({
  animation: "slide",
  controlNav: false,
  directionNav: false,
  pauseOnHover: true,
  pauseOnAction: false,
  start: function(slider){
    $('#slider, #featured-products').hover(
      function(){
        slider.pause();
      },
      function(){
        slider.resume();
      }
    );
  }
});
$('#slider').flexslider({
  animation: "fade",
  controlsContainer: "#featured-products",
  controlNav: false,
  pauseOnHover: true,
  pauseOnAction: false,
  start: function(slider){
    $('#featured-products').hover(
      function(){
        slider.pause();
      },
      function(){
        slider.resume();
      }
    );
  },
  before: function(slider){
    $('#carousel').data('flexslider').flexAnimate(slider.animatingTo);
  }
});
@helgatheviking

look great so far!! have to wait on some feedback from an actual ipad user since i'm living in the technological stone ages myself. ;)

i'm still confused about

// First slider setup
$('#container').eq(0) //exists

// Second slider setup
$('#container').eq(1) //does not exist, there is only one #container element

i'm toying around with only using 1 slider at a time or keeping them both but unlinking their behavior (since i'm sure i'll be using flexslider again, but not in this weirdly complicated paired slider way)... and for some reason if i have them initialized one at a time.

$('#slider').flexslider({  
    controlsContainer: "#featured-products" 
});

appends the controls to the #featured-products div, while

$('#carousel').flexslider({  
    controlsContainer: "#featured-products" 
});

does not, but instead appends the controls to the default class = "flexslider" (which is the #carousel div).

similarly, if i try to initialize them both:

$('#slider').flexslider({
controlsContainer: "#featured-products",
controlNav: false
});

$('#carousel').flexslider({
controlNav: false,
directionNav: false
});


puts the controls in the correct div, but inverting that


$('#slider').flexslider({
controlNav: false,
directionNav: false
});

$('#carousel').flexslider({
controlsContainer: "#featured-products",
controlNav: false
});


puts the controls back in the #carousel div.  i'm definitely imposing on your assistance, but i'm trying to get a handle on how they might work either solo... or in multiple instances that work independently of each other.  
@tylerxo
Contributor
tylerxo commented Apr 5, 2012

To preface what I am about to explain, I'll say that you just shook loose a realization in my head. I know how to fix this issue in v2.

Right now, the plugin runs under the assumption that the selector it will receive for the controlsContainer, in the case of multiple sliders on one page, will be a class. It's not exactly an elegant assumption, but it is necessary to derive a flexible level of accuracy. This is why everything I've written on the FlexSlider site and on the demo.html uses classes.

The following is an excerpt from jquery.flexslider.js where the controlsContainer is tested:

//Test for controlsContainer
if (slider.vars.controlsContainer != "") {
  slider.controlsContainer = $(slider.vars.controlsContainer).eq($('.slides').index(slider.container));
  slider.containerExists = slider.controlsContainer.length > 0;
}

$(slider.vars.controlsContainer).eq($('.slides').index(slider.container));

  • $(slider.vars.controlsContainer) - Make a jQuery object from the selector given, presumably a class
  • .eq() - go to an index position within the jQuery object array
  • $('.slides').index(slider.container) - Assuming the 'ul.slides' pattern for FlexSliders, find the index of THIS slider in that array

When you throw ID's into the picture here, this code breaks down. Here is what your two calls are producing:

// $('#slider').flexslider() parses this:
$('#featured-products').eq(0) //exists, because there is one element in that object array

// $('#carousel').flexslider() parses this:
$('#featured-products').eq(1) //does not exist

The reason you get .eq(1) in the second slider initialization is because you have two .slides objects, and the .slides object within that slider is in the second array position.

Coming back around to my preface, I believe I know how to fix this. I can put in a clause that checks if the given selector is an ID, and if it is, I can forgo the .eq(index) business that is creating this issue.

That help clear up the issue?

@helgatheviking

upon reading : #85 i have switched to using a class for the controlsContainer and that solves it. .eq() is still new to me.... got a lot of jquery left to learn, but for now that makes it work in just about any configuration i can set up. Thanks so much for all your help!

@tylerxo tylerxo closed this Apr 11, 2012
@shilpamahajan08

what is meaning of controlsContainer anybody plz explain?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment