1. Advertising
    y u no do it?

    Advertising (learn more)

    Advertise virtually anything here, with CPM banner ads, CPM email ads and CPC contextual links. You can target relevant areas of the site and show ads based on geographical location of the user if you wish.

    Starts at just $1 per CPM or $0.10 per CPC.

Owl Carousel 2 switches to default position after Ajax call

Discussion in 'JavaScript' started by habotho, Apr 23, 2016.

  1. #1
    Hello gurus!

    I'm a real noob at js so I hope I'll find working solution to solve my problem. I'm working on Drupal 7 project based on Porto template v.2.1 using Dupal Commerce module. I've implemented Owl Carousel 2 v. 2.1.0 with jQuery 1.12.3.
    At the product display page I have few attribute widgets which are carousels. All my carousels items are clickable (product attributes which loads big picture of a model with related attributes by Ajax calls). One widget has more than 30 items (models which are taxonomy terms), now it has just 14 items. So I call for that widget (div) carousel plugin with following code:

    (function($) {
        Drupal.behaviors.myBehavior = {
          attach: function (context) {
            $('.attribute-widgets > div > div ').addClass("owl-carousel");
            $('.attribute-widgets > div > div ').addClass("owl-theme");
            var owl = $('.owl-carousel');
                owl.owlCarousel({
                    dots: false,
                    margin: 10,
                    autoWidth: false,
                    responsive:{
                        640:{
                            items:3,
                            nav: true,
                            navText: "",
                        },
                        768:{
                            items:4,
                            nav: true,
                            navText: "",
                        },
                        1024:{
                            items:7,
                            nav: true,
                            navText: "",
                        },
                        1280:{
                            items:9,
                            nav: true,
                            navText: "",
                        },
                        1366:{
                            items:10,
                            nav: true,
                            navText: "",
                        },
                        1600:{
                            items:13,
                            nav: true,
                            navText: "",
                        },
                    }
                });
            }
        };
    })(jQuery);
    Code (JavaScript):
    And here how it looks like:

    [​IMG]

    [​IMG]

    So when you move to the last item for example which is not visible when page loads first time and click on that item, carousel switches to it default position and clicked item become not visible, but I want carousel to stay after click in the same position before clicking.

    All those color squares below are carousels too which are respresents product attributes such as door color, glass color etc, so those carousels should keep their current positions after their items being clicked.

    Is there a possibility to do that by modificating my js code? All matching examples are really appreciated!

    Also what I want to make work is when you click on middle+1 item carousel should moves forward for one item, when you click on middle+2 item carousel should moves forward for two items, the same for +3 and +4. And carousel should have possibility to move backwards after clicking middle-1 items, middle-2 item and etc.

    Really hope to get real examples of how can I make all this work, cause my knowledge don't allow me to make is by myself.

    Thanks in advance,
    Ilya
     
    habotho, Apr 23, 2016 IP
  2. habotho

    habotho Greenhorn

    Messages:
    9
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    21
    #2
    Here is the current version of this website: http://srv109687.hoster-test.ru/каталог/серия-U
     
    habotho, Apr 23, 2016 IP
  3. Blizzardofozz

    Blizzardofozz Well-Known Member

    Messages:
    132
    Likes Received:
    9
    Best Answers:
    1
    Trophy Points:
    118
    #3
    I guess the ajax request when finises resets the carousel to its initial state. Is the ajax request a part of the carousel or you modified it? Because I don't see the functionality of loading the clicked item into bigger image to be a part of this carousel.
     
    Blizzardofozz, Apr 24, 2016 IP
  4. habotho

    habotho Greenhorn

    Messages:
    9
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    21
    #4
    Hello! Thanks for your reply! Yes, you're right. It seems that when new content is loaded by Ajax call, carousel resests to it initial state. Ajax request is not a part of carousel code. Commerce Fancy Attribute module is responsible for loading big picture and related attributes widgets.
     
    habotho, Apr 24, 2016 IP
  5. Blizzardofozz

    Blizzardofozz Well-Known Member

    Messages:
    132
    Likes Received:
    9
    Best Answers:
    1
    Trophy Points:
    118
    #5
    Could you check or post the code where you are getting the result from the ajax call and what is happening after that. How you use the result from the ajax call and what is affected by them. Because it looks like those results are affecting the carousel code somehow.

    Lots of things in the code are changing after I click a door. Shouldn't the only thing that is changing be the large image of the door? The Ajax call should change only the large image right?
     
    Last edited: Apr 24, 2016
    Blizzardofozz, Apr 24, 2016 IP
  6. habotho

    habotho Greenhorn

    Messages:
    9
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    21
    #6
    Well actually I develope this website using drupal 7 and drupal modules only without any custom coding exept js plugin which calls owl carousel. I can explain how did I make the structure, but I don't know if you familiar with drupal. You are right about changing the big picture after clicking on any carousel item, but in this case the parent is the thumbnail of a door. When you click on it door thumb, Ajax loads big picture of that model and related attributes widgets, such as door color, glass color and etc.
     
    habotho, Apr 24, 2016 IP
  7. Blizzardofozz

    Blizzardofozz Well-Known Member

    Messages:
    132
    Likes Received:
    9
    Best Answers:
    1
    Trophy Points:
    118
    #7
    So you use same settings for 3 carousels and you need to change the settings of the carousel after each click so you can have the specific colors for each door but probably this resets to its initial state the doors carousel which is your problem in this case.

    As it is right now I don't see why you need a carousel for the colors and the windows. Maybe if you don't use carousel for colors and windows there will be no need to reset the carousel and doors will just stay in current position. Or if you use different classes for each carousel so you can reset colors and windows but don't affect the doors.

    As I see it you should look at the carousel not as a parent but as a menu for the door page. You click on the menu item in the carousel and ajax call retrieves the wanted door and colors, colors should be other menu but no need for carousel.

    If you need 3 carousels then make a different calls to carousel script by putting different classes for each carousel - see if this helps. Ajax should call carousel script just for windows and colors not the doors.
     
    Last edited: Apr 24, 2016
    Blizzardofozz, Apr 24, 2016 IP
  8. habotho

    habotho Greenhorn

    Messages:
    9
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    21
    #8
    Well there is gonna be much more color and glass variations than exist by this time. Check out this page http://srv109687.hoster-test.ru/каталог/серия-VG at 640px width screen. As you can see at small screens and gudgets those carousels are mandatory. You are right, all three carousels uses same settings cause all of them are in 'attribute-widgets' div and I apply js like that: $('.attribute-widgets > div > div ').addClass("owl-carousel");

    I just don't know how to apply js for them separately right way. I've tried to apply js this way: $('.form-item-attributes-field-door-category > div').addClass("owl-carousel"); In this case "owl-carousel" class applies to mentioned div and to divs inside "owl-item" divs. Images are not displayed because of wrong css, but anyway if you click on last item carousel switches to default position.

    I just really don't know what to do whith that...
     
    habotho, Apr 25, 2016 IP
  9. Blizzardofozz

    Blizzardofozz Well-Known Member

    Messages:
    132
    Likes Received:
    9
    Best Answers:
    1
    Trophy Points:
    118
    #9
    First - you can add ids to the divs you want to add the class: <div id="doorsCarousel"></div>. This way you may call just: $('#doorsCarousel').addClass("owl-carouselDoors")

    My idea was to have three classes: .addClass("owl-carouselDoors"), .addClass("owl-carouselColors") and .addClass("owl-carouselWindows").

    So:
    var owlDoors = $('.owl-carouselDoors');
    var owlColors = $('.owl-carouselColors');
    var owlWindows = $('.owl-carouselWindows');

    This way may be possible to have like three objects that can be called separately in the Ajax call and to reset only ones you need.

    To summarize: you really have 3 objects - 3 carousels but you call them all in one ajax request. You have to separate them, each carousel is different object.
     
    Blizzardofozz, Apr 25, 2016 IP
  10. Blizzardofozz

    Blizzardofozz Well-Known Member

    Messages:
    132
    Likes Received:
    9
    Best Answers:
    1
    Trophy Points:
    118
    #10
    Hey, did you get the idea? Should I clarify more?

    Also - you don't need to have the carousels in the cart form.

    
    <div id="bigDoorImage"></div>
    <div id="carousels">
        <div id="doorsCarousel"></div>
        <div id="colorCarousel"></div>
        <div id="windowCarousel"></div>
    </div>
    <form id="shoppingCart"></form>
    
    Code (markup):
    <div id="doorsCarousel"></div> item click loads big door image, item info for the cart and carousels only for colors and windows
    <div id="colorCarousel"></div> item click loads only big door image

    doorsCarousel ajax call: when user clicks on a door the script sends a request to the database for the door you need, the colors and windows for this door and also for the price of the door but not the door carousel. Then you get this data and feed it to the carousels, big image div and the cart.

    colorCarousel ajax call: feeds only the big image div.

    To do that you need a way to call each carousel separately. So:

    
    (function($) {
        Drupal.behaviors.myBehavior = {
            attach: function(context) {
                $('#doorsCarousel').addClass("owlCarouselDoors");
                $('#colorsCarousel').addClass("owlCarouselColors");
                $('#windowsCarousel').addClass("owlCarouselWindows");
    
                var owlDoors = $('.owlCarouselDoors'),
                      owlColors = $('.owlCarouselColors'),
                      owlWindows = $('.owlCarouselWindows');
    
                owlDoors.owlCarousel({
                    settings
                });
               owlColors.owlCarousel({
                    settings
               });
               owlWindows.owlCarousel({
                   settings
               });
           }
        };
    })(jQuery);
    
    Code (markup):
    or maybe:

    
    (function($) {
        Drupal.behaviors.myBehavior = {
            attach: function(context) {
                var owlDoors = $('#doorsCarousel'),
                      owlColors = $('#colorsCarousel'),
                      owlWindows = $('#windowsCarousel');
    
                owlDoors.owlCarousel({
                    settings
                });
               owlColors.owlCarousel({
                    settings
               });
               owlWindows.owlCarousel({
                   settings
               });
           }
        };
    })(jQuery);
    
    Code (markup):
     
    Last edited: Apr 25, 2016
    Blizzardofozz, Apr 25, 2016 IP
  11. habotho

    habotho Greenhorn

    Messages:
    9
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    21
    #11
    Hello! Thank you for your attension to my issue.

    I've just tried to apply carousel initialization to particular container with small doors this way:

    $('.form-item-attributes-field-door-category .form-radios').addClass("owl-carousel");
    $('.form-item-attributes-field-door-category .form-radios').addClass("owl-theme");
    var owl = $('.owl-carousel');

    It applied correct and carousel is displaying small doors only but anyway after clicking last small doors carousel switches to default position. Same is happening when you just move to last door and click on color or window attribute.
     
    habotho, Apr 26, 2016 IP
  12. Blizzardofozz

    Blizzardofozz Well-Known Member

    Messages:
    132
    Likes Received:
    9
    Best Answers:
    1
    Trophy Points:
    118
    #12
    OK but somewhere you are calling: form-item-attributes-field-color-category or other way the div with the colors so it can become a carousel. Probably in the ajax call?

    adding .addClass("owl-carousel") to an element turns a div with images into a carousel right? So you have to make the colors a carousel somewhere somehow. Where do you do that?

    See here:
    $('.attribute-widgets > div > div ').addClass("owl-carousel");
    var owl = $('.owl-carousel');

    here the variable owl gets all elements with class "owl-carousel" and you have this class on doors carousel and on colors carousel so the script activates both elements with this class. You need to have both elements with different classes and to have 2 variables so the script will affect them differently. As I showed you above. Class: owl-carousel-doors AND other class: owl-carousel-colors and then to make two variables: var owlDoors = $('.owl-carousel-doors'); AND var owlColors = $('.owl-carousel-colors');

    You are getting all elements with class owl-carousel and you rule them with one variable - owl and wen you change this variable you change all elements in the page that have the class of owl-carousel. So you need to give each html element a different class and different variable.
     
    Last edited: Apr 26, 2016
    Blizzardofozz, Apr 26, 2016 IP
  13. Blizzardofozz

    Blizzardofozz Well-Known Member

    Messages:
    132
    Likes Received:
    9
    Best Answers:
    1
    Trophy Points:
    118
    #13
    I'm not sure how to explain it the best way.

    You have 3 divs that you want to be carousels. You assign them the class owl-carousel. Then all 3 carousels obey the rules for class owl-carousel. One class to rule them all!!! :)) Then when you change the status of one carousel all 3 obey this change and all 3 resets when you want to reset just one like for colors. You want to change the colors carousel but all 3 changes because the all obey class owl-carousel. I guess this is your problem.
     
    Blizzardofozz, Apr 26, 2016 IP
  14. habotho

    habotho Greenhorn

    Messages:
    9
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    21
    #14
    Yeah, I understand that. I just was trying to say that implementing initialization such way as in my above post I've applied a carousel for div with doors only. In that situation I have only one carousel at this page, colors and windows are just divs with divs inside them. So even in that case carousel switches to it default position after clicking last door.

    Probably this function is the reason why this happening? http://www.rit.edu/drupal/api/drupal/sites!all!modules!commerce!modules!cart!commerce_cart.module/function/commerce_cart_add_to_cart_form_attributes_refresh/7.41
     
    habotho, Apr 26, 2016 IP
  15. Blizzardofozz

    Blizzardofozz Well-Known Member

    Messages:
    132
    Likes Received:
    9
    Best Answers:
    1
    Trophy Points:
    118
    #15
    try this and see what happens:

    $(#form-item-attributes-field-door-category').addClass("owl-carousel");
    $('#form-item-attributes-field-door-category').addClass("owl-theme");

    Otherwise you should search in the code if there is somewhere other: .addClass("owl-carousel") or other way of adding owl-carousel class to a element.

    It is possible this function to change classes of elements inside the form. It will be better to move the doors and colors out of the cart form. Cart form should be only for the price and number of items . This way it's a mess.
    Add custom javascript click events when a door is clicked and with it make the ajax call for the colors and windows and price of the current door.

    I see you use hidden inputs to take the ID of each door? but you can do that with data attribute or other ways so no form is needed. Or maybe this plugin allows attributes of a product so you want to use it for the doors functionality.

    This is the way I see it. If you want I'll see how to modify the function but it's not recommended to alter the code of plugins and CMSs.

    But anyway try to give different classes for each carousel and this way maybe this function won't add the same class: owl-carousel.

    All divs under attribute-widgets have form-item form-type-commerce-fancy-attributes form-item-attributes-field-color-category form-type-commerce-fancy-attributes-ajax class so may be the cart plugin affect them all.
     
    Blizzardofozz, Apr 26, 2016 IP
  16. habotho

    habotho Greenhorn

    Messages:
    9
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    21
    #16
    Hello there again! Thank you so much for your attention to my issue. Finally we fix that by adjusting js script. If you are intested to take a look at it you can find it here: http://srv109687.hoster-test.ru/sites/all/themes/Porto/js/owlwrapper.js

    Thanks again, I really appreciate it!
    Ilya
     
    habotho, Apr 26, 2016 IP
  17. Blizzardofozz

    Blizzardofozz Well-Known Member

    Messages:
    132
    Likes Received:
    9
    Best Answers:
    1
    Trophy Points:
    118
    #17
    So looping the owl did the trick right? It's an array of objects (carousels) so now the script treats each object separately.
     
    Blizzardofozz, Apr 26, 2016 IP
  18. habotho

    habotho Greenhorn

    Messages:
    9
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    21
    #18
    Nope, loop is endless cycle, I don't need it :)
     
    habotho, Apr 27, 2016 IP
  19. Blizzardofozz

    Blizzardofozz Well-Known Member

    Messages:
    132
    Likes Received:
    9
    Best Answers:
    1
    Trophy Points:
    118
    #19
    The loop is not endless in most cases :))

    A will loop help you to iterate over elements of array.

    for (start usually from 0; is current element larger number than index of last element of array if it's larger then QUIT THE LOOP; add 1) { do what you want with current element of array }

    owl.each(function (index) { ... does that for owl array.
     
    Blizzardofozz, Apr 27, 2016 IP