0

My menu is constructed by consuming web-service returned javascript which looks like below:

strGlobalNav='<ul><li><a href="//testonline/" alt="test Online Main Page">testOnline</a></li><li><a href="//testonline/ec/" alt="Employee Center Site">Employee Center</a><ul><li><a href="//testonline/ec" alt="Employee Center Site">Employee Center</a></li><li><a href="//testonline/ec/awards" alt="Awards &amp; Recognition Site">Awards &amp; Recognition</a></li><li><a href="//testonline/hr/benefits" alt="Benefits Site">Benefits</a></li><li><a href="//testonline/hr/EERelations/Pages/Default.aspx" alt="Employee Relations">Employee Relations</a></li><li><a href="//testonline/hr/Employment/Pages/Default.aspx" alt="Employment">Employment</a></li><li><a href="//testonline/ec/training" alt="test University Site">test University</a></li><li><a href="//testonline/ec/healthandsafety" alt="Health &amp; Safety Site">Health &amp; Safety</a></li><li><a href="//testonline/sites/offices" alt="Office Locations Site">Office Locations</a></li><li><a href="//testonline/ec/travel" alt="Travel Site">Travel</a></li><li><a href="//testonline/ec/tso" alt="Total Service Organization">TSO</a></li><li><a href="//testonline/ec/vidconf" alt="Video Conferencing Services">Video Conferencing</a></li></ul></li></ul>'; document.getElementById('test-nav-wrapper').innerHTML = strGlobalNav;

I need to add class to submenu items for the parent list item that has an <ul><li> inside of it.

Here is my navigation.

<div class="globalNav">
  <div id="test-nav-wrapper"></div>
</div>

Here is the actual fiddle: http://jsbin.com/urIlAlO/1/edit

Why is my script not able to add the class to the menu items. I am trying to convert the dropdown menu to two columned mega menu style stuff.

Please help me understand why the adding class to the dynamic content doesnt work however, if i add html directly it works? Example here: http://jsbin.com/iHaqihI/1/edit

Athapali
  • 1,091
  • 4
  • 25
  • 48
  • 1
    That is a lot of code to sift through. I have found it very helpful to slowly delete elements that are not part of the problem to help me focus on the actual error. Doing this helps you see what is going on as well as helping those who want to help you see the actual goal and its problem. I often do this sorting just by taking a jsfiddle like you have created and slowly deleting elements that are not key to the problem. A suggestion. – Thomas Oct 11 '13 at 16:35

2 Answers2

1

