javascript - 如何用视图模型和表格内容序列化表单?
问题描述
我是 ASP.NET MVC 的新手。我面临一个问题,无法找到解决方案。实际上我正在创建一个库存管理项目。在这个项目中,我有 2 个 ViewModel。一个是 PurchaseOrderViewModel,另一个是 TableViewModel。现在我在弹出模式中使用两者并将详细信息保存在视图模型中,但我无法做到这一点。在图像中,您可以看到下面显示了一个表记录,我需要将其插入到视图模型中。请帮助我。我真的很感谢你。
[HttpPost]
public async Task<ActionResult> CreateOrUpdatePurchase(PurchaseOrderViewModel purchase)
{
PurchaseOrder purchase2 = new PurchaseOrder();
int suplierId = purchase.Supplier_ID;
purchase.Supplier_ID = suplierId;
purchase.SupplierName = context.Suppliers.Where(x => x.Supplier_ID == suplierId).Select(x => x.Supplier_Name).FirstOrDefault();
string loginId = Convert.ToString(Session["LoginId"]);
string UserRoleName = Convert.ToString(Session["UserTypeName"]);
try
{
if (!string.IsNullOrEmpty(loginId))
{
if (UserRoleName == RoleTypeConstant.CustomerUserType)
{
PurchaseOrder purchase1 = new PurchaseOrder();
purchase1.LoginID = loginId;
purchase1.PurchaseID = purchase.PurchaseID;
purchase1.SupplierID = purchase.Supplier_ID;
purchase1.SupplierName = purchase.SupplierName;
purchase1.Currency = purchase.Currency;
purchase1.Date_Of_Purchase = purchase.Date_Of_Purchase;
purchase1.Due_Date = purchase.Due_Date;
purchase1.CreatedBy = loginId;
purchase1.CreatedOn = DateTime.Now;
purchase1.UpdatedBy = loginId;
purchase1.UpdatedOn = DateTime.Now;
purchase1.Status = StatusConstant.Active;
bool regCustBen = await _websiteRepo.AddPurchase(purchase1);
if (regCustBen)
{
return Json(new { success = true, message = "Saved Successfully" }, JsonRequestBehavior.AllowGet);
}
return RedirectToAction("GetPurchasePartial");
}
else
{
return RedirectToAction("Purchase_Order", "Home");
}
}
else
{
return RedirectToAction("Login", "Account");
}
}
catch (Exception)
{
throw;
}
}
public class TableViewModel
{
public int Pid { get; set; }
//public string ProductName { get; set; }
public string Qty { get; set; }
public string Price { get; set; }
public string Amount { get; set; }
}
public class PurchaseOrderViewModel
{
public int PurchaseID { get; set; }
public string LoginID { get; set; }
public int SupplierID { get; set; }
public int Supplier_ID { get; set; }
public string SupplierName { get; set; }
public string Supplier_Name { get; set; }
public string Currency { get; set; }
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")]
public string Date_Of_Purchase { get; set; }
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")]
public string Due_Date { get; set; }
public string CreatedBy { get; set; }
public DateTime? CreatedOn { get; set; }
public string UpdatedBy { get; set; }
public DateTime? UpdatedOn { get; set; }
public int? Status { get; set; }
public int OrderID { get; set; }
public string ProductName { get; set; }
//public List<Order> s { get; set; }
public int Stock_ID { get; set; }
public string Stock_Name { get; set; }
public string Quantity { get; set; }
public decimal Price { get; set; }
public decimal Amount { get; set; }
public List<TableViewModel> TableListDto { get; set; }
}
我的脚本是
function CreateOrUpdate() {
debugger;
var modal = $("#purchaseModal");
var form = $('form[name="purchaseForm"]');
let tableData = $('#detailsTable > tbody > tr');
debugger;
console.log(tableData);
var tableDto = [];
$.each(tableData, function (rindex, row) {
console.log(row);
let tmp = {};
tmp.pid = $(row).find('td:nth-child(1)').attr('pid');
//tmp.productName = $(row).find('td:nth-child(1)').text();
tmp.qty = $(row).find('td:nth-child(2)').text();
tmp.price = $(row).find('td:nth-child(3)').text();
tmp.amount = $(row).find('td:nth-child(4)').text();
tableDto.push(tmp);
tmp = {};
});
form.validate();
if (!form.valid()) {
return;
}
else {
var data = form.serialize();
//data.TableListDto = tableDto.serialize();
$.post("/Home/CreateOrUpdatePurchase", data, function (res) {
if (res) {
modal.modal('hide');
dataTable.ajax.reload();
$.notify("Saved Successfully", {
className: "success",
globalPosition: 'top - center'
});
}
})
}
}
让我向您展示我的输出屏幕。点击这里
解决方案
您将想要发布您的购买清单,这有点捏造和人为的示例,但应该向您展示 c# 中的基本移植和savePurchases
命名空间中函数的核心保存部分。我写得很快,并且没有测试过去非常基本的(也没有 c# 测试)所以可能有一些错别字等。
为此,您只需要注意两件事
- 要保存的模型(这些列表)
- 发送到该保存购物车方法的对象(与该方法匹配的数组)查看
savePurchases
函数
我制作了一个可以使用的表单,将物品放入购物车(没有添加删除),购物车是purchases
命名空间中的对象数组。这只有简单的“添加项目”,其中没有超级花哨的东西。
[HttpPost]
public async Task<JsonResult> CreateOrUpdatePurchase(List<SaveModel> purchase)
{
// first validate your data here
// second, call your middle ware code to update database
// third return results back, whatever you need, I made this up
return Json(
new PurchaseResultModel
{
PurchaseQuantity = somevalue,
PurchaseValue = somemoney,
/*These are Provider only options.*/
SavedOK = true, //verify save OK
ValidData = true // validated data OK
});
}
public class SaveModel
{
public int Pid { get; set; }
public string Qty { get; set; }
}
创建一些 JSON 以发回
var myApp = {
products: [{
pid: "123",
name: "Water Cats",
price: 42.34
}, {
pid: "32234",
name: "Bolts",
price: 1.18
}, {
pid: "56",
name: "Sheep",
price: 34.34
}, {
pid: "2323",
name: "Sack - cotton",
price: 5.99
}],
currency: 'USD',
currencySymbol: '$',
onAddProduct: function() {
let productCart = $('#product-cart');
let firstProductItem = productCart
.find('.product-item')
.first();
},
prod: {},
savePurchases: function(event) {
let me = event.data[0].arg1;
if (me.purchases.length > 0) {
// get what we sold
let purchases = [];
// this just to show how to make a match to the c# class
// I left out price and amount since that should be a server calculation to prevent hacking of values.
for (var i = 0; i < me.purchases.length; i++) {
let p = {
Pid: me.purchases[i].pid,
Qty: me.purchases[i].qty
};
purchases.push(p);
}
$.ajax({
url: "/Home/SavePurchase",
data: purchases,
})
.complete(function(res) {
if (res) {
modal.modal('hide');
dataTable.ajax.reload();
$.notify("Saved Successfully", {
className: "success",
globalPosition: 'top - center'
});
}
})
.fail(function(x) {
// save fail action
});
} else {
// tell them they made no selections?
}
},
validate: function() {
form.validate();
if (!form.valid()) {
return;
} else {
//do valid thing
}
},
onQuantityChange: function(event) {
let me = event.data[0].arg1;
if (this.value > 0) {
let opt = me.productSelect.find("option:selected");
let product = opt.data('item');
$('#price').val(product.price);
let a = me.roundToCents(product.price * $(this).val());
me.setFieldAmount(a, $('#amount-sold')[0]);
} else {
$('#price').val(0);
me.setFieldAmount(0, $('#amount-sold')[0]);
}
},
localStringToNumber: function(s) {
return Number(String(s).replace(/[^0-9.-]+/g, ""));
},
setFieldAmount: function(amount, field) {
var options = {
maximumFractionDigits: 2,
currency: this.currency,
style: "currency",
currencyDisplay: "symbol"
};
field.value = amount ?
this.localStringToNumber(amount).toLocaleString(undefined, options) :
'';
},
setTextAmount: function(amount, field) {
var options = {
maximumFractionDigits: 2,
currency: this.currency,
style: "currency",
currencyDisplay: "symbol"
};
let v =
amount ?
this.localStringToNumber(amount).toLocaleString(undefined, options) :
'';
field.text(v);
},
onProductChange: function(event) {
let me = event.data[0].arg1;
let opt = me.productSelect.find("option:selected");
let hasSelection = !!opt;
me.productSelect.toggleClass('choice-made', hasSelection);
let q = $('#quantity');
q.prop('disabled', !hasSelection)
.val(hasSelection ? 1 : 0)
.trigger('change');
},
roundToCents: function(num) {
return Math.round(num * 100) / 100;
},
onAddItem: function(event) {
let me = event.data[0].arg1;
let prod = me.productSelect;
// only if we made a valid choice
if (prod.hasClass('choice-made')) {
let optVal = prod.find("option:selected").val();
let product = me.products.find(x => x.pid === optVal);
if (product) {
let q = $('#quantity');
let cart = $('#product-cart');
let first = cart.find('.product-item').first();
let itemRowC = first.clone();
itemRowC.find('.product-name').text(product.name);
itemRowC.find('.product-quantity').text(q.val());
me.setTextAmount(product.price, itemRowC.find('.product-price').first());
me.setTextAmount($('#amount-sold').val(), itemRowC.find('.product-amount').first());
let v = {
pid: optVal,
qty: q.val()
};
me.purchases.push(v);
itemRowC.find('.hidden').find('div').unwrap('.hidden');
let calctot = cart.find('.grand-total-group');
itemRowC.insertBefore(calctot);
let total = me.getCalculatedTotal(me.purchases);
// reset quantity values
q.prop('disabled', true)
.val(0)
.trigger('change');
prod.val('')
.removeClass('choice-made');
}
}
},
getCalculatedTotal: function(purchases) {
let total = 0;
let count = purchases.length;
for (var i = 0; i < purchases.length; i++) {
let product = this.products.find(x => x.pid === purchases[i].pid);
total = total + (product.price * purchases[i].qty);
}
$('.products-in-cart').text(count);
this.setTextAmount(total, $('#grand-total'));
return total;
},
startup: function() {
this.productSelect = $('#products');
this.purchases = [];
//add products
this.products.forEach(product => {
const opt = $('<option value="' + product.pid + '">' + product.name + '</option>');
opt.data('item', product);
this.productSelect.append(opt);
});
$('#quantity').on('change', [{
arg1: this
}], this.onQuantityChange);
$('#products').on('change', [{
arg1: this
}], this.onProductChange);
$('#add-to-cart').on('click', [{
arg1: this
}], this.onAddItem);
$('#save-cart').on('click', [{
arg1: this
}], this.savePurchases);
}
};
myApp.startup();
.hidden {
display: none;
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
<div id="purchaseModal">
<div id="purchaseOptions" data-list="[]" class="container-fluid">
<div class="row">
<div class="col-md-4 order-md-2 mb-4">
<h4 class="d-flex justify-content-between align-items-center mb-3">
<span class="text-muted">Your cart</span>
<span class="products-in-cart badge badge-secondary badge-pill">3</span>
</h4>
<ul id="product-cart" class="list-group mb-3">
<li class="list-group-item d-flex justify-content-between lh-condensed product-item">
<div class="hidden">
<div>
<h6 class="my-0">Product name</h6>
<small class="text-muted product-name">Brief description</small>
</div>
<div>
<h6 class="my-0">Quantity</h6>
<small class="text-muted product-quantity">3</small>
</div>
<div>
<h6 class="my-0">Price</h6>
<small class="text-muted product-price">$12.24</small>
</div>
<div>
<h6 class="my-0">Amount</h6>
<small class="centered-text text-muted product-amount">$36.72</small>
</div>
</div>
</li>
<li class="grand-total-group list-group-item d-flex justify-content-between bg-light">
<div class="text-success">
<span>Total (USD)</span>
</div>
<strong class="text-success"><span id="grand-total">0</span></strong>
</li>
</ul>
</div>
<div class="col-md-12 order-md-1">
<h4 class="mb-3">Choose Products</h4>
<form class="product-choice needs-validation" novalidate="" _lpchecked="1">
<div class="row">
<div class="col-md-5 mb-3">
<label for="products">Products</label>
<select class="custom-select d-block w-100" id="products" required="">
<option value="">Choose...</option>
</select>
<div class="invalid-feedback">
Please select a valid Product.
</div>
</div>
</div>
<div class="row ">
<div class="col-3 ">
<label for="quantity">Quantity</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text">#</span>
</div>
<input type="number" disabled="true" class="form-control" id="quantity" placeholder="0" required="">
<div class="invalid-feedback" style="width: 100%;">
Quantity is required.
</div>
</div>
</div>
<div class="col-3 ">
<label for="price">Price</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text">$</span>
</div>
<input type="text" class="form-control" id="price" disabled="true">
</div>
</div>
<div class="col-3 ">
<label for="amount-sold">Amount</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text">$</span>
</div>
<input type="text" pattern="^\d+(?:\.\d{1,2})?$" class="form-control" id="amount-sold" disabled="true">
</div>
</div>
</div>
<div class="col-3 ">
<button id="add-to-cart" class="form-control btn btn-info btn-sm " type="button">Add to Cart</button>
</div>
</div>
<hr class="sm-4">
<button id="save-cart" class="btn btn-primary btn-md btn-block" type="button">Save Cart</button>
</form>
</div>
</div>
</div>
</div>
推荐阅读
- protractor - 在量角器中跳过广告
- android - 在 Android 11 的锁定屏幕上隐藏媒体控件
- linux - 是否需要在禁用 CR0“写保护”后调用 set_memory_rw 来修改 Linux 内核中的只读页面?
- tabulator - Tabulator Ajax 排序 - 将字段作为 sorters[0][field] 和 sorters[0][dir] 传递,我如何将其更改为自定义参数
- java - 为什么我的 Matchers.equalTo() 说数组相同时不同
- .net-5 - .NET 5.0 HealthCheckService 不会为基于 Url 的健康检查返回正确的 json 响应
- authentication - Gramex 注册功能
- c++ - C++中动态调度机制和调用正确函数的过程
- ruby-on-rails-6 - Rails 6:找不到模块“private_pub”,未定义 PrivatePub
- sql - 将日期转换为其他格式时数字无效