0

I am currently attempting to set up a set of chained selects using the Flexbox Jquery plugin (this is not specifically designed for chaining, but can be used for that).

I have the chaining working if I set everything explicitly, but I am trying to dry my code up and make it more understandable. As such, I have come up with the code below.

All boxes currently load initially, and make their queries. The problem I am having is that when I iterate through the menus (as below), I lose the onSelect functionality - it only fires for the last menu I loaded.

My understanding was that since I am using a different JQuery selector each time - $('#' + fbMenu.divId) - it would not matter that I then set the onSelect behavior for another menu, but evidently this is not the case. Am I somehow overwriting the binding each time I am loading a box?

Hopefully I don't have to specify the onSelect functionality for each dropdown, as there could be a large number of them.

Many thanks for any assistance you can provide!

$(document).ready(function() {  

    // Create the variables for data objects  
    var vehicleMakeFb = new Object();
    var vehicleModelFb = new Object();
    var vehicleTrimFb = new Object();

    // Set up each menu with the divId, jsonUrl and the chlid menus that will be updated on select
    vehicleMakeFb.divId = 'vehicle_vehicleMake_input';
    vehicleMakeFb.jsonUrl = '/vehicles/getmakes';
    vehicleMakeFb.children = [vehicleModelFb];

    vehicleModelFb.divId = 'vehicle_vehicleModel_input';
    vehicleModelFb.jsonUrl = '/vehicles/getmodels';
    vehicleModelFb.children = [vehicleTrimFb];

    vehicleTrimFb.divId = 'vehicle_vehicleTrim_input';
    vehicleTrimFb.jsonUrl = '/vehicles/gettrims';
    vehicleTrimFb.children = [];

    // Create an array of all menu objects so that they can be iterated through
    var allMenus = [vehicleMakeFb,vehicleModelFb,vehicleTrimFb];

    // Create the parent menu
    for (var i = 0; i < allMenus.length; i++) {
        var fbMenu = allMenus[i];
        alert(fbMenu.divId);
        $('#' + fbMenu.divId).flexbox(fbMenu.jsonUrl + '.json', {  

            // Update the child menu(s), based on the selection of the first menu
            onSelect: function() {  

                    for (var i = 0; i < fbMenu.children.length; i++) {
                        var fbChild = fbMenu.children[i];
                        var hiddendiv = document.getElementById(fbMenu.divId + '_hidden');
                        var jsonurl1 = fbChild.jsonUrl + '/' + hiddendiv.getAttribute('value') + '.json';
                        alert(jsonurl1);
                        $('#' + fbChild.divId).flexbox(jsonurl1);   
                    }

            }

        });
    }

});
James Khoury
  • 21,330
  • 4
  • 34
  • 65
Harry
  • 4,660
  • 7
  • 37
  • 65

1 Answers1

1

If you put all the information on the elements them selves i think you will have better results. Although I've been known to be wrong, I think the context of the select functions are getting mixed up.

instead of setting up each menu as an object try:

$(document).ready(function() {  

    var setupdiv = (function(divId, jsonUrl, children)
    {
        jQuery('#' + divId)
            .data("jsonurl", jsonUrl)
            .data("children", children.join(",#"));
    
        // Create the parent menu
        jQuery('#' + divId).flexbox(jsonUrl + '.json', 
        {  
            // Update the child menu(s), based on the selection of the first menu
            onSelect: function() 
            {  
                var children = jQuery(this).data("children");
                var jsonUrl = jQuery(this).data("jsonurl");
                if(children)
                 {
                     children = jQuery('#' + children);
                     alert('children was true');
                 }
                 else
                 {
                     children = jQuery();
                     alert('children was false');
                 }
                 var hiddendiv = jQuery('#' + this.id + '_hidden');
                 children.each(function()
                 {
                     var childJsonUrl = jsonUrl + '/' + hiddendiv.val() + '.json';
                     alert(childJsonUrl);
                     $(this).flexbox(childJsonUrl);   
                 });
             }

         });
    });
    setupdiv('vehicle_vehicleMake_input', '/vehicles/getmakes', ['vehicle_vehicleModel_input']);

    setupdiv('vehicle_vehicleModel_input', '/vehicles/getmodels', ['vehicle_vehicleTrim_input']);

    setupdiv('vehicle_vehicleTrim_input', '/vehicles/gettrims', []);
});

DISCLAIMER

I'm known for my spelling mistakes. Please spellcheck before using this code ;)

Update

I've changed the first two lines of code and I've normalized the indenting as there were a mix of tabs and spaces. Should be easier to read now.

James Khoury
  • 21,330
  • 4
  • 34
  • 65
  • Many thanks for your code - i've updated it slightly to add some closing brackets, thus removing the console errors. This is allowing the menus to load initially, but strangely the children .data() object always seems to be false so the `children = jQUery('#' + children);` code is not firing... I'll investigate further. – Harry Jun 24 '11 at 08:33
  • check my update and see if that changes anything. You've put too many brackets and made a mistake there. – James Khoury Jun 24 '11 at 08:53
  • I can't seem to see your edit as yet - could you let me know where you made the change? – Harry Jun 24 '11 at 09:08
  • @HO you were too quick. It seems that the indenting had me a little confused and it took me longer to change it than i thought. – James Khoury Jun 24 '11 at 09:09
  • Many thanks indeed for your help - I have now managed to get this working, though I had to make a few more modifications to the code to ensure that the divs did not get confused (between parent and child), and also to ensure that the jsonUrl got updated for each child menu (you had it outside the loop, so all menus were using the jsonUrl for the first item if there are multiple child menus). – Harry Jun 24 '11 at 11:43
  • @HO if you edit the post and put your changed code in it could help others with similar issues. – James Khoury Jun 26 '11 at 06:48