Menu navigation technique in SPA

Untitled-1

Navigation/Menu demands some extra atttention in a single page application. Since, master/shell page does not refresh, so it requires to mark an menu item active and other inactive (i.e. add/remove styles).

And, finally laod the partial content.

/*CSS to spin the preloader image*/
.imagee {
    overflow: hidden;
    transition-duration: 0.8s;
    transition-property: transform;
}

.imagee:hover {
    transform: rotate(360deg);
}

.imageee {  
     margin: -60px 0 0 -60px;
    -webkit-animation: spin 2s linear infinite;
    -moz-animation: spin 2s linear infinite;
    animation: spin 2s linear infinite;
}

@-moz-keyframes spin {
    100% {
        -moz-transform: rotate(360deg);
    }
}

@@-webkit-keyframes spin {
    100% {
        -webkit-transform: rotate(360deg);
    }
}

@@keyframes spin {
    100% {
        -webkit-transform: rotate(360deg);
        transform: rotate(360deg);
    }
}
<ul class="navigation">
    <li class="active">
        <a class="handle-link" href="index.html" title=""><img src="dashboard.png" />Dashboard</a>
    </li>

    <li class="has-sub-menu">
        <a href="#" title=""><img src="form-elements.png" />Multiple<strong>3</strong></a>
        <ul>
            <li>
                <a class="handle-link sub-menu" href="forms.html" >One</a>
            </li>
            <li>
                <a class="handle-link sub-menu" href="two.html">Two</a>
            </li>
            <li><a class="handle-link sub-menu" href="three.html" >Three</a></li>
        </ul>
    </li>
    <li >
        <a class="handle-link" href="index.html"><img src="dashboard.png" />Single
        </a> 
    </li>

    <li class="has-sub-menu">
        <a href="#"><img src="elements.png"/>This is Multiple also<strong>2</strong></a>
        <ul>
            <li>
                <a class="handle-link sub-menu" href="forms.html" >One</a>
            </li>
            <li>
                <a class="handle-link sub-menu" href="form_wizards.html" title="">Two</a>
            </li>
        </ul>
    </li>
</ul>
$('a.handle-link').click(function (e) {
    e.preventDefault();
    var currentMenuItem = $(this);
    var currentLinkAddress = $(currentMenuItem).attr('href');
    var currentLI = currentMenuItem.closest('li');

    var img; //variable to hold currently displaying preloader.

    //Check this is sub-menu --->
    if (currentMenuItem.hasClass('sub-menu'))
    {  //If this is a sub-menu item ---->

        var currentUL = currentLI.closest('ul');
        var parentLI = currentUL.closest('li');

        //Checking whether it has 'current' class ---->
        if (currentLI.hasClass('current')) 
        { //if it has 'current' class -->
            //This is current and its top li is also active. So no need to do any class removing code.
            //But user may want to reload this page. So, show the preloader
            //Showing preloader--->
            var firstAnchor = parentLI.find('a:first');
            img = firstAnchor.find('img');
            img.addClass('imageee');
            //Showing preloader---<
        } //if it has 'current' class ---<
        else 
        { //if it does not have 'current' class --->

            //But it might be the sub-menu under the same menu. So check it now.
            if (parentLI.hasClass('active'))
            { //If it's under same parent menu--->
                //No need to check whether another element has 'imageee' class
                //Just show the preloader
                var firstAnchor = parentLI.find('a:first');
                img = firstAnchor.find('img');
                img.addClass('imageee');

                // So, no need to change active. But change only 'current' class
                currentUL.find('li').each(function (i) {
                    if ($(this).hasClass('current')) {
                        $(this).removeClass('current');
                    }
                });
                currentLI.addClass('current');
            } //If it's under same parent menu ---<
            else
            { //If parent li does not have 'active' class --->
                //But other menu/sub-menu may have 'active' class or display preloader. So check it.
                var baseUl = parentLI.closest('ul');
                baseUl.find('li').each(function (i) {
                    if ($(this).hasClass('active')) {
                        $(this).removeClass('active');

                        //Hide all other (if any) preloader--->
                        var otherAnimatingImage = $(this).find('img');
                        if (otherAnimatingImage.hasClass('imageee')) {
                            otherAnimatingImage.removeClass('imageee')
                        }
                        //Hide all other (if any) preloader---<

                        if ($(this).hasClass('has-sub-menu')) {
                            $(this).find('li').each(function (i) {
                                if ($(this).hasClass('current')) {
                                    $(this).removeClass('current');
                                }
                            });
                        }
                    }
                });

                parentLI.addClass('active');
                currentLI.addClass('current');
                //Show preloader--->
                var firstAnchor = parentLI.find('a:first');
                img = firstAnchor.find('img');
                img.addClass('imageee');
                //Show preloader ----<
            } //If parent li does not have 'active' class ---<
        } //If it does not have 'current' class ---<
        //Checking whether it has 'current' class ----<
    } //If this is a sub-menu item ----<
    else
    { //If this is not sub-menu ---->
        var baseUl = currentLI.closest('ul');
        baseUl.find('li').each(function (i) {
            if ($(this).hasClass('active')) {

                //Hide all other (if any) preloader--->
                var otherAnimatingImage = $(this).find('img');
                if (otherAnimatingImage.hasClass('imageee')) {
                    otherAnimatingImage.removeClass('imageee')
                }
                //Hide all other (if any) preloader--->

                $(this).removeClass('active');
                if ($(this).hasClass('has-sub-menu')) {
                    $(this).find('li').each(function (i) {
                        if ($(this).hasClass('current')) {
                            $(this).removeClass('current');
                        }
                    });
                }
            }
        });

        currentLI.addClass('active');

        img = currentMenuItem.find("img");
        img.addClass('imageee');
    } //If this is not sub-menu ---->
    //Check this is sub-menu --->

    //Finally, ajax call to load partial ---->
    $.ajax({
        url: currentLinkAddress,
        async: true,
        beforeSend: function () {
            // $("#PartialContent").fadeOut("slow").empty();
            //$('#PartialContent').fadeTo('slow', 0);
        },
        success: function (data) {
            //  $('#PartialContent').fadeTo('slow', 0).slideUp()
            $('#PartialContent').html(data).fadeIn("slow");
        },
        error: function (request, status, error) {
            //  alert("Error-  Request: " + request + ", Status: " + status + ", Error: " + error);
            var msg = '<div class="notice outer"> \
                            <div class="note note-danger">  \
                            <button type="button" class="close">×</button>   \
                                <strong>Notice!</strong> Something is wrong. Please reload the page.  \
                            </div>  \
                        </div>';
            $('#PartialContent').html(msg).fadeIn("slow");

        },
        complete: function () {
            img.removeClass('imageee');
        }
    });
    //Finally, ajax call to load partial ----<
});


Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s