This is in ASP.NET Core MVC 2.1.
What I have is a main Index page on witch I load all my partial views.
<button type="button" id="CreateButton" class="btn btn-success" style="margin-top: 20px;">Nova osoba</button>
<button type="button" id="LoadDataButton" class="btn btn-info" style="margin-top: 20px;">Ucitati podatke</button>
<div id="CreateEditView">
</div>
<div id="TablePeopleView">
</div>
The way I load data into "TablePeopleView" is like this.
function AjaxCall(url) {
$("#TablePeople").replaceWith(
$.ajax({
url: url,
method: "POST",
success: function (html) {
$("#TablePeopleView").html(html);
}
}));
}
$(document).ready(function () {
AjaxCall("@Url.Action("IndexAjax")");
});
This calls the IndexAjax method from the controller and creates this partial view inside "TablePeopleView"
@model List<Person>
<table style="margin-top: 20px;" class="table table-condensed" id="TablePeople">
<thead>
<tr>
<th>ID</th>
<th>Ime</th>
<th>Prezime</th>
<th>Grad</th>
<th>Postanski broj</th>
<th>Broj mobitela</th>
<th> </th>
<th> </th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>@item.ID</td>
<td>@item.FirstName</td>
<td>@item.LastName</td>
<td>@item.CityName</td>
<td>@item.PostalCode</td>
<td>@item.MobileNumber</td>
<td>
<button type="button" class="btn btn-toolbar EditButton" data-url="@Url.Action("Edit","Zadatak")/@item.ID">
Uredi osobu
</button>
</td>
<td>
<button type="submit" class="btn btn-danger DeleteButton" data-url="@Url.Action("Delete","Zadatak")/@item.ID">
Obriši osobu
</button>
</td>
</tr>
}
</tbody>
</table>
And it works fine, gets the data and shows it on table.
When I want to create a new person I click on the "CreateButton" and get a new partial view inside "CreateEditView". The partial view looks like this.
@model Person
<div class="modal fade" id="CreateOrEditModal" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
@if (Model == null)
{
<h4 class="modal-title">Nova osoba</h4>
}
else
{
<h4 class="modal-title">Uredi osobu</h4>
}
</div>
<div class="modal-body">
<form asp-controller="Zadatak" id="CreateOrEditModalForm">
<div class="form-group">
<label class="control-label">Ime osobe</label>
<input asp-for="FirstName" class="form-control" id="FirstName" />
<span asp-validation-for="FirstName" class="text-danger"></span>
</div>
<div class="form-group">
<label class="control-label">Prezime osobe</label>
<input asp-for="LastName" class="form-control" id="LastName" />
<span asp-validation-for="LastName" class="text-danger"></span>
</div>
<div class="form-group">
<label class="control-label">Naziv grada</label>
<input asp-for="CityName" class="form-control" id="CityName" />
<span asp-validation-for="CityName" class="text-danger"></span>
</div>
<div class="form-group">
<label class="control-label">Poštanski broj</label>
<input asp-for="PostalCode" class="form-control" id="PostalCode" onkeypress="return isNumberKey(event)" />
<span asp-validation-for="PostalCode" class="text-danger"></span>
</div>
<div class="form-group">
<label class="control-label">Mobilni broj</label>
<input asp-for="MobileNumber" class="form-control" id="MobileNumber" onkeypress="return isNumberKey(event)" />
<span asp-validation-for="MobileNumber" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Pospremi osobu" class="btn btn-default" id="SavePerson" />
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" id="ClosePerson" class="btn btn-default" data-dismiss="modal">Zatvori</button>
</div>
</div>
</div>
</div>
The way I get the partial view to show up in "CreateEditView" is like this.
$('#CreateButton').click(function () {
var url = "@Url.Action("Create","Zadatak")";
$("#CreateEditView").load(url, function () {
$("#CreateOrEditModal").modal("show");
});
});
The way I save date from the form "CreateOrEditModalForm" is with this.
$("#CreateEditView").on("click", "#SavePerson", function (event) {
$("#CreateOrEditModalForm").removeData('validator');
$("#CreateOrEditModalForm").removeData('unobtrusiveValidation');
$.validator.unobtrusive.parse("#CreateOrEditModalForm");
$("#CreateOrEditModalForm").validate();
if ($("#CreateOrEditModalForm").valid()) {
$("#CreateOrEditModal").modal("hide");
}
});
I had to do it like this because it is loaded through a partial view witch is not loaded on page load.
After the form is validated it calls the "Create" method from the controller witch looks like this.
[HttpPost]
public IActionResult Create(Person model)
{
if (ModelState.IsValid)
{
this._dbContext.People.Add(model);
this._dbContext.SaveChanges();
return NoContent();
}
return NoContent();
}
Now this is where my problem comes I think. If the "ModelState.IsValid" is valid the new person will be saved to the DB and it will return NoContent. I put no content so the page does not refresh but if I put return RedirectToAction(nameof(IndexAjax));
like I did in the begginig it just loads the partila view in a new page like this.
I do not want that to happen, I just want the table to be refreshed with the new person while staying on the page.
Ajax allows websites to load content onto the screen without refreshing the page.
Here is a working demo you could check:
Model:
public class Person
{
public int ID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string CityName { get; set; }
public string PostalCode { get; set; }
public string MobileNumber { get; set; }
}
View(Views/Zadatak/Index.cshtml
):
<button type="button" id="CreateButton" class="btn btn-success" style="margin-top: 20px;">Nova osoba</button>
<button type="button" id="LoadDataButton" class="btn btn-info" style="margin-top: 20px;">Ucitati podatke</button>
<div id="CreateEditView">
</div>
<div id="TablePeopleView">
</div>
@section Scripts
{ //be sure add _ValidationScriptsPartial....
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
<script>
function AjaxCall(url) {
//the same as yours..
}
$(document).ready(function () {
AjaxCall("@Url.Action("IndexAjax")");
});
$('#CreateButton').click(function () {
//the same as yours..
});
$("#CreateEditView").on("click", "#SavePerson", function (event) {
$("#CreateOrEditModalForm").removeData('validator');
$("#CreateOrEditModalForm").removeData('unobtrusiveValidation');
$.validator.unobtrusive.parse("#CreateOrEditModalForm");
$("#CreateOrEditModalForm").validate();
if ($("#CreateOrEditModalForm").valid()) {
$("#CreateOrEditModal").modal("hide");
//add the following code....
$("#TablePeople").replaceWith(
$.ajax({
url:"@Url.Action("Create", "Zadatak")",
method: "POST",
data: $("#CreateOrEditModalForm").serialize(),
success: function (html) {
$("#TablePeopleView").html(html);
}
}));
}
});
</script>
}
Be sure modify your CreateEditView.cshtml
:
@model Person
<div class="modal fade" id="CreateOrEditModal" role="dialog">
//...
<div class="form-group">
@*change type="submit" to type="button"*@
<input type="button" value="Pospremi osobu" class="btn btn-default" id="SavePerson" />
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" id="ClosePerson" class="btn btn-default" data-dismiss="modal">Zatvori</button>
</div>
</div>
</div>
</div>
Controller:
public class ZadatakController : Controller
{
private readonly YourContext _context;
public ZadatakController(YourContext context)
{
_context = context;
}
[HttpGet]
public async Task<IActionResult> Index()
{
return View();
}
[HttpPost]
public async Task<IActionResult> IndexAjax()
{
//change here....
return PartialView("_IndexTable", await _context.Person.ToListAsync());
}
public IActionResult Create()
{
return PartialView("CreateEditView");
}
[HttpPost]
public async Task<IActionResult> Create(Person person)
{
if (ModelState.IsValid)
{
_context.Add(person);
await _context.SaveChangesAsync();
//change here....
return PartialView("_IndexTable", await _context.Person.ToListAsync());
}
return View(person);
}
}
Result: