Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ctrl+Click on link that renders partial view

I got a link that renders partial view using AJAX.

Here is my link code:

<a href="#" onclick="LoadChildCategories(@i.CategoryId,  
    @i.IsTrading.ToString().ToLower())">@i.Name</a>

And here is LoadChildCategories function code:

function LoadChildCategories(id, isTrading) {
    var link;
    if (isTrading === false) {
        link = '@Html.Raw(@Url.Action("NonTradingCategories", "Home",  
                 new {categoryId = -1}))';
    } else {
        link = '@Html.Raw(@Url.Action("ModelList", "Home", new {categoryId = -1}))';
    }
    link = link.replace("-1", id);

    $.ajax({
        url: link,
        method: 'GET',
        success: function(data) {
            $("#viewPartial").html(data);
        }
    });
}

When I click it without CTRL it's ok, partial view renders into my div. But when I click it with CTRL partial view renders into current tab and then another tab opens at Index page.

And when I rightclick on link and select to open it in another tab then nothing happens at current tab and new tab opens at Index page.

So, is there any ways to handle that?

like image 744
Renat Zamaletdinov Avatar asked Mar 26 '26 07:03

Renat Zamaletdinov


1 Answers

I found pretty nice solution, so I modified project according to this solution: Make an MVC Application into a SPA with AJAX and History.js

1) Make controller methods return View, not PartialView and add one line of code than will check is it an AJAX request:

public ViewResult Category(int id)
{
    ViewBag.IsAjaxRequest = Request.IsAjaxRequest();
    var node = CategoriesHandler.Instance.First(x => x.CategoryId == id);
    var childCategories = CategoriesHandler.Instance.Where(x => x.ParentId == node.Id).ToList();
    ViewBag.Message = node.Name;
    return View(childCategories);
}

2) Edit _ViewStart.cshtml like that:

@{
    Layout = ViewContext.ViewBag.IsAjaxRequest == true ? null : "~/Views/Shared/_Layout.cshtml";
}

3) Prepare links to be managed via AJAX:

<a href="@Url.Action("Category", "Intech", new { id = i.CategoryId })" class="ajaxLink" data-href="@Url.Action("Category", "Intech", new { id = i.CategoryId })" data-title="@i.Name">@i.Name</a>

4) Create container for views at _Layout.cshtml

@/*Some layout stuff*/
<div id="bodyContent">
 @RenderBody()
</div>
@/*Other layout stuff*/

5) Prepare helper javascript file like that:

$(function () {

var contentShell = $('#bodyContent');

var History = window.History, State = History.getState();

$(".ajaxLink").on('click', function (e) {
    e.preventDefault();
    var url = $(this).data('href');
    var title = $(this).data('title');
    History.pushState(null, title, url);
});

function navigateToURL(url) {
    $('#bodyContent').html('<div class="loader"> </div>');
    $.ajax({
        type: "GET",
        url: url,
        dataType: "html",
        cache: false,
        success: function (data, status, xhr) {
            $('#bodyContent').hide();
            contentShell.html(data);
            $('#bodyContent').fadeIn(500);
        },
        error: function (xhr, status, error) {
            $('#bodyContent').hide();
            alert("TEST_Error");
        }
    });
}

History.Adapter.bind(window, 'statechange', function () {
    State = History.getState();
    if (State.url === '') {
        return;
    }
    navigateToURL(State.url);
});});

6) Do not forget to include your javascript files into the bundle!

like image 137
Renat Zamaletdinov Avatar answered Mar 28 '26 20:03

Renat Zamaletdinov