I am trying to create an expandable input table and I am running into some issues. Both seem to be related to the fact that the scripts are not running, but I am not sure. None of the buttons are working even though they have in the past. I don't know what changed, but I did not change the add or delete functions but they don't work anymore. The submit button doesn't seem to trigger the corresponding function in the controller.
I have tried looking for syntax errors and there don't seem to be any. The scripts seem to be referencing the correct portion of the view.
Here is the controller:
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Promotion_Generator.Models.DataModels;
namespace Promotion_Generator.Controllers
{
public class PromotionController : Controller
{
private PromotionGeneratorEntities db = new PromotionGeneratorEntities();
public ActionResult BOGO()
{
return View();
}
[HttpPost]
public JsonResult BOGOSave(string BuyMemberData, string GetMemberData)
{
try
{
var BuySerializeData = JsonConvert.DeserializeObject<List<String>>(BuyMemberData);
foreach (var data in BuySerializeData)
{
}
var GetSerializeData = JsonConvert.DeserializeObject<List<String>>(GetMemberData);
foreach (var data in GetSerializeData)
{
}
db.SaveChanges();
}
catch (Exception)
{
return Json("fail");
}
return Json("success");
}
}
}
Here is the View
#model Promotion_Generator.Models.BOGOModel
#{
ViewBag.Title = "BOGO";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2><b>Buy One Get One Free</b></h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
<p class = "control-label col-md-2"><b>Promotion Code</b></p>
<div class="col-md-10">
#Html.EditorFor(model => model.PROMOTION_CODE, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.PROMOTION_CODE, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<p class="control-label col-md-2"><b>Description</b></p>
<div class="col-md-10">
#Html.EditorFor(model => model.DESCRIPTION, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.DESCRIPTION, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<p class="control-label col-md-2"><b>Start Date Time</b></p>
<div class="col-md-10">
#Html.EditorFor(model => model.START_DATE_TIME, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.START_DATE_TIME, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<p class="control-label col-md-2"><b>End Date Time</b></p>
<div class="col-md-10">
#Html.EditorFor(model => model.END_DATE_TIME, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.END_DATE_TIME, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<p class="control-label col-md-2"><b>Percent Off</b></p>
<div class="col-md-10">
#Html.EditorFor(model => model.PERCENT_OFF, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.PERCENT_OFF, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<p class="control-label col-md-2"><b>Percent Off</b></p>
<div class="col-md-10">
#Html.EditorFor(model => model.BUY_MEMBERS, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.PERCENT_OFF, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group col-md-10">
<h3><b>Buy Products</b></h3>
<table id="buyProducts" class="table">
<thread>
<tr>
<th>
<p>Product UPC</p>
</th>
</tr>
</thread>
<tbody>
<tr>
<td>
#Html.EditorFor(modelItem => modelItem.BUY_MEMBERS, new { htmlAttributes = new { #class = "form-control" } })
</td>
<td>
<input type="button" value="Remove" onclick="T1Remove(this)" />
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td>
<input class="btn btn-default" id="btnAdd1" type="button" name="name" value="Add" />
</td>
</tr>
</tfoot>
</table>
</div>
<div class="form-group col-md-10">
<h3><b>Get Products</b></h3>
<table id="getProducts" class="table">
<thread>
<tr>
<th>
<p>Product UPC</p>
</th>
</tr>
</thread>
<tbody>
<tr>
<td>
#Html.EditorFor(modelItem => modelItem.GET_MEMBERS, new { htmlAttributes = new { #class = "form-control" } })
</td>
<td>
<input type="button" value="Remove" onclick="T2Remove(this)" />
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td>
<input class="btn btn-default" id="btnAdd2" type="button" name="name" value="Add" />
</td>
</tr>
</tfoot>
</table>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" id="btnSubmit" value="Submit" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to Home", "Index", "Home")
</div>
#section scripts{
<script>
$(".btnAdd1").click(function () {
//Get the reference of the Table's TBODY element.
var tBody = $("#buyProducts > TBODY")[0];
//Add Row.
var row = tBody.insertRow(-1);
//Add Editor cell.
var cell = $(row.insertCell(-1));
cell.append("#Html.EditorFor(modelItem => modelItem.GET_MEMBERS, new { htmlAttributes = new { #class = "form-control" } })");
//Add Button cell.
cell = $(row.insertCell(-1));
var btnRemove = $("<input />");
btnRemove.attr("type", "button");
btnRemove.attr("onclick", "T1Remove(this);");
btnRemove.val("Remove");
cell.append(btnRemove);
//Clear the TextBoxes.
txtName.val("");
txtCountry.val("");
});
$(".btnAdd2").click(function () {
//Get the reference of the Table's TBODY element.
var tBody = $("#getProducts > TBODY")[0];
//Add Row.
var row = tBody.insertRow(-1);
//Add Editor cell.
var cell = $(row.insertCell(-1));
cell.append("#Html.EditorFor(modelItem => modelItem.GET_MEMBERS, new { htmlAttributes = new { #class = "form-control" } })");
//Add Button cell.
cell = $(row.insertCell(-1));
var btnRemove = $("<input />");
btnRemove.attr("type", "button");
btnRemove.attr("onclick", "T2Remove(this);");
btnRemove.val("Remove");
cell.append(btnRemove);
//Clear the TextBoxes.
txtName.val("");
txtCountry.val("");
});
function T1Remove(button) {
//Determine the reference of the Row using the Button.
var row = $(button).closest("TR");
var name = $("TD", row).eq(0).html();
if (confirm("Do you want to delete: " + name)) {
//Get the reference of the Table.
var table = $("#buyProducts")[0];
//Delete the Table row using it's Index.
table.deleteRow(row[0].rowIndex);
}
};
function T2Remove(button) {
//Determine the reference of the Row using the Button.
var row = $(button).closest("TR");
var name = $("TD", row).eq(0).html();
if (confirm("Do you want to delete: " + name)) {
//Get the reference of the Table.
var table = $("#getProducts")[0];
//Delete the Table row using it's Index.
table.deleteRow(row[0].rowIndex);
}
};
function BuyMembers() {
var BuyMembers = $(this).find('#BuyMembers').val();
return BuyMembers;
};
function GetMembers() {
var GetMembers = $(this).find('#GetMembers').val();
return GetMembers;
};
$('.btnSubmit').click(function () {
$.ajax({
url: '/Promotion/SaveData',
type: 'POST',
dataType: 'json',
contentType: 'application/json; charset=utf-8',
data: JSON.stringify(BuyMembers),
data: JSON.stringify(GetMembers),
success: function () {
alert("Data Added Successfully");
},
error: function () {
alert("Error while inserting data");
}
});
});
</script>
}
When I hit the Add, Remove, and Submit buttons the script doesn't seem to run and no columns are added or deleted.
You're currently assigning the jQuery events to the classes ($(".btnAdd1")) instead of ids ($("#btnAdd1")). You can either change your events to link to the id values:
$("#btnAdd1").click(function () {
//...
}
$("#btnAdd2").click(function () {
//...
});
$('#btnSubmit').click(function () {
//...
});
or change the inputs to have the classes of the events. This will fix your issue with the click events not triggering.
Related
public partial class Sale
{
public int Sale_id { get; set; }
public string Order_No { get; set; }
public string Customer_name { get; set; }
public string Customer_phone { get; set; }
public string Customer_address { get; set; }
public string Payment_method { get; set; }
public double Total_amout { get; set; }
public bool Status_bit { get; set; }
public string Created_by { get; set; }
public System.DateTime Created_date { get; set; }
public string Modified_by { get; set; }
public System.DateTime Modified_date { get; set; }
}
public partial class SalesDetail
{
public int Sales_detail_id { get; set; }
public string Order_No_cp { get; set; }
public int Product_id { get; set; }
public double Unit_price { get; set; }
public int Quantity { get; set; }
public double LineTotal { get; set; }
public virtual Product Product { get; set; }
}
I Combined two model (Sales & SalesDetail)
public class Combined
{
public virtual Sale MCombined_Sales { get; set; }
public virtual SalesDetail MCombined_SalesDetail { get; set; }
}
Controller
public ActionResult Client()
{
Session["SysDateTime"] = System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
Session["CrruntUser"] = "Testing";
ViewBag.Product_id = new SelectList(db.Products, "Product_id", "Product_name");
return View();
}
[HttpPost]
public ActionResult Add(Combined model)
{
if (ModelState.IsValid == true)
{
var MCombined_Sales = new Sale
{
Order_No = model.MCombined_Sales.Order_No,
Customer_name = model.MCombined_Sales.Customer_name,
Customer_phone = model.MCombined_Sales.Customer_phone,
Customer_address = model.MCombined_Sales.Customer_address,
Payment_method = model.MCombined_Sales.Payment_method,
Total_amout = model.MCombined_Sales.Total_amout,
Status_bit = model.MCombined_Sales.Status_bit,
Created_by = model.MCombined_Sales.Created_by,
Created_date = model.MCombined_Sales.Created_date,
Modified_by = model.MCombined_Sales.Modified_by,
Modified_date = model.MCombined_Sales.Modified_date,
};
var MCombined_SalesDetail = new SalesDetail
{
Order_No_cp = model.MCombined_SalesDetail.Order_No_cp,
Product_id = model.MCombined_SalesDetail.Product_id,
Unit_price = model.MCombined_SalesDetail.Unit_price,
Quantity = model.MCombined_SalesDetail.Quantity,
LineTotal = model.MCombined_SalesDetail.LineTotal,
};
using (var context = new Entities())
{
context.Sales.Add(MCombined_Sales);
MCombined_Sales.Sale_id = MCombined_Sales.Sale_id;
context.SalesDetails.Add(MCombined_SalesDetail);
context.SaveChanges();
ModelState.Clear();
}
}
return View();
}
View ( With using namespace:- #model ASH_POS.Models.Merge.Combined)
#using (Html.BeginForm(new { #id = "registerFormId", #class = "form-horizontal", role = "form" })) {
#Html.AntiForgeryToken()
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="card">
<h4 class="text-center">Sale</h4>
<div id="Detail" class="row visually-hidden">
<div class="col">
<div class="form-group">
#Html.LabelFor(model => model.MCombined_Sales.Status_bit, htmlAttributes: new { #class = "control-label " })
<div class="col-md-10">
<div class="checkbox">
#Html.EditorFor(model => model.MCombined_Sales.Status_bit)
#Html.ValidationMessageFor(model => model.MCombined_Sales.Status_bit, "", new { #class = "text-danger" })
</div>
</div>
</div>
</div>
<div class="col">
<div class="form-group">
#Html.LabelFor(model => model.MCombined_Sales.Created_by, htmlAttributes: new { #class = "control-label " })
<div class="col-md-10">
#Html.EditorFor(model => model.MCombined_Sales.Created_by, new { htmlAttributes = new { #class = "form-control", #Value = Session["CrruntUser"], #readonly = "readonly" } })
#Html.ValidationMessageFor(model => model.MCombined_Sales.Created_by, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="col">
<div class="form-group">
#Html.LabelFor(model => model.MCombined_Sales.Created_date, htmlAttributes: new { #class = "control-label " })
<div class="col-md-10">
#Html.EditorFor(model => model.MCombined_Sales.Created_date, new { htmlAttributes = new { #class = "form-control", #Value = Session["SysDateTime"], #readonly = "readonly" } })
#Html.ValidationMessageFor(model => model.MCombined_Sales.Created_date, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="col">
<div class="form-group">
#Html.LabelFor(model => model.MCombined_Sales.Modified_by, htmlAttributes: new { #class = "control-label " })
<div class="col-md-10">
#Html.EditorFor(model => model.MCombined_Sales.Modified_by, new { htmlAttributes = new { #class = "form-control", #Value = Session["CrruntUser"], #readonly = "readonly" } })
#Html.ValidationMessageFor(model => model.MCombined_Sales.Modified_by, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="col">
<div class="form-group">
#Html.LabelFor(model => model.MCombined_Sales.Modified_date, htmlAttributes: new { #class = "control-label " })
<div class="col-md-10">
#Html.EditorFor(model => model.MCombined_Sales.Modified_date, new { htmlAttributes = new { #class = "form-control", #Value = Session["SysDateTime"], #readonly = "readonly" } })
#Html.ValidationMessageFor(model => model.MCombined_Sales.Modified_date, "", new { #class = "text-danger" })
</div>
</div>
</div>
</div>
<div class="card-title">
<div class="form-group">
#Html.LabelFor(model => model.MCombined_Sales.Order_No, htmlAttributes: new { #class = "control-label " })
<div class="col-md-10">
#Html.EditorFor(model => model.MCombined_Sales.Order_No, new { htmlAttributes = new { #class = "form-control", #required = true, #Value = "1500" } })
#Html.ValidationMessageFor(model => model.MCombined_Sales.Order_No, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="card-body">
<div class="row">
<div class="col">
<div class="form-group">
#Html.LabelFor(model => model.MCombined_Sales.Customer_name, htmlAttributes: new { #class = "control-label " })
<div class="col-md-10">
#Html.EditorFor(model => model.MCombined_Sales.Customer_name, new { htmlAttributes = new { #class = "form-control", #required = true, #Value = "N/A" } })
#Html.ValidationMessageFor(model => model.MCombined_Sales.Customer_name, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="col">
<div class="form-group">
#Html.LabelFor(model => model.MCombined_Sales.Customer_phone, htmlAttributes: new { #class = "control-label " })
<div class="col-md-10">
#Html.EditorFor(model => model.MCombined_Sales.Customer_phone, new { htmlAttributes = new { #class = "form-control", #Value = "N/A" } })
#Html.ValidationMessageFor(model => model.MCombined_Sales.Customer_phone, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="col">
<div class="form-group">
#Html.LabelFor(model => model.MCombined_Sales.Customer_address, htmlAttributes: new { #class = "control-label" })
<div class="col-md-10">
#Html.EditorFor(model => model.MCombined_Sales.Customer_address, new { htmlAttributes = new { #class = "form-control", #Value = "N/A" } })
#Html.ValidationMessageFor(model => model.MCombined_Sales.Customer_address, "", new { #class = "text-danger" })
</div>
</div>
</div>
</div>
<div class="row">
<div class="col">
<div class="form-group">
#Html.LabelFor(model => model.MCombined_Sales.Payment_method, htmlAttributes: new { #class = "control-label " })
<div class="col-md-10">
#Html.EditorFor(model => model.MCombined_Sales.Payment_method, new { htmlAttributes = new { #class = "form-control", #Value = "Cash" } })
#Html.ValidationMessageFor(model => model.MCombined_Sales.Payment_method, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="col">
<div class="form-group">
#Html.LabelFor(model => model.MCombined_Sales.Total_amout, htmlAttributes: new { #class = "control-label " })
<div class="col-md-10">
#Html.EditorFor(model => model.MCombined_Sales.Total_amout, new { htmlAttributes = new { #class = "form-control", #readonly = "readonly" } })
#Html.ValidationMessageFor(model => model.MCombined_Sales.Total_amout, "", new { #class = "text-danger" })
</div>
</div>
</div>
</div>
</div>
<div class="card-footer">
<table id="tblProduct" class="table" cellpadding="0" cellspacing="0">
<thead>
<tr>
<th>Order No</th>
<th>Product Name</th>
<th>Per Pice Price</th>
<th>Quantity</th>
<th>Amount</th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="text" readonly value="" placeholder="Enter Order No " id="textBox_Order_No_cp" class="form-control" /></td>
<td><input type="text" value="1" placeholder="Search Product " id="textBox_Product_id" class="form-control" /></td>
<td><input type="number" value="15" min="0" placeholder="Enter Unit Price Product " id="textBox_Unit_price" class="form-control" /></td>
<td><input type="number" value="" step="1" min="1" placeholder="Enter Quantity" id="textBox_Quantity" class="form-control" /></td>
<td><input type="number" min="1" readonly value="" placeholder="Line Total" id="textBox_LineTotal" class="form-control" /></td>
<td><input type="button" id="btnAddProduct" value="Add" class="btn btn-sm" /></td>
</tr>
</tbody>
<tfoot>
<tr>
<td>
#Html.EditorFor(model => model.MCombined_SalesDetail.Order_No_cp, new { htmlAttributes = new { #class = "form-control", #placeholder = "Order Number" } })
#Html.ValidationMessageFor(model => model.MCombined_SalesDetail.Order_No_cp, "", new { #class = "text-danger" })
</td>
<td>
#Html.EditorFor(model => model.MCombined_SalesDetail.Product_id, new { htmlAttributes = new { #class = "form-control", #placeholder = "ID" } })
#Html.ValidationMessageFor(model => model.MCombined_SalesDetail.Product_id, "", new { #class = "text-danger" })
</td>
<td>
#Html.EditorFor(model => model.MCombined_SalesDetail.Unit_price, new { htmlAttributes = new { #class = "form-control", #placeholder = "Unit Price", #min = "0" } })
#Html.ValidationMessageFor(model => model.MCombined_SalesDetail.Unit_price, "", new { #class = "text-danger" })
</td>
<td>
#Html.EditorFor(model => model.MCombined_SalesDetail.Quantity, new { htmlAttributes = new { #class = "form-control", #placeholder = "Quantity", #type = "number", #min = "1" } })
#Html.ValidationMessageFor(model => model.MCombined_SalesDetail.Quantity, "", new { #class = "text-danger" })
</td>
<td>
#Html.EditorFor(model => model.MCombined_SalesDetail.LineTotal, new { htmlAttributes = new { #class = "form-control", #placeholder = "LineTotal", } })
#Html.ValidationMessageFor(model => model.MCombined_SalesDetail.LineTotal, "", new { #class = "text-danger" })
</td>
<td></td>
</tr>
</tfoot>
</table>
</div>
<div id="btns">
<div class="form-group dataTables_wrapper">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn " id="AddClient" />
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="reset" value="Reset" class="btn" id="AddClient" />
</div>
</div>
<input type="submit" value="Testing Multi Row Table" class="btn btn-info close" id="btnTesting" />
</div>
</div> }
Use jQuery For Handle Multiple Models
$("#AddClient").click(function () {
var MCombined_Sales = {
Order_No: $('##Html.IdFor(model => model.MCombined_Sales.Order_No)').val(),
Customer_name: $('##Html.IdFor(model => model.MCombined_Sales.Customer_name)').val(),
Customer_phone: $('##Html.IdFor(model => model.MCombined_Sales.Customer_phone)').val(),
Customer_address: $('##Html.IdFor(model => model.MCombined_Sales.Customer_address)').val(),
Payment_method: $('##Html.IdFor(model => model.MCombined_Sales.Payment_method)').val(),
Total_amout: $('##Html.IdFor(model => model.MCombined_Sales.Total_amout)').val(),
Status_bit: $('##Html.IdFor(model => model.MCombined_Sales.Status_bit)').val(),
Created_by: $('##Html.IdFor(model => model.MCombined_Sales.Created_by)').val(),
Created_date: $('##Html.IdFor(model => model.MCombined_Sales.Created_date)').val(),
Modified_by: $('##Html.IdFor(model => model.MCombined_Sales.Modified_by)').val(),
Modified_date: $('##Html.IdFor(model => model.MCombined_Sales.Modified_date)').val()
};
var MCombined_SalesDetail = {
Order_No_cp: $('##Html.IdFor(model => model.MCombined_SalesDetail.Order_No_cp)').val(),
Product_id: $('##Html.IdFor(model => model.MCombined_SalesDetail.Product_id)').val(),
Unit_price: $('##Html.IdFor(model => model.MCombined_SalesDetail.Unit_price)').val(),
Quantity: $('##Html.IdFor(model => model.MCombined_SalesDetail.Quantity)').val(),
LineTotal: $('##Html.IdFor(model => model.MCombined_SalesDetail.LineTotal)').val()
};
var model = {
"MCombined_Sales": MCombined_Sales,
"MCombined_SalesDetail": MCombined_SalesDetail
}
$.ajax({
type: "POST",
url: "/Customer/Add",
data: model,
dataType: "json",
success: function (r) {
alert("id: " + r.Sale_id.toString());
},
failure: function (response) {
alert(response.responseText);
},
error: function (response) {
alert(response.responseText);
}
});
});
I try use jQuery For Send Multiple Rows to db butt no success
$("body").on("click", "#btnAddProduct", function () {
//Reference the Name and Country TextBoxes.
var textBox_Order_No_cp = $("#textBox_Order_No_cp");
var textBox_Product_id = $("#textBox_Product_id");
var textBox_Unit_price = $("#textBox_Unit_price");
var textBox_Quantity = $("#textBox_Quantity");
var textBox_LineTotal = $("#textBox_LineTotal");
//Get the reference of the Table's TBODY element.
var tBody = $("#tblProduct > TBODY")[0];
//Add Row.
var row = tBody.insertRow(-1);
//Add textBox_Order_No_cp cells.
var cell = $(row.insertCell(-1));
cell.html(textBox_Order_No_cp.val());
//Add textBox_Product_id cell.
var cell = $(row.insertCell(-1));
cell.html(textBox_Product_id.val());
//Add textBox_Unit_price cell.
var cell = $(row.insertCell(-1));
cell.html(textBox_Unit_price.val());
//Add textBox_Quantity cell.
var cell = $(row.insertCell(-1));
cell.html(textBox_Quantity.val());
//Add textBox_LineTotal cell.
var cell = $(row.insertCell(-1));
cell.html(textBox_LineTotal.val());
//Add Button cell.
cell = $(row.insertCell(-1));
var btnRemove = $("<input />");
btnRemove.attr("type", "button");
btnRemove.attr("onclick", "Remove(this);");
btnRemove.addClass("btn btn-sm btn_row_remove")
btnRemove.val("x");
cell.append(btnRemove);
//Clear the TextBoxes.
//textBox_Order_No_cp.val("");
textBox_Product_id.val("");
textBox_Unit_price.val("");
textBox_Quantity.val("");
textBox_LineTotal.val("");
$('#btnAddProduct').attr("disabled", true);
});
function Remove(button) {
//Determine the reference of the Row using the Button.
var row = $(button).closest("TR");
var name = $("TD", row).eq(1).html();
//if (confirm("Do you want to delete: " + name)) {
// //Get the reference of the Table.
// var table = $("#tblProduct")[0];
// //Delete the Table row using it's Index.
// table.deleteRow(row[0].rowIndex);
//}
// if dirict delete with out msg
var table = $("#tblProduct")[0];
table.deleteRow(row[0].rowIndex);
};
$("body").on("click", "#btnTesting", function () {
//Loop through the Table rows and build a JSON array.
var DataMethod = new Array();
$("#tblProduct TBODY TR").each(function () {
var row = $(this);
var DataString = {};
DataString.MCombined_SalesDetail.Order_No_cp = row.find("TD").eq(0).html();
DataString.MCombined_SalesDetail.Product_id = row.find("TD").eq(1).html();
DataString.MCombined_SalesDetail.Unit_price = row.find("TD").eq(2).html();
DataString.MCombined_SalesDetail.Quantity = row.find("TD").eq(3).html();
DataString.MCombined_SalesDetail.LineTotal = row.find("TD").eq(4).html();
DataMethod.push(DataString);
alert("Check Array");
});
alert("Going To Ajax");
//Send the JSON array to Controller using AJAX.
$.ajax({
type: "POST",
url: "/Customer/Insert",
data: JSON.stringify(DataMethod),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (r) {
alert(r + " record(s) inserted.");
}
});
});
I have sent multiple models data to database successfully, but i face problems send multiple row data.
I have an ASP.NET MVC program with an order/odc request form. I have a customer, order and order item model. What I want to do is allow the user to place an order for a list of items to be approved. I have the viewmodel being passed to the form/view with a few fields including a list of order item objects. I am able to dynamically add rows to the table which shows the list of order items but on submit there is nothing in the viewmodel list. What am I doing wrong? How do I pass the items entered into the table to the view so that I can submit to the database?
Controller
public ActionResult NewOdc()
{
var viewModel = new NewOdcViewModel()
{
OdcItems = new List<tblOdcItem>()
};
viewModel.OdcItems.Add(new tblOdcItem());
return View(viewModel);
}
I call this code from jQuery to add a new item to the list:
public ActionResult GetView(string rowCount)
{
tblOdcItem item = new tblOdcItem();
return PartialView("_OdcItemEditor", item);
}
And on submit I call this code:
[HttpPost]
public ActionResult NewOdcSubmit(NewOdcViewModel viewModel)
{
_context.tblOdcs.Add(new tblOdc());
...
I'm using a foreach to go through the list and create a partial for each item.
View:
#using (Html.BeginForm("NewOdcSubmit", "Odc", FormMethod.Post))
{
if (Model != null)
{
#Html.HiddenFor(m => m.OdcItems);
}
<div class="panel panel-info">
<div class="panel-heading">
<h2 class="panel-title">Enter New ODC</h2>
</div>
<div class="panel-body">
#Html.AntiForgeryToken()
<div class="form-group">
#Html.LabelFor(model => model.User.UserName, new { #class = "col-md-2 col-sm-1 control-label" })
<div class="col-md-2 col-sm-3">
#Html.TextBoxFor(model => model.User.UserName, new { #Value = ((PM_Portal2020.Models.tblUser)Session["User"]).UserName, #readonly = true })
</div>
#Html.LabelFor(model => model.User.Phone, new { #class = "col-md-2 col-sm-1 control-label" })
<div class="col-md-2 col-sm-3">
#Html.TextBoxFor(model => model.User.Phone, new { #Value = ((PM_Portal2020.Models.tblUser)Session["User"]).Phone })
</div>
</div>
<div class="form-group col-md-10 col-sm-12">
<label>Expenses</label>
<table id="submissionTable" class="table table-bordered">
<thead>
<tr>
<th>Qty</th>
<th>Description</th>
<th>Estimated Cost</th>
</tr>
</thead>
<tbody>
#foreach (PM_Portal2020.Models.tblOdcItem item in Model.OdcItems)
{
#Html.Partial("_OdcItemEditor", item)
}
</tbody>
</table>
<p>
<button id="add" type="button" class="btn btn-primary">Add</button>
</p>
</div>
<div class="form-group col-lg-10 col-sm-12">
#Html.LabelFor(model => model.Details, new { #class = "col-md-2 col-sm-1 control-label" })
<div class="">
#Html.TextAreaFor(model => model.Details, new { #class = "form-control" })
</div>
</div>
</div>
<div class="panel-footer">
<div class="">
<button type="submit" class="btn btn-success">Save</button>
#Html.ActionLink("Back", "Index")
</div>
</div>
</div>
}
PartialView in Shared folder:
#model PM_Portal2020.Models.tblOdcItem
<tr #Html.Id("tablerow" + Model.ID)>
<td>
<div class="editor-field">
#Html.TextBoxFor(model => model.Quantity, new { #class = "text-box single-line", name = "Quantity[" + Model.ID + "]", type = "text", value = "", required = "required" })
</div>
</td>
<td>
<div class="editor-field">
#Html.TextBoxFor(model => model.Description, new { #class = "text-box single-line", name = "Description[" + Model.ID + "]", type = "text", value = "", required = "required", id = "itemDesc" })
</div>
</td>
<td>
<div class="editor-field">
#Html.TextBoxFor(model => model.EstimatedCost, new { #class = "text-box single-line", name = "EstimatedCost[" + Model.ID + "]", type = "text", value = "", required = "required" })
</div>
</td>
<td>
<button type="button" class="btn btn-primary" onclick="removeTr(this);">
<span class="glyphicon glyphicon-trash"></span>
</button>
</td>
</tr>
View Model
public class NewOdcViewModel
{
public NewOdcViewModel()
{
}
public IList<tblOdcItem> OdcItems { get; set; }
public string Details { get; set; }
public int OdcId { get; set; }
public tblUser User { get; set; }
}
It submits to the controller but the odcitems list is always count = 0. Any help would be great. Thanks
Here is the javascript example, just use this function on add/delete operation to re-arrange name.
function RearangeName(){
var i = 0;
$("#submissionTable>tbody>tr").each(function () {
$(this).find("input").each(function () {
if ($(this).prop("name").indexOf('Quantity') > 0) {
$(this).attr('name', "OdcItems[" + i + "].Quantity");
}
if ($(this).prop("name").indexOf('Description') > 0) {
$(this).attr('name', "OdcItems[" + i + "].Description");
}
if ($(this).prop("name").indexOf('EstimatedCost') > 0) {
$(this).attr('name', "OdcItems[" + i + "].EstimatedCost");
}
});
i++;
});
}
the name should be matched with model property, so in partial view, you have set name as OdcItems[0].Quantity instead of Quantity[" + Model.ID + "].
#Html.TextBoxFor(model => model.Quantity, new { #class = "text-box single-line", name = "OdcItems[0].Quantity", type = "text", value = "", required = "required" })
eg.
OdcItems[0].Quantity
OdcItems[1].Quantity
OdcItems[2].Quantity
....
OdcItems[n].Quantity
I'm trying to call a partial view with details table for some items. However, the partial view does not show any record in the main view. How I can call the Patrial view successfully? the partial view as follows:
#model IDECOHealthInsurance.Models.Pharmacy
#using (Html.BeginForm("pharmacyDetials", "Pharmacy"))
{
<h4>تفاصيل الصيدلية</h4>
<div id="dvPatientNotice" class="MainGridContainer pb-5">
#if (Model.dtItemsDetails != null)
{
<table dir="rtl" id="Paitents" class="MainGrid">
<thead>
<tr style="text-size-adjust:auto">
<th>
رقم الموظف
</th>
<th>
التاريخ
</th>
<th>
الوقت
</th>
<th>
المستفيدون
</th>
<th>
ملاحظات
</th>
<th>
الباركورد
</th>
<th>
أسم العينة
</th>
<th>
الكمية
</th>
<th>
السعر
</th>
</tr>
</thead>
<tbody>
#foreach (System.Data.DataRow row in Model.dtItemsDetails.Rows)
{
<tr style="width:100%">
<td>
#row["EMPLOYEE_NUMBER"]
</td>
<td>
#row["ENTRY_DATE"]
</td>
<td>
#row["ENTRY_TIME"]
</td>
<td>
#row["BENEFICIARIES"]
</td>
<td>
#row["NOTE"]
</td>
<td>
#row["ITEM_CODE"]
</td>
<td>
#row["ITEM_NAME"]
</td>
<td>
#row["QTY"]
</td>
<td>
#row["PRICE"]
</td>
</tr>
}
</tbody>
</table>
}
</div>
}
The controller as follows:
[HttpGet]
public ActionResult pharmacyDetials(Pharmacy model)
{
var masterID = Convert.ToInt32(Session["login"]);
if (masterID == 0)
{
return RedirectToAction("Login");
}
else
{
Models.Pharmacy objPharamcyMode = new Pharmacy();
IDECOServiceReference.IdecoAPIServiceClient idecoAPI = new IDECOServiceReference.IdecoAPIServiceClient();
DataTable dataTable = idecoAPI.GETPHARMACYEMPLOYEEMASTER("", 1);
model.dtItemsDetails = dataTable;
return PartialView("_PharmacyDetails", model);
}
}
And the Main view as follows:
#model IDECOHealthInsurance.Models.Pharmacy
#{
ViewBag.Title = "PharmacyApplication";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<table style="height:680px; width:1280px; border:hidden">
<tr>
<td>
<div id="pDetail">
#Html.Partial("_PharmacyDetails", Model)
</div>
</td>
<td>
#using (Ajax.BeginForm("PharmacyApplication", "Pharmacy", new AjaxOptions { HttpMethod = "Post", UpdateTargetId = "updatePnl", InsertionMode = System.Web.Mvc.Ajax.InsertionMode.Replace, LoadingElementId = "Loading", OnBegin = "" }))
{
<div class="form-horizontal">
<div class="form-group">
#Html.LabelFor(model => model.PHARMACY_NAME, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DisplayFor(model => model.PHARMACY_NAME)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.EMPLOYEE_NUMBER, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.EMPLOYEE_NUMBER, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.EMPLOYEE_NUMBER, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ENTRY_DATE, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DisplayFor(model => model.ENTRY_DATE, new { htmlAttributes = new { #class = "form-control", #Value = DateTime.Today.ToString("dd/MM/yyyy"), #readonly = "readonly" } })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ENTRY_TIME, new { htmlAttributes = new { #class = "form-control", #Value = DateTime.Today.ToString("HH:mm:ss"), #readonly = "readonly" } })
<div class="col-md-10">
#Html.DisplayFor(model => model.ENTRY_TIME)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.BENEFICIARIES, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
زوجة #Html.RadioButtonFor(m => m.BENEFICIARIES, 1)
أبن #Html.RadioButtonFor(m => m.BENEFICIARIES, 2)
أبنة #Html.RadioButtonFor(m => m.BENEFICIARIES, 3)
الموظف #Html.RadioButtonFor(m => m.BENEFICIARIES, 4)
#Html.ValidationMessageFor(model => model.BENEFICIARIES, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Note, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
<textarea name="NOTE" id="comments" style="font-family:'Times New Roman';font-size:1.2em; width: 280px; height:auto" placeholder="أكتب ملاحظاتك هنا"></textarea>
#Html.ValidationMessageFor(model => model.Note, "", new { #class = "text-danger" })
</div>
</div>
<div id="showPnl">
<input class="btn btn-default" type="button" value="تفاصيل الصيدلية" onclick="#("window.location.href='" + #Url.Action("pharmacyDetials", "Pharmacy") + "'");" />
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" id="panel" value="أضافة" class="btn btn-default" />
</div>
<input class="btn btn-default" type="button" value="خروج" onclick="#("window.location.href='" + #Url.Action("LogOut", "Pharmacy") + "'");" />
</div>
</div>
}
</td>
</tr>
</table>
<div id="updatePnl">
#Html.Partial("_PartialPharmacyDetails", Model)
</div>
<br />
<br />
<br />
<div id="pnlItemsDetails">
#Html.Partial("_PartialItemsDetails", Model)
</div>
When I click on the pharmacy details (in Arabic) = "تفصيل الصيدلية" button it redirects me to another page which contains the desired table that I want to show in the main view. However, I don't want this to happen I want to show the table without clicking on the button. Could you explain why this problem happened?
The Result at the run time appears as follows:
Result of the application at run time
If you want to prevent your page from redirecting, you've to use an ajax request. Replace below line :
<input class="btn btn-default" type="button" value="تفاصيل الصيدلية" onclick="#("window.location.href='" + #Url.Action("pharmacyDetials", "Pharmacy") + "'");" />
with :
<input class="btn btn-default" type="button" value="تفاصيل الصيدلية" onclick="getPharmacyDetails();" />
and in your javascript section, add below code :
function getPharmacyDetails()
{
$.ajax({
url : '#Url.Content("~/Pharmacy/pharmacyDetials")',
type: "GET",
success: function (result) {
$("#pDetail").html(result);
}
});
}
Also, replace below HTML :
<div id="pDetail">
#Html.Partial("_PharmacyDetails", Model)
</div>
With :
<div id="pDetail"></div>
The above ajax request will execute the partial view and fill the pDetial div with the required result. Try it and Let me know if you've any query.
In my view, I have an image element as follows:
<img id="ImageDisplay" class="img-thumbnail" width="280" height="280"
src="#Url.Action("GetFileFromHttpPostedFile", "Image", new { File = Model.File })"/>
When I debug my code, I can see that my Model.File is not null. But when I pass it to the action method, the action method receives the parameter as null. Here is my action method:
public FileContentResult GetFileFromHttpPostedFile(HttpPostedFileBase File)
{
byte[] imageData = new byte[File.ContentLength];
File.InputStream.Read(imageData, 0, File.ContentLength);
return GetFileFromData(imageData, File.ContentType);
}
Am I missing something? Can we not pass an HttpPostedFileBase to a method? Help please.
Edit:
I also have the following element in the view that allows the user to populate Model.File property:
<input type="file" name="File" id="File" onchange="loadFile(event)" />
loadFile(event) simply shows a preview of the picture on the view.
Edit 2: Here is the full code for the view:
#model MyProject.Models.ViewModels.ChangeProfileModel
#{
ViewBag.Title = "Change Your Profile";
}
<script>
$(document).ready(function () {
$('textarea').keyup(updateCount);
$('textarea').keydown(updateCount);
function updateCount() {
var cs = [500 - $(this).val().length];
$('#characters').text(cs);
}
});
var loadFile = function (event) {
var output = document.getElementById('ImageDisplay');
if (output != null) {
output.src = URL.createObjectURL(event.target.files[0]);
}
};
</script>
<h2>Change Your Profile Info</h2>
#using (Html.BeginForm("ChangeProfile", "Account", FormMethod.Post, new { #class = "form-horizontal", role = "form", enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
if (ViewBag.ChangesSaved == true)
{
<div class="alert alert-success">
Your changes have been saved successfully!
×
</div>
}
<div class="form-horizontal">
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.Id)
<div class="form-group">
#Html.LabelFor(model => model.City, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.City, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.City, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Country, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Country, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Country, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<label class="control-label col-md-2">Select an Image </label>
<div class="col-md-10">
<input type="file" name="File" id="File" onchange="loadFile(event)" />
</div>
</div>
<div class="form-group">
<label class="control-label col-md-2"></label>
<div class="col-md-10">
#if (Model.File == null)
{
<img id="ImageDisplay" class="img-thumbnail" width="280" height="280"
src="#Url.Action("GetImageByUser", "Image", new { id = Model.Id })"/>
}
else
{
<img id="ImageDisplay" class="img-thumbnail" width="280" height="280"
src="#Url.Action("GetFileFromHttpPostedFile", "Image", new { File = Model.File })"/>
}
</div>
</div>
<div class="form-group">
#Html.LabelFor(m => m.About, new { #class = "col-md-2 control-label" })
<div class="col-md-10">
#Html.TextAreaFor(m => m.About, new { #class = "form-control", #rows = "5", #maxlength = 500 })
<span id="characters" style="color:#999;">500</span> <span style="color:#999;">characters left</span>
#Html.ValidationMessageFor(model => model.About, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
#Html.ActionLink("Cancel", "Index", "Manage", null, new { #class = "btn btn-default" })
</div>
</div>
</div>
}
In my HomeController, I have the following methods:
public ActionResult ChangeProfile()
{
var userId = User.Identity.GetUserId();
var loggedInUser = UserManager.FindById(userId);
ChangeProfileModel viewModel = new ChangeProfileModel
{
Id = userId,
City = loggedInUser.City,
Country = loggedInUser.Country,
About = loggedInUser.About
};
return View(viewModel);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult ChangeProfile(ChangeProfileModel viewModel)
{
if (!ModelState.IsValid)
{
return View(viewModel);
}
var userId = User.Identity.GetUserId();
var loggedInUser = UserManager.FindById(userId);
byte[] imageData = null;
if (viewModel.File != null)
{
imageData = new byte[viewModel.File.ContentLength];
viewModel.File.InputStream.Read(imageData, 0, viewModel.File.ContentLength);
}
_aspNetUserRepository.EditUserInfo(userId, viewModel.City, viewModel.Country, viewModel.About,
imageData, (viewModel.File == null) ? null: viewModel.File.ContentType);
ViewBag.ChangesSaved = true;
return View(viewModel);
}
Lastly, here is my last relevant action method inside ImageController:
public FileContentResult GetFileFromHttpPostedFile(HttpPostedFileBase File)
{
byte[] imageData = new byte[File.ContentLength];
File.InputStream.Read(imageData, 0, File.ContentLength);
return GetFileFromData(imageData, File.ContentType);
}
I have an Index page on which there is a section to write a project name and select from a dropdownlist a project type.
Below that I have a submit button that directs to the ActionResult method Create in the Projects controller.
Code:
[UPDATE]
index.cshtml:
#using reqcoll.ViewModels
#model myViewModel
#{
ViewBag.Title = "ReqColl - project";
}
#* First half *#
#using (Html.BeginForm("CreateProject", "Projects"))
{
#Html.AntiForgeryToken()
<div class="top-spacing col-md-12 col-lg-12 col-sm-12">
#RenderTopHalf(Model.modelProject)
</div>
}
#* Second half *#
#using (Html.BeginForm("CreateRequirement", "Projects"))
{
#Html.AntiForgeryToken()
<div class="form-group" id="pnSecondHalf">
#* Requirements list *#
<div class=" col-md-6 col-lg-6 col-sm-12">
#RenderBottomLeftHalf(Model.modelRequirement)
</div>
#* New/Edit requirements panel *#
<div class="col-md-6 col-lg-6 col-sm-12">
#RenderBottomRightHalf(Model.modelRequirement)
</div>
</div>
}
#* ================================================================================= ============= *#
#* Helpers *#
#helper RenderTopHalf(reqcoll.Models.Project project)
{
<div class=" well">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="row">
#Html.LabelFor(model => project.projectName, htmlAttributes: new { #class = "control-label col-md-2 col-lg-2 col-sm-12" })
<div class="col-md-10 col-lg-10 col-sm-12">
#Html.TextBoxFor(model => project.projectName, htmlAttributes: new { #class = "ProjectNameInput" })
#Html.ValidationMessageFor(model => project.projectName)
</div>
</div>
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="row row-spacing">
#Html.LabelFor(model => project.projectType, htmlAttributes: new { #class = "control-label col-md-2 col-lg-2 col-sm-12" })
<div class="col-md-10 col-lg-10 col-sm-12">
#Html.DropDownListFor(model => project.projectType, new SelectList(
new List<Object>{
new { value = 0 , text = "...Select..." },
new { value = 1 , text = "Windows application" },
new { value = 2 , text = "Web application" },
new { value = 3 , text = "Device application"}
},
"value",
"text",
project.projectType), htmlAttributes: new { #class = "DropDownList" })
#Html.ValidationMessageFor(model => project.projectType)
</div>
<input type="hidden" value="" id="hdProjectID" />
</div>
<div class="row top-spacing col-md-offset-5 col-sm-offset-5">
<div id="pnCreate" class=" col-sm-4 col-md-4 col-lg-4">
<input type="submit" class="btn btn-default" value="Create" />
</div>
<div id="pnEdit" class=" col-sm-4 col-md-4 col-lg-4">
<input type="submit" class="btn btn-default" value="Edit" />
|
<input type="submit" class="btn btn-default" value="Delete" />
</div>
</div>
</div>
}
#helper RenderBottomLeftHalf(reqcoll.Models.Requirement requirement)
{
<div class=" well">
<table class="table">
<tr>
<th>
#if (Model.modelProject.Requirements != null)
{
var m = Model.modelProject;
if (m.Requirements.Count > 0)
{
#Html.DisplayNameFor(model => model.modelProject.Requirements[0].shortDesc)
}
}
else
{
<label class="label label-primary col-sm-12 col-md-6 col-lg-6">No requirements available</label>
}
</th>
<th></th>
</tr>
#if (Model.modelProject.Requirements != null)
{
var m = Model.modelProject;
if (m.Requirements.Count > 0)
{
foreach (var item in Model.modelProject.Requirements)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.shortDesc)
</td>
<td>
#* buttons here*#
#*#Html.ActionLink("E", "Edit", new { id = item.requirementID }) |
#Html.ActionLink("D", "Delete", new { id = item.requirementID })*#
</td>
</tr>
}
}
}
</table>
</div>
}
#helper RenderBottomRightHalf(reqcoll.Models.Requirement requirement)
{
<div class=" well">
#Html.ValidationSummary(true)
<div class="row">
#Html.LabelFor(model => requirement.shortDesc, htmlAttributes: new { #class = "control-label col-md-4 col-lg-4 col-sm-12" })
<div class="col-md-8 col-lg-8 col-sm-12">
#Html.TextBoxFor(model => requirement.shortDesc, htmlAttributes: new { #class = "RequirementShortDesc" })
#Html.ValidationMessageFor(model => requirement.shortDesc)
</div>
</div>
#Html.ValidationSummary(true)
<div class="row row-spacing">
#Html.LabelFor(model => requirement.longDesc, htmlAttributes: new { #class = "control-label col-md-4 col-lg-4 col-sm-12" })
<div class="col-md-8 col-lg-8 col-sm-12 RequirementLongDesc">
#Html.EditorFor(model => requirement.longDesc)
#Html.ValidationMessageFor(model => requirement.longDesc)
</div>
</div>
#Html.ValidationSummary(true)
<div class="row row-spacing">
#Html.LabelFor(model => requirement.priorityCode, htmlAttributes: new { #class = "control-label col-md-4 col-lg-4 col-sm-12" })
<div class="col-md-8 col-lg-8 col-sm-12">
#foreach (var value in Enum.GetValues(requirement.priorityCode.GetType()))
{
<div class="control-label col-sm-5 col-md-5 col-lg-5">
#Html.RadioButtonFor(m => requirement.priorityCode, value)
#Html.Label(value.ToString())
</div>
}
#Html.ValidationMessageFor(model => requirement.priorityCode)
</div>
</div>
<input type="hidden" value="" id="hdRequirementID" />
<div class="row top-spacing col-md-offset-5 col-sm-offset-5">
<div id="pnReqCreate" class=" col-sm-12 col-md-6 col-lg-6">
#* submit button here *#
#*#Html.ActionLink("Add", "Add", "Requirement", new { #class = "btn btn-default btnSize" })*#
</div>
<div id="pnReqEdit" class=" col-sm-12 col-md-6 col-lg-6">
#* submit buttons here *#
#*#Html.ActionLink("Edit", "Edit", "Requirement", new { #class = "btn btn-default btnSize" })
#Html.ActionLink("Delete", "Delete", "Requirement", new { #class = "btn btn-default btnSize" })*#
</div>
</div>
</div>
}
#section Scripts {
<script>
$(function () {
var pID = $('#hdProjectID').val();
if (pID != null) {
if (pID.length > 0) {
$('#pnEdit').show();
$('#pnCreate').hide();
$('#pnSecondHalf').show();
} else {
$('#pnEdit').hide();
$('#pnCreate').show();
$('#pnSecondHalf').hide();
}
} else {
$('#pnEdit').hide();
$('#pnCreate').show();
$('#pnSecondHalf').hide();
}
var rID = $('#hdRequirementID').val();
if (rID != null) {
if (rID.length > 0) {
$('#pnReqEdit').show();
$('#pnReqCreate').hide();
} else {
$('#pnReqEdit').hide();
$('#pnReqCreate').show();
}
} else {
$('#pnReqEdit').hide();
$('#pnReqCreate').show();
}
});
</script>
#Scripts.Render("~/bundles/jqueryval")
}
ViewModel:
using reqcoll.Models;
namespace reqcoll.ViewModels
{
public class myViewModel
{
public Project modelProject;
public Requirement modelRequirement;
}
}
Controller:
using System.Web.Mvc;
using reqcoll.Models;
using reqcoll.ViewModels;
namespace reqcoll.Controllers
{
public class ProjectsController : Controller
{
private myContext db = new myContext();
// GET: Projects
public ActionResult Index()
{
// allow more than one model to be used in the view
var vm = new myViewModel()
{
modelProject = new Project() { projectName = "test", projectType = 1 },
modelRequirement = new Requirement() { requirementID = -1 },
};
return View(vm);
}
[HttpPost]
[ValidateAntiForgeryToken]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult CreateProject(myViewModel vm)
{
if (vm != null)
{
var ab = Request.Form;
// key 1: __RequestVerificationToken
// key 2: project.projectName
// key 3: project.projectType
if (ModelState.IsValid)
{
Project project = vm.modelProject;
// db.Project.Add(project.Item1);
// db.SaveChanges();
// return RedirectToAction("Index");
}
}
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
}
}
[ORIGINAL]
#using (Html.BeginForm("Create", "Projects"))
{
#Html.AntiForgeryToken()
<div class="top-spacing col-md-12 col-lg-12 col-sm-12">
<div class=" well">
#Html.ValidationSummary(true)
<div class="row">
#Html.LabelFor(model => model.Item1.projectName, htmlAttributes: new { #class = "control-label col-md-2 col-lg-2 col-sm-12" })
<div class="col-md-10 col-lg-10 col-sm-12">
#Html.TextBoxFor(model => model.Item1.projectName, htmlAttributes: new { #class = "ProjectNameInput" })
#Html.ValidationMessageFor(model => model.Item1.projectName)
</div>
</div>
#Html.ValidationSummary(true)
<div class="row row-spacing">
#Html.LabelFor(model => model.Item1.projectType, htmlAttributes: new { #class = "control-label col-md-2 col-lg-2 col-sm-12" })
<div class="col-md-10 col-lg-10 col-sm-12">
#Html.DropDownListFor(model => model.Item1.projectType, new SelectList(
new List<Object>{
new { value = 0 , text = "...Select..." },
new { value = 1 , text = "Windows application" },
new { value = 2 , text = "Web application" },
new { value = 3 , text = "Device application"}
},
"value",
"text",
0), htmlAttributes: new { #class = "DropDownList" })
#Html.ValidationMessageFor(model => model.Item1.projectType)
</div>
<input type="hidden" value="" id="hdProjectID" />
</div>
<div class="row top-spacing col-md-offset-5 col-sm-offset-5">
<div id="pnCreate" class=" col-sm-4 col-md-4 col-lg-4">
<input type="submit" class="btn btn-default" value="Create" />
</div>
<div id="pnEdit" class=" col-sm-4 col-md-4 col-lg-4">
<input type="submit" class="btn btn-default" value="Edit" />
|
<input type="submit" class="btn btn-default" value="Delete" />
</div>
</div>
</div>
</div>
}
ProjectsController:
private myContext db = new myContext();
// GET: Projects
public ActionResult Index()
{
// allow more than one model to be used in the view
return View(new Tuple<Project, Requirement, Priority>(new Project(), new Requirement(), new Priority()));
}
[HttpPost]
[ValidateAntiForgeryToken]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create([Bind(Include = "projectName,projectType")] Project project)
{
if (ModelState.IsValid)
{
db.Project.Add(project);
db.SaveChanges();
return RedirectToAction("Index");
}
return RedirectToAction("Index");
}
So when the submit button is clicked, the ActionResult Create is called, but the ModelState is not valid and does not have the information enterd by the user.
What am I doing wrong?
Your model is looking like complex object as you are using model.Item1.projectName and model.Item1.projectType, but in action method you are trying to get values directly which is wrong.
[Updated code]
With the new code posted, this quick correction to your model will allow it to bind correctly from your view:
namespace reqcoll.ViewModels
{
public class myViewModel
{
public Project project;
public Requirement requirement;
}
}
[Original]
Despite the fact of using a Tuple<> type instead of defining a class that would encapsulate the data to pass to the view. You can still achieve what you want by creating a helper in your view.
#helper RenderMyProject(Project project) {
...
#Html.TextBoxFor(x=> project.projectType)
...
}
Then, you will call this helper
#RenderMyProject(model.Item1)
Whats the difference?
The name of the input will change. Instead of posting [Item1.projectType] Inside the response object to your controller, it will look like [project.projectType] which will be mapped to your project parameter automatically.
Found the problem.
I added {get; set;} in the myViewModel to both the models and then it worked.
so:
using reqcoll.Models;
namespace reqcoll.ViewModels
{
public class myViewModel
{
public Project Project { get; set; }
public Requirement Requirement { get; set; }
}
}