In your original code you missed "{" tag in jQuery(document).ready(function() this is why it's not working there!

       jQuery(document).ready(function()   
       {
        //clean up the row of the mega menu. add css class to each element on bottom row.
        //only if more than 7 elements. if more than 16, mm-3
        jQuery('#test-nav-wrapper ul li ul').each(function(ulindex, ulele){
            $total = jQuery(this).children('li').size();
            if ($total <= 7) {
                jQuery(this).addClass('mm-1');
            }
            else {
                $cols = Math.floor(($total) / 8) + 1;
                $remainder = $total % $cols;
                $rows = Math.ceil($total / $cols);
                jQuery(this).addClass('mm-' + $cols + ' total-' + $total + ' rem-'+$remainder );

                jQuery(this).children().each(function(liindex, liele){
                 //alert("total: "+$total+", remainder: "+ $mod+", ulindex: "+ulindex+", liindex: "+liindex);

                    jQuery(this).addClass('col-' + Math.floor((liindex / $total * $cols)+1) );
                    if( (liindex+1) % $rows == 0) {
                        jQuery(this).addClass('last');
                    }
                });

                for (var colcount = 1; colcount<= $cols; colcount++){
                    jQuery(this).children('.col-'+colcount).wrapAll('<div class="col" />');
                }
            }
        });          

});

Fiddle

Alex Art.
  • 8,711
  • 3
  • 29
  • 47
  • That's very weird because if I load the same javascript from a URL, it doesn't work. Here is the url: http://yourjavascript.com/501211013113/test.js – Athapali Oct 11 '13 at 16:52
  • That is not weird at all because you probably trying to manipulate the elements before they get to DOM. If you loading your JavaScript with Ajax you should do all manipulations in ajaxComplete handler – Alex Art. Oct 11 '13 at 16:56
1

It's just a loading sequence issue. You jQuery fires when the DOM is ready, but probably before that nav is added since it's being added by javascript. If you moved that addition to the document ready function before you add the class, it should work. See this updated fiddle.

http://jsbin.com/urIlAlO/8/

I also moved all the logic from the head section to the body so it's non-blocking. Essentially, what I did was change your document ready function to below:

 $(function() {  
           var strGlobalNav='<ul><li><a href="//testonline/" alt="test Online Main Page">testOnline</a></li><li><a href="//testonline/ec/" alt="Employee Center Site">Employee Center</a><ul><li><a href="//testonline/ec" alt="Employee Center Site">Employee Center</a></li><li><a href="//testonline/ec/awards" alt="Awards &amp; Recognition Site">Awards &amp; Recognition</a></li><li><a href="//testonline/hr/benefits" alt="Benefits Site">Benefits</a></li><li><a href="//testonline/hr/EERelations/Pages/Default.aspx" alt="Employee Relations">Employee Relations</a></li><li><a href="//testonline/hr/Employment/Pages/Default.aspx" alt="Employment">Employment</a></li><li><a href="//testonline/ec/training" alt="test University Site">test University</a></li><li><a href="//testonline/ec/healthandsafety" alt="Health &amp; Safety Site">Health &amp; Safety</a></li><li><a href="//testonline/sites/offices" alt="Office Locations Site">Office Locations</a></li><li><a href="//testonline/ec/travel" alt="Travel Site">Travel</a></li><li><a href="//testonline/ec/tso" alt="Total Service Organization">TSO</a></li><li><a href="//testonline/ec/vidconf" alt="Video Conferencing Services">Video Conferencing</a></li></ul></li></ul>';
             $('#test-nav-wrapper').html(strGlobalNav);
            //clean up the row of the mega menu. add css class to each element on bottom row.
            //only if more than 7 elements. if more than 16, mm-3
            jQuery('#test-nav-wrapper ul li ul').each(function(ulindex, ulele){
                $total = jQuery(this).children('li').size();
                if ($total <= 7) {
                    jQuery(this).addClass('mm-1');
                }
                else {
                    $cols = Math.floor(($total) / 8) + 1;
                    $remainder = $total % $cols;
                    $rows = Math.ceil($total / $cols);
                    jQuery(this).addClass('mm-' + $cols + ' total-' + $total + ' rem-'+$remainder );

                    jQuery(this).children().each(function(liindex, liele){
                     //alert("total: "+$total+", remainder: "+ $mod+", ulindex: "+ulindex+", liindex: "+liindex);

                        jQuery(this).addClass('col-' + Math.floor((liindex / $total * $cols)+1) );
                        if( (liindex+1) % $rows == 0) {
                            jQuery(this).addClass('last');
                        }
                    });

                    for (var colcount = 1; colcount<= $cols; colcount++){
                        jQuery(this).children('.col-'+colcount).wrapAll('<div class="col" />');
                    }
                }
            });          


});

UPDATE: Just reread your question and noticed 'My menu is constructed by consuming web-service returned javascrip'.

Do your jquery stuff in the body afeer the JS generated by your web service. start your on ready function by adding the menu to the nav as below, before doing your check and adding the classes.

$(function() {
  $('#test-nav-wrapper').html(strGlobalNav);
  //clas checking stuff here
})

That should work just fine for you. It would also be nice to know how you're getting the menu from a web service. If it's a service on the same domain, consider using $.ajax() and then doing your check and adding the class in your success function. See http://api.jquery.com/jQuery.ajax/

Jazzuzz
  • 490
  • 6
  • 12
  • The problem isn't there he just simply missed opening "{" in ready handler – Alex Art. Oct 11 '13 at 16:47
  • 1
    His question indicates he has the issue when using the menu generated from a web service. His example I think shows what he said works. – Jazzuzz Oct 11 '13 at 16:52
  • yea that was a part of it, but the major problem is if i load the same javascript string from a url, it doesn't work. Here is the URL. http://yourjavascript.com/501211013113/test.js – Athapali Oct 11 '13 at 16:53
  • Consider using jquery.ajax() or jquery.getScript() and do your check on the success callback function. – Jazzuzz Oct 11 '13 at 16:55