My model contains two lists of the Order
entity type, but differentiating only by the value of the Status
property. When Orders
are created, the Status
property is automatically set to In Progress
and in the AdminOrders view
, placed in the Orders In Progress table
. The AdminOrders view
has two tables: Orders In Progress table
and Orders Dispatched table
which will be filled by the Model
's lists respectively.
When the Status
value of new orders
is changed from the drop down list to dispatched
, and when the update
button in the view is clicked, the Ajax post request
should be triggered by the JavaScript click event - passing the list of all updated orders
in the view to the Ajax post method. However, nothing seems to be happening when I run the application.
At each time, multiple Order objects
can have their Status'
changed which is why I thought a simple Ajax update post request
would be suitable.
Here's the Model class:
public class AdminOrdersViewModel
{
public List<Order> OrdersInProgress { get; set; }
public List<Order> OrdersDespatched { get; set; }
public List<Status> OrderStatuses { get; set; }
}
This is the controller GET action for the AdminOrders view:
[HttpGet]
[Authorize(Roles = "Admin")]
public ActionResult AdminOrders()
{
var inProgressOrders = db.Orders.Where(o => o.Status == "In Progress").ToList();
var despatchedOrders = db.Orders.Where(o => o.Status == "Despatched").ToList();
var statuses = new List<Status> {
new Status { StatusName = "In Progress" },
new Status {StatusName = "Despatched" }
};
return View(new AdminOrdersViewModel { OrdersInProgress = inProgressOrders, OrdersDespatched = despatchedOrders, OrderStatuses = statuses });
}
My post ajax method is here:
[HttpPost]
public ActionResult UpdateOrders(List<UpdatedOrder> UpdatedOrdersList)
{
foreach (var item in UpdatedOrdersList)
{
db.Entry(item).State = EntityState.Modified;
db.SaveChangesAsync();
}
return View("AdminOrders");
}
It should update every order that has had it's Status
property changed and then update the view page.
This is the class for UpdatedOrder:
public class UpdatedOrder
{
public int id { get; set; }
public string newstatus { get; set; }
}
As you can see, there is a list which is being passed. This list is collected from the JavaScript method in the view:
<script type="text/javascript">
$(document).ready(function () {
$("#Order-Update-Button").click(function () {
var ListOfUpdatedOrders = []
@{
foreach (var item in Model.OrdersInProgress)
{
@:ListOfUpdatedOrders.push({ id: "@item.OrderId", newStatus: document.getElementById("@item.OrderId") });
}
}
var dataJson = JSON.stringify({
"UpdatedOrdersList": ListOfUpdatedOrders
});
alert("running");
// Perform the ajax post
$.ajax({
contentType: "application/json; charset=utf-8",
type: "POST",
url: "@Url.Action("UpdateOrders", "Manage")",
data: dataJson,
dataType: "json",
success: function (data) {
alert(data);
},
error: function () {
alert("an error has occured!!!");
}
});
});
});
</script>
The ListOfUpdatedOrders
list will put together objects consisting of Order Id
and Status
attributes. The new Status is being extracted through getElementById
and the id is set to the OrderId
of each order object displayed in the view.
The full view page code is the following:
@model ValueVille.Models.AdminOrdersViewModel
@{
ViewBag.Title = "Orders";
}
<script src="/Scripts/jquery-3.1.1.min.js"
type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () {
$("#Order-Update-Button").click(function () {
var ListOfUpdatedOrders = []
@{
foreach (var item in Model.OrdersInProgress)
{
@:ListOfUpdatedOrders.push({ id: "@item.OrderId", newStatus: document.getElementById("@item.OrderId") });
}
}
var dataJson = JSON.stringify({
"UpdatedOrdersList": ListOfUpdatedOrders
});
alert("running");
// Perform the ajax post
$.ajax({
contentType: "application/json; charset=utf-8",
type: "POST",
url: "@Url.Action("UpdateOrders", "Manage")",
data: dataJson,
dataType: "json",
success: function (data) {
alert(data);
},
error: function () {
alert("an error has occured!!!");
}
});
});
});
</script>
<div class="main-content-container">
<h1>New Orders In Progress<span id="update-order-test"></span></h1>
@Html.AntiForgeryToken()
<table class="panel panel-default table cart-table">
<tr>
<th>
Order ID
</th>
<th>
Total
</th>
<th>
Date
</th>
<th>
Status
</th>
</tr>
@foreach (var item in Model.OrdersInProgress)
{
<tr>
<td>
<a href="@Url.Action("OrderDetails", "Home", new { id = item.OrderId })">
@item.OrderId
@Html.HiddenFor(x => item.OrderId)
</a>
</td>
<td>
£@item.Total
@Html.HiddenFor(x => item.Total)
</td>
<td>
@item.OrderDate
@Html.HiddenFor(x => item.OrderDate)
</td>
<td>
@Html.DropDownListFor(m => item.Status, new SelectList(Model.OrderStatuses, "StatusId", "StatusName"), new { @id=item.OrderId })
</td>
</tr>
}
</table>
<h1>Orders Despatched</h1>
<table class="panel panel-default table cart-table">
<tr>
<th>
Order ID
</th>
<th>
Total
</th>
<th>
Date
</th>
<th>
Status
</th>
</tr>
@foreach (var item in Model.OrdersDespatched)
{
<tr>
<td>
<a href="@Url.Action("OrderDetails", "Home", new { id = item.OrderId })">
@item.OrderId
@Html.HiddenFor(x => item.OrderId)
</a>
</td>
<td>
£@item.Total
@Html.HiddenFor(x => item.Total)
</td>
<td>
@item.OrderDate
@Html.HiddenFor(x => item.OrderDate)
</td>
<td>
@Html.DropDownListFor(m => item.Status, new SelectList(Model.OrderStatuses, "Id", "StatusName"))
</td>
</tr>
}
</table>
<div class="panel-body form-group">
<div class="col-md-offset-2 col-md-10">
<input id="Order-Update-Button" type="submit" value="Update" class="btn btn-success" />
</div>
</div>
</div>
Chrome Console Error:
AdminOrders:60 Uncaught TypeError: Converting circular structure to JSON
at JSON.stringify (<anonymous>)
at HTMLInputElement.<anonymous> (AdminOrders:60)
at HTMLInputElement.dispatch (jquery-3.1.1.js:5201)
at HTMLInputElement.elemData.handle (jquery-3.1.1.js:5009)