aik
aik

Reputation: 97

MVC Core ajax and return result is a view

MVC Core, NET 5, not razor pages.

On a view I have three select components (bootstrap-select). I populate them via ViewModel.

"Get request -> Controller -> return View(viewModel);"

What I want... When I changed value in any select component I do a post request (ajax) to the same controller (other method) and return view with repopulated data.

"'Post request -> Controller -> return View(changedModel);"

As I understood when I did ajax request I should handle it result in success and other cases.

What I should to do to reload page with new data?

Is it possible to achive this with this approach?

Upvotes: 0

Views: 829

Answers (3)

aik
aik

Reputation: 97

Based on advices of cwalvoort and mj1313

I did:

  • Render main page with partials. ViewModel transfered to a partial as a parameter
  • On main page I added eventListners to controls with JS.
  • When control changes - ajax request to backend happens Controller/GetPartialView
  • Result from ajax replace html in partial section
  • Programmatically show needed components, re-add eventListners

PS Really need to learn Blazor or UI Framework :)

Code samples:

// JS
document.addEventListener("DOMContentLoaded", function (event) {

BindSelectActions();
});

function BindSelectActions() {

$('#selectGroups').on('hidden.bs.select', DoPartialUpdate);
$('#selectCompanies').on('hidden.bs.select', DoPartialUpdate);
$('#selectPeriods').on('hidden.bs.select', DoPartialUpdate);
}

function DoPartialUpdate(e, clickedIndex, isSelected, previousValue) {

// ToDo: Implement common script with "CallBackend" function

$.ajax({
    type: "POST",
    url: 'https://localhost:44352/TestController/TestGetPartial',
    // no data its a stub at the moment
    // data: $('#form').serialize(),
    success: function (data, textStatus) {

        $("#testControls").html(data);
        $('#selectGroups').selectpicker('show');
        $('#selectCompanies').selectpicker('show');
        $('#selectPeriods').selectpicker('show');

        BindSelectActions();
    }
});
}


// Controllers
[HttpGet]
[ResponseCache(NoStore = true, Location = ResponseCacheLocation.None)]
public async Task<IActionResult> Main()
{
    // ViewModel = _helper -> _mediator -> query -> context
    return await Task.Run(() => View(new TestViewModel()));
}

[HttpPost]
[ResponseCache(NoStore = true, Location = ResponseCacheLocation.None)]
public IActionResult TestGetPartial(TestViewModel model)
{
    // ViewModel = _helper -> _mediator -> query -> context
    var result = new TestViewModel();
    result.IsPageReload = "yes";
    result.TestCollection = new string[] { "A", "B", "C" };
    result.Companies = new List<SelectListItem> { new SelectListItem { Value = "999", 
Text = "Test" } };

// ModelState.Clear();
return PartialView("_TestPartial", result);
}

// Main and partial views
@model TestViewModel

@{
    ViewData["Title"] = "Test";
}

<div id="testControls">

    @await Html.PartialAsync("_TestPartial", Model)

</div>

@section Scripts {

    <script type="text/javascript" src="~/js/test.js" asp-append-version="true"> 
</script>
}

@model TestViewModel

<form>
<div class="d-flex flex-row justify-content-between mt-4">

    <div><select id="selectGroups" asp-for="Groups" asp-items="Model.Groups" 
class="selectpicker" data-live-search="true" data-style="btn-outline-dark" 
title="Group"></select></div>
    <div><select id="selectCompanies" asp-for="Companies" asp-items="Model.Companies" 
class="selectpicker" data-live-search="true" data-style="btn-outline-dark" 
title="Company"></select></div>
    <div><select id="selectPeriods" asp-for="Periods" asp-items="Model.Periods" 
class="selectpicker" data-live-search="true" data-style="btn-outline-dark" 
title="Period"></select></div>

    <div><button type="button" class="btn btn-outline-dark">Import</button></div>
</div>
</form>

<div>
@{
    if (null != Model.TestCollection)
    {
        foreach (var item in Model.TestCollection)
        {
            <p>@item</p>
            <br>
        }
    }
}
</div>

Upvotes: 1

mj1313
mj1313

Reputation: 8459

What I should to do to reload page with new data?

If the post action return the same view as the get action and you want to reload the whole page, I think there is no need to use ajax. You can just redirect to post action with a form submission. If the view returned by the post action is a partialview you want render to the current view, you can use it like that in @cwalvoort answer.

Upvotes: 1

cwalvoort
cwalvoort

Reputation: 1967

Yes, this is possible and you do not need to reload the page, just append the returned html to wherever you want it.

$.ajax({
    type: "POST",
    url: {your_url},
    dataType: "html",
    success: function (html) {
        $("#someDiv").html(html);
    }
});

Upvotes: 1

Related Questions