Request ajax

4

I'm loading the menu, of the system I'm developing, through a request via ajax using jQuery, however the menu formatting is not getting as expected.

My request via jQuery

<script type="text/javascript">
    $(document).ready(function () {
        $.ajax({
            url: '/Menu/Index',
            contentType: 'application/html; charset=utf-8',
            type: 'GET',
            dataType: 'html'
        })
            .success(function (result) {
                $('#menuNavigation').html(result);
            });
    });
</script>

My controller

public class MenuController : Controller
{
    public ActionResult Index()
    {
        using (DevcompyContext context = new DevcompyContext())
        {
            var menus = context.Menu.ToList();

            return PartialView(menus);
        }
    }          
}

Expected result

Resultobtained.

In short, my problem would be that when I load my menu using jQuery, formatting it is lost, when I leave static the formatting is correct.

I believe that those who do the service close the menu are via the following javascripts

/*
 * metismenu - v1.0.3
 * Easy menu jQuery plugin for Twitter Bootstrap 3
 * https://github.com/onokumus/metisMenu
 *
 * Made by Osman Nuri Okumuş
 * Under MIT License
 */
;(function ($, window, document, undefined) {

var pluginName = "metisMenu",
    defaults = {
        toggle: true
    };

function Plugin(element, options) {
    this.element = element;
    this.settings = $.extend({}, defaults, options);
    this._defaults = defaults;
    this._name = pluginName;
    this.init();
}

Plugin.prototype = {
    init: function () {

        var $this = $(this.element),
            $toggle = this.settings.toggle;

        if (this.isIE() <= 9) {
            $this.find("li.active").has("ul").children("ul").collapse("show");
            $this.find("li").not(".active").has("ul").children("ul").collapse("hide");
        } else {
            $this.find("li.active").has("ul").children("ul").addClass("collapse in");
            $this.find("li").not(".active").has("ul").children("ul").addClass("collapse");
        }

        $this.find("li").has("ul").children("a").on("click", function (e) {
            e.preventDefault();

            $(this).parent("li").toggleClass("active").children("ul").collapse("toggle");

            if ($toggle) {
                $(this).parent("li").siblings().removeClass("active").children("ul.in").collapse("hide");
            }
        });
    },

    isIE: function() {//https://gist.github.com/padolsey/527683
        var undef,
            v = 3,
            div = document.createElement("div"),
            all = div.getElementsByTagName("i");

        while (
            div.innerHTML = "<!--[if gt IE " + (++v) + "]><i></i><![endif]-->",
            all[0]
        ) {
            return v > 4 ? v : undef;
        }
    }
};

$.fn[ pluginName ] = function (options) {
    return this.each(function () {
        if (!$.data(this, "plugin_" + pluginName)) {
            $.data(this, "plugin_" + pluginName, new Plugin(this, options));
        }
    });
};
})(jQuery, window, document);

and

$(function() {

$('#side-menu').metisMenu();
});
//Loads the correct sidebar on window load,
//collapses the sidebar on window resize.
// Sets the min-height of #page-wrapper to window size
$(function() {    
$(window).bind("load resize", function() {        
topOffset = 50;
    width = (this.window.innerWidth > 0) ? this.window.innerWidth : this.screen.width;
    if (width < 768) {
        $('div.navbar-collapse').addClass('collapse')
        topOffset = 100; // 2-row-menu
    } else {
        $('div.navbar-collapse').removeClass('collapse')
    }

    height = (this.window.innerHeight > 0) ? this.window.innerHeight : this.screen.height;
    height = height - topOffset;
    if (height < 1) height = 1;
    if (height > topOffset) {
        $("#page-wrapper").css("min-height", (height) + "px");
    }
})
});

My view _Layout

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="">
<title>SB Admin 2 - Bootstrap Admin Theme</title>
@Styles.Render("~/Content/css")
@Scripts.Render("~/bundles/modernizr")
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
    <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script><scriptsrc="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
@RenderSection("styles", required: false)
</head>
<body>    
<div id="wrapper">
@if (Request.IsAuthenticated)
{
    <div id="menuNavigation"></div>            
    <div id="page-wrapper">
        <div class="row">
            <div class="col-lg-12">
                <h1 class="page-header">@ViewBag.Title</h1>
            </div>
                <!-- /.col-lg-12 -->
            </div>
            <!-- /.row -->
            <div class="row">
                <div class="col-lg-12">
                    @RenderBody()
                    <!-- /.panel -->
                </div>
                <!-- /.col-lg-12 -->
            </div>
            <!-- /.row -->
        </div>
    }
    else
    {
        @RenderBody()
    }
</div>

@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/bootstrap")
@Scripts.Render("~/bundles/plugins")

@RenderSection("scripts", required: false)

<script type="text/javascript">
    $(document).ready(function () {
        $.ajax({
            url: '/Menu/Index',
            contentType: 'application/html; charset=utf-8',
            type: 'GET',
            dataType: 'html'
        })
            .success(function (result) {
                $('#menuNavigation').html(result);
            });
    });
</script>

    
asked by anonymous 19.12.2014 / 13:18

1 answer

2

The problem is that this menu is closed via JavaScript and the code that does this is being run before AJAX, so before HTML is present on the page.

One solution is to put $('#side-menu').metisMenu(); as the last line of the .success(function (result) { function. That way you call the plugin that closes the menu when HTML is already on the page.

Another ideal solution is to do this with CSS. In that case the part of the expanded menus would be controlled by CSS and only open / close by JavaScript as the plugin has. This involves changing some HTML and using classes to identify ul with submenus.

CSS suggestion:

#menuNavigation ul.submenu li { display: none; }
#menuNavigation ul.submenu.active li { display: block !important; }

jQuery:

$('#menuNavigation').on("click", "li ul a", function (e) {
    e.preventDefault();
    $(this).parent("li").toggleClass("active");
    $(this).parent("li").siblings().removeClass("active");
});
    
19.12.2014 / 14:28