Inserting value to database using Jquery and MVC - c#

I have created a form which to insert few data into database. I am using jquery to insert the data in my mvc project but I am getting confused in how can I create insert function.
First thing, I have created a one method to Insert or Updating the record via ID. But I don't know how can I use Id as primary to check whether to Insert or Update. I know that if my ID is equal to 0 means Insert or if greater than 0 then update but how can I add that into my function. Second, I know my Insert function does not seems to be right way but what could be easier way to implement?
(View).asmx
<script type="text/javascript">
$(document).ready(function() {
//function will be called on button click having id btnsave
$("#btnRoleListSubmit").click(function() {
$.ajax({
type: "POST", //HTTP POST Method
url: '/Admin.mvc/Admin/InsertRoleList', // Controller/View
data: { //Passing data
Name: $("#Name").val(), //Reading text box values using Jquery
Role: $("#Role").val(),
}
});
});
});
</script>
<table align="center">
<tr>
<td valign="top" width="100" class="col-label">
<span>Name</span>
</td>
<td class="col-label">
<input type="text" maxlength="200" style="margin-left: 0;" name="Name" id="Name"
class="required" value="" />
</td>
</tr>
<tr>
<td valign="top" class="col-label">
Employee Role
</td>
<td class="col-label">
<textarea id="Role" name="Role" class="required" cols="15" rows="2"></textarea>
</td>
</tr>
</table>
<hr />
<div style="margin: 12px;" align="center">
<button type="submit" name="btnRoleListSubmit" class="actionButton">
<span>Add Employee Role</span></button>
</div>
(Controller).cs
public ActionResult InsertRoleList(int branchId, RoleListViewModel obj)
{
AddDetails(branchId, obj);
return View();
}
private void AddDetails(int branchId, EmailListViewModel obj)
{
Branch branches = this._branches.GetID(branchId);
var GetDB = branches.GetClientDatabase();
RoleListViewModel listData = new RoleListViewModel();
{
listData.Name= obj.Name;
listData.Role= obj.Role;
};
List<int> lstIds = GetDB.InsertorUpadateRole(obj);
}
SqlQueries.cs
public List<int> InsertorUpadateRole (RoleList obj)
{
RoleList lstData = new RoleList();
string sqlQuery = string.Empty;
sqlQuery = #"INSERT INTO [dbo].[EmployeeRoleList]
([name],
[is_active],
[role],
[is_admin]
}
VALUES ( '{0}','1','{2}','0')
SELECT SCOPE_IDENTITY() AS id;";
try
{
this.ExecuteReader((record) =>
{
Name = Convert.ToInt32(record["name"]);
Role = Convert.ToInt32(record["role"]);
},
string.Format(sqlQuery, lstdata.Name, lstdata.Role));
}
catch (Exception e)
{
var message = e;
}
}
Can anyone help with this?

Your url usually starts with the controller, try "/Admin/InsertRoleList". Your ajax post parameters need to match the controller InsertRoleList(string Name, string Role) which is not very similar to your controller code...

Related

How can I bind a dynamic-length List<> in a Razor/.NET Core PageModel, without relying on JavaScript to re-index each input?

I have a form in which a user can supply an arbitrary-length list of <DateTime, int> pairs. It is represented like so:
List<ItemsPerDay> ItemsPerDayList = new List<ItemsPerDay>();
public class ItemsPerDay {
public DateTime Date { get; set; }
public int Amount { get; set; }
}
<tbody>
#{ var i = 0; }
#foreach (var _ in Model.ItemsPerDayList) {
<tr>
<td><input asp-for="ItemsPerDayList[i].Date" type="date" /></td>
<td><input asp-for="ItemsPerDayList[i].Amount" /></td>
<td><a class="remove">Remove</a></td>
</tr>
i++;
}
</tbody>
The issue:
The user is able to add/remove rows as they need. However, the property binding relies on the pairs being properly indexed. If, for example, you remove the first item, the list now begins at [1] and the property binding does not work; ItemsPerDayList is posted as null.
My current workaround:
I've had to use some JavaScript to make sure the indexes always remain correct. This works but isn't optimal.
function reIndexItemRows() {
$("table > tbody > tr").each(function(idx) {
$(this).find("input[type=date]").attr({
"data-val": true,
"data-val-required": "The Date field is required.",
id: `ItemsPerDayList_${idx}__Date`,
name: `ItemsPerDayList[${idx}].Date`
});
$(this).find("input[type=number]").attr({
"data-val": true,
"data-val-required": "The Amount field is required.",
id: `ItemsPerDayList_${idx}__Amount`,
name: `ItemsPerDayList[${idx}].Amount`
});
});
}
The question:
What is the appropriate way to represent this model on the front-end, such that I don't have to rely on JavaScript to groom the form each time a row is added or removed?
NOTE: I am not doing any updates, therefore the indexes are not necessary. Upon submission, any existing pairs are deleted, and the form-submitted pairs are inserted.
JavaScript is necessary for adjusting index. You can add events to adjust the index when submitting the form.
Add a event on Remove. Here is the form.
<form method="post" id="myform">
<table>
<tbody>
#{ var i = 0; }
#foreach (var _ in Model.ItemsPerDayList)
{
<tr>
<td><input asp-for="ItemsPerDayList[i].Date" type="date" /></td>
<td><input asp-for="ItemsPerDayList[i].Amount" /></td>
<td><a class="remove" onclick="remove(this)" >Remove</a></td>
</tr>
i++;
}
</tbody>
</table>
<input type="submit" name="name" value="submit" />
</form>
<button id="add" onclick="add()" class="btn-primary">add</button>
Before submitting the form, javascript iterates each row and modify the index.
#section Scripts{
<script>
$('#myform').submit(function () {
var i = 0;
$("tbody> tr ").each(function () {
$(this).find("td input[name$='Date']").attr("name", "ItemsPerDayList[" + i + "].Date");
$(this).find("td input[name$='Amount']").attr("name", "ItemsPerDayList[" + i + "].Amount");
i++
})
// ...
return true; // return false to cancel form action
});
function remove(e) {
$(e).parent().parent().remove()
}
function add() {
$('tbody').append('<tr><td> <input name="ItemsPerDayList[i].Date" type="date" /></td ><td><input name="ItemsPerDayList[i].Amount" /><td><a class="remove" onclick="remove(this)">Remove</a></td></tr>');
}
</script>
}
Then, I can get the all data from front-end.

ASP.NET without runat="server"

I have to create a simple website using asp.net web forms, but I'm required to not use any server controls i.e. runat="server"
I have the following:
HTML
<form method="post" action="">
<label for="name">Name</label>
<input id="name" name="name" type="text" />
<input value="Save" type="submit" />
</form>
Code behind
protected void myFunction()
{
// do something
}
I'm currently putting // do something in the protected void Page_Load(object sender, EventArgs e) function, but I would like to call it when the save button is clicked. However I don't know how to do this without using runat="server". Is there a way of achieving this?
The real answer to this question is in the comment:
Using webforms but saying no runat="server" is like saying go kayaking, but no paddles. It sounds more like you should be using ASP.NET MVC
I'll add ASP.Net Web Pages as well for getting things done quickly (note: this doesn't mean ASP.Net Web Pages are only for "simple" sites - you can do whatever you want with it).
I have to create a simple website using asp.net web forms
But since it "has to" be WebForms it's still doable. Is it advisable? nope - particularly with aforementioned options as well as other comments on SPA/Javascript/XHR.
End of day, it's still HTTP Requests, and Responses, so standard HTML form inputs and such work just like in any other "framework":
the "front end" (well, Page is technically a control but we're sticking to WebForms so this will be the only "server control"):NoServerControls.aspx
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="NoServerControls.aspx.cs" Inherits="WebForms.NoServerControls" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Humor Me Batman</title>
</head>
<body>
<form method="post">
<input type="text" name="wtf"/>
<input type="submit" value="Batman"/>
</form>
<h1>It's "classic ASP" Batman! <%= echo %></h1>
</body>
</html>
the "back end" (NoServerControls.aspx.cs code behind)
public partial class NoServerControls : System.Web.UI.Page
{
public string echo { get; set; }
protected void Page_Load(object sender, EventArgs e)
{
//Trivial example: skipping all validation checks
//It's either a GET or POST end of day
if (Request.RequestType == "POST")
{
//Do something with data, just echoing it here
echo = Request["wtf"];
}
}
}
Hth.
Batman :)
I have a working test project on this please refer this...
<table>
<tr>
<td>Name </td>
<td>
<input type="text" id="custid" class="form-control custname" name="fullname" required />
</td>
</tr>
<tr>
<td>Designation </td>
<td>
<select id="loading" class="form-control loading">
<option value="0">Select </option>
<option value="HR">HR </option>
<option value="Engg">Engg </option>
<option value="Doctor">Doctor </option>
</select>
</td>
</tr>
<tr>
<td>Mobile No. </td>
<td>
<input type="text" id="mobile" class="form-control mobile" onkeypress="return event.charCode >=48 && event.charCode <= 57" name="fullname" required />
</td>
</tr>
<tr>
<td>Email Id </td>
<td>
<input type="text" id="emailid" class="form-control emailid" name="fullname" required />
</td>
</tr>
<tr>
<td colspan="2" id="btn">
<button type="button" onsubmit="return validateForm()" class="btn btn-primary">Save</button>
</td>
</tr>
</table>
<script>
$(document).ready(function () {
$('#btn').click(function () {
var CustNamevalidate = $('.custname').val();
if (CustNamevalidate != '') {
Name = $(".custname").val();
Loading = $(".loading").val();
Mobile = $(".mobile").val();
EmailId = $(".emailid").val();
$.ajax({
type: "POST",
url: "test.aspx/Complextype",
data: JSON.stringify({
Nam: Name, Loadin: Loading, Mobil: Mobile, EmailI: EmailId
}),
contentType: "application/json; charset=utf-8",
datatype: "json"
}).done(function (result) {
console.log(result);
alert(JSON.stringify(result));
})
}
else {
alert('Please Enter Customer Name');
}
});
});
</script>
Code Behind WEB MEthod
[WebMethod]
public static string Complextype(string Nam, string Loadin, string Mobil, string EmailI)
{
string Qtets = "Details are : Name =" + Nam + " And Designation is =" + Loadin + " And Mobileno=" + Mobil + " And EmailI=" + EmailI;
// ScriptManager.RegisterStartupScript(Page, typeof(Page), "test", "<script>alert('Sorry This Category Name Already Exist.');</script>", false);
using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["Constr"].ConnectionString))
{
SqlCommand cmd = new SqlCommand("usp_add_upd_emptb", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#EmpName", Nam);
cmd.Parameters.AddWithValue("#EmpNo", Mobil);
cmd.Parameters.AddWithValue("#Desig", Loadin);
cmd.Parameters.AddWithValue("#Email", EmailI);
cmd.Parameters.AddWithValue("#id", 0);
con.Open();
cmd.ExecuteNonQuery();
if (con.State == ConnectionState.Open)
{
con.Close();
}
else
{
con.Open();
}
}
//SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["Constr"].ConnectionString);
//{
//}
return Qtets;
}
you Can not call Function Directly if you are not using server controls for function to be called you need to have Web service with static function.

Using jQuery to get multiple checkbox's value and Multiple Delete Using jquery json

I have already bind a html table using jQuery json.
I want to get multiple checkbox value using jQuery json and delete by selected multiple delete method.
This is my code for bind the table.
$(function () {
debugger
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "WebForm5.aspx/BindDatatable",
data: "{}",
dataType: "json",
success: function (dt) {
debugger;
for (var i = 0; i < dt.d.length; i++) {
$("#example1 > tbody").append("<tr><td> <input type='checkbox' /></td><td>" + dt.d[i].CategoryID + "</td><td>" + dt.d[i].Name + "</td><td>" + dt.d[i].Status + "</td><td> <button type='submit'>Submit</button><button type='submit' onclick='deleteRecord(" + dt.d[i].CategoryID + ")'>Delete</button> </tr>");
}
$("#example1").DataTable();
},
error: function (result) {
alert("Error");
}
});
});
This is my Button to Delete selected(multiple delete):
<button type="button" name="deletebtn" id="deletebtn">Delete Selected</button>
This is my html table:
<div class="box-body">
<button type="button" name="deletebtn" id="deletebtn">Delete Selected</button>
<table id="example1" class="table table-bordered table-striped">
<thead>
<tr>
<th>Check Box</th>
<th>Category Name</th>
<th>Category Details</th>
<th>Status</th>
<th>Action</th>
</tr>
</thead>
<tbody id="myBody">
</tbody>
</table>
</div>
You just tell me :
1.what is the code to select all the checkbox??
2.Code to delete using multiple jquery??
The Server side Code is here For Single Delete(with out checkbox):
[WebMethod]
public static void deleteRecord(int Id)
{
clsCategoryBL objproject = new clsCategoryBL();
objproject.CategoryDelete(Id);
}
In BL:
public string CategoryDelete(int CategoryID)
{
using (KSoftEntities db = new KSoftEntities())
{
try
{
var categoryDetails = db.tblCategories.Where(i => i.CategoryID == CategoryID).SingleOrDefault();
db.tblCategories.Remove(categoryDetails);
db.SaveChanges();
return "Record deleted successfully";
}
catch (Exception ex)
{
}
return "Error on deletion";
}
}
The Delete is Occur on the Client Side by Using This code:
$().ready(function () {
$('body').on('click', '#deletebtn', function () {
debugger;
$("#example1 tr").each(function () {
var rowSelector = $(this);
if (rowSelector.find("input[type='checkbox']").prop('checked')) {
rowSelector.remove();
}
});
});
});
The Code For Bind The Table:
enter code here
protected void Page_Load(object sender, EventArgs e)
{
if (Session["adminuser"] == null)
Response.Redirect("Default.aspx");
if (!IsPostBack)
{
// Page.Title = "Category Details";
BindDatatable();
}
}
[WebMethod]
public static UserDetails[] BindDatatable()
{
clsCategoryBL objcategory = new clsCategoryBL();
List<UserDetails> details = new List<UserDetails>();
DataTable dt = new DataTable();
//var categories= clsCategoryBL.GetAllCategoryDetails("admin");
dt = objcategory.GetAllCategoryDetails("admin");
if (dt.Rows.Count > 0)
{
foreach (DataRow dtrow in dt.Rows)
{
UserDetails user = new UserDetails();
user.CategoryID = dtrow["CategoryID"].ToString();
user.Name = dtrow["Name"].ToString();
user.Status = dtrow["Status"].ToString();
details.Add(user);
}
//literal1.Text = html.ToString();
}
return details.ToArray();
}
public class UserDetails
{
public string CategoryID { get; set; }
public string Name { get; set; }
public string Status { get; set; }
}
I want To delete it on server Side that means also on my database(Sql)
So what should i do???
I Want To Delete Multiple Row By Click On Multiple CheckBox On Database Also..I have mention in above the backend code also..I want to delete the row of html table by click 2 to 3 checkbox(it may be vary depend upon the data) and click Delete Selected button..
The Table structure after pressing f12:
enter code here
<table id="example1" class="table table-bordered table-striped dataTable no-footer" role="grid" aria-describedby="example1_info">
<thead>
<tr role="row"><th class="sorting_asc" tabindex="0" aria-controls="example1" rowspan="1" colspan="1" aria-sort="ascending" aria-label="Check Box: activate to sort column descending" style="width: 204px;">Check Box</th><th class="sorting" tabindex="0" aria-controls="example1" rowspan="1" colspan="1" aria-label="Category Name: activate to sort column ascending" style="width: 276px;">Category Name</th><th class="sorting" tabindex="0" aria-controls="example1" rowspan="1" colspan="1" aria-label="Category Details: activate to sort column ascending" style="width: 293px;">Category Details</th><th class="sorting" tabindex="0" aria-controls="example1" rowspan="1" colspan="1" aria-label="Status: activate to sort column ascending" style="width: 148px;">Status</th><th class="sorting" tabindex="0" aria-controls="example1" rowspan="1" colspan="1" aria-label="Action: activate to sort column ascending" style="width: 211px;">Action</th></tr>
</thead>
<tbody id="myBody">
<tr role="row" class="odd"><td class="sorting_1"> <input type="checkbox"></td><td>42</td><td>xyz</td><td>True</td><td> <button type="submit">Submit</button><button type="submit" onclick="deleteRecord(42)">Delete</button> </td></tr><tr role="row" class="even"><td class="sorting_1"> <input type="checkbox"></td><td>33</td><td>Advertising</td><td>True</td><td> <button type="submit">Submit</button><button type="submit" onclick="deleteRecord(33)">Delete</button> </td></tr><tr role="row" class="odd"><td class="sorting_1"> <input type="checkbox"></td><td>31</td><td>Travel & Hospitality</td><td>True</td><td> <button type="submit">Submit</button><button type="submit" onclick="deleteRecord(31)">Delete</button> </td></tr></tbody>
</table>
Assuming there is only one checkbox in a row, you could simply iterate through the rows and post to your existing [WebMethod]
Using the second column as the ID (EDIT):
$().ready(function () {
$('body').on('click', '#deletebtn', function () {
$("#example1 tr").each(function () {
var rowSelector = $(this);
if (rowSelector.find("input[type='checkbox']").prop('checked'))
{
//THE MARKUP SHOWING THE ID IS NOT AVAILABLE
//POST A TABLE ENTRY TO CLEAR UP
var id = rowSelector.find('td').first().next().html();
var sendObj = {Id : id};
//USE JSON OBJECT
$.ajax({
url : "/page.aspx/deleteRecord",//CHANGE TO YOUR URL
dataType: "json",
data: sendObj,
type: "POST",
success: function () {
alert("entry deleted");
}
});
rowSelector.remove();
}
});
});
});
Explanation
Using JQuery you simply iterate through each row and look for the checkbox value. Note you will iterate through the header as well, so if there is a checkbox there you must add logic to skip the first iteration.
EDIT 3: You will also post the ID to the server if the checkbox is checked. Important to note that you would rather post a single bulk array of ID's instead of multiple single posts, but that method has not been exposed or posted here.
Good Luck
CODE SNIPPET (CLIENT SIDE ONLY)
$().ready(function () {
$('body').on('click', '#deletebtn', function () {
$("#example1 tr").each(function () {
var rowSelector = $(this);
if (rowSelector.find("input[type='checkbox']").prop('checked'))
{
rowSelector.remove();
}
});
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<button id='deletebtn'>DELETE</button>
<table id='example1'>
<thead>
<tr>
<th>CHECKBOX</th>
<th>NAME</th>
<th>DESCRIPTION</th>
</tr>
</thead>
<tbody>
<tr>
<td><input type='checkbox' value='check' /></td>
<td>the name</td>
<td>the description</td>
</tr>
<tr>
<td><input type='checkbox' value='check' /></td>
<td>the name</td>
<td>the description</td>
</tr>
<tr>
<td><input type='checkbox' value='check' /></td>
<td>the name</td>
<td>the description</td>
</tr>
</tbody>
</table>
</div>
A easier method will be if you give a class to all the check-boxes in your form and then on button click you simply iterate through all the check-boxes using the class, and therby seralizing their values.
var values = $("#Myform").find(".CheckBoxClass").serialize();
here the variable value will contain the values of all the checkboxes in your form and you can send them using ajax on your server to perform further action.
You can use something like below mentioned.
$("example1 input:checkbox").prop('checked',this.checked);
Or it is answered already in below post
jquery set all checkbox checked

Place model image in MVC view

I am trying to display an image stored in the database (actually a varbinary) and trying to display it in a "img" tag. Simple View:
<table style="font-size:x-small">
#Html.HiddenFor(x=>x.CandidateId, new { #id = "txtCandidateId"})
<tr>
<td>
#Html.DisplayNameFor(x=>x.Name)
</td>
<td>
#Html.DisplayTextFor(x=>x.Name)
</td>
<td>
AD Account User Name:
</td>
<td>
<input type="text" id="txtUsername" />
</td>
</tr>
<tr>
<td colspan="4">
<img id="img" src="" alt="" />
</td>
</tr>
</table>
Then in script:
var cand;
$(document).ready(function () {
debugger;
cand = function () { return #Html.Raw(Json.Encode(Model)) }();
var source = "/InProcess/RetrieveImage/" + cand.CandidateId;
$("#img").attr("src", source);
});
Then in controller:
public ActionResult RetrieveImage(string candidate)
{
byte[] pdf;
using (var memStream = new MemoryStream())
{
Repository.GetCandidatePdf(candidate).CopyTo(memStream);
pdf = memStream.ToArray();
}
if (pdf != null)
{
return File(pdf, "cover/jpg");
}
else
return null;
}
I can see the correct id, which is a uniqueidentifer, in the JS of the page and the action is getting called but the candidateId is null. Anybody have any ideas why? Is there a better way to do this?
By default, the route parameters in ASP.NET MVC are {controller}, {action}, and {id} - controller and action are handled for you, and id needs to be the name of the action paramemter:
public ActionResult RetrieveImage(String id) {
...
}
Also your Content-Type is incorrect, it should be image/jpeg if you're returning a JPEG image, or application/pdf if you're returning an Adobe PDF document. However you cannot load a PDF into an <img /> element.

How to pass data from view to controller in ASP.NET MVC? [duplicate]

I'm developing an ASP.NET MVC 5 web with C# and .NET Framework 4.5.1.
I have this form in a cshtml file:
#model MyProduct.Web.API.Models.ConnectBatchProductViewModel
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Create</title>
</head>
<body>
#if (#Model != null)
{
<h4>Producto: #Model.Product.ProductCode, Cantidad: #Model.ExternalCodesForThisProduct</h4>
using (Html.BeginForm("Save", "ConnectBatchProduct", FormMethod.Post))
{
#Html.HiddenFor(model => model.Product.Id, new { #id = "productId", #Name = "productId" });
<div>
<table id ="batchTable" class="order-list">
<thead>
<tr>
<td>Cantidad</td>
<td>Lote</td>
</tr>
</thead>
<tbody>
<tr>
<td>#Html.TextBox("ConnectBatchProductViewModel.BatchProducts[0].Quantity")</td>
<td>#Html.TextBox("ConnectBatchProductViewModel.BatchProducts[0].BatchName")</td>
<td><a class="deleteRow"></a></td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="5" style="text-align: left;">
<input type="button" id="addrow" value="Add Row" />
</td>
</tr>
</tfoot>
</table>
</div>
<p><input type="submit" value="Seleccionar" /></p>
}
}
else
{
<div>Error.</div>
}
<script src="~/Scripts/jquery-2.1.3.min.js"></script>
<script src="~/js/createBatches.js"></script> <!-- Resource jQuery -->
</body>
</html>
And this is the action method:
[HttpPost]
public ActionResult Save(FormCollection form)
{
return null;
}
And the two ViewModel:
public class BatchProductViewModel
{
public int Quantity { get; set; }
public string BatchName { get; set; }
}
public class ConnectBatchProductViewModel
{
public Models.Products Product { get; set; }
public int ExternalCodesForThisProduct { get; set; }
public IEnumerable<BatchProductViewModel> BatchProducts { get; set; }
}
But I get this in FormCollection form var:
But I want to get an IEnumerable<BatchProductViewModel> model:
public ActionResult Save(int productId, IEnumerable<BatchProductViewModel> model);
If I use the above method signature both parameters are null.
I want an IEnumerable because user is going to add more rows dynamically using jQuery.
This is jQuery script:
jQuery(document).ready(function ($) {
var counter = 0;
$("#addrow").on("click", function () {
counter = $('#batchTable tr').length - 2;
var newRow = $("<tr>");
var cols = "";
var quantity = 'ConnectBatchProductViewModel.BatchProducts[0].Quantity'.replace(/\[.{1}\]/, '[' + counter + ']');
var batchName = 'ConnectBatchProductViewModel.BatchProducts[0].BatchName'.replace(/\[.{1}\]/, '[' + counter + ']');
cols += '<td><input type="text" name="' + quantity + '"/></td>';
cols += '<td><input type="text" name="' + batchName + '"/></td>';
cols += '<td><input type="button" class="ibtnDel" value="Delete"></td>';
newRow.append(cols);
$("table.order-list").append(newRow);
counter++;
});
$("table.order-list").on("click", ".ibtnDel", function (event) {
$(this).closest("tr").remove();
counter -= 1
$('#addrow').attr('disabled', false).prop('value', "Add Row");
});
});
Any idea?
I have checked this SO answer, and this article but I don't get my code working.
You need to generate the controls for the collection in a for loop so they are correctly named with indexers (note that property BatchProducts needs to be IList<BatchProductViewModel>
#using (Html.BeginForm("Save", "ConnectBatchProduct", FormMethod.Post))
{
....
<table>
....
#for(int i = 0; i < Model.BatchProducts.Count; i++)
{
<tr>
<td>#Html.TextBoxFor(m => m.BatchProducts[i].Quantity)</td>
<td>#Html.TextBoxFor(m => m.BatchProducts[i].BatchName)</td>
<td>
// add the following to allow for dynamically deleting items in the view
<input type="hidden" name="BatchProducts.Index" value="#i" />
<a class="deleteRow"></a>
</td>
</tr>
}
....
</table>
....
}
Then the POST method needs to be
public ActionResult Save(ConnectBatchProductViewModel model)
{
....
}
Edit
Note: Further to your edit, if you want to dynamically add and remove BatchProductViewModel items in he view, you will need to use the BeginCollectionItem helper or a html template as discussed in this answer
The template to dynamically add new items would be
<div id="NewBatchProduct" style="display:none">
<tr>
<td><input type="text" name="BatchProducts[#].Quantity" value /></td>
<td><input type="text" name="BatchProducts[#].BatchName" value /></td>
<td>
<input type="hidden" name="BatchProducts.Index" value ="%"/>
<a class="deleteRow"></a>
</td>
</tr>
</div>
Note the dummy indexers and the non-matching value for the hidden input prevents this template posting back.
Then the script to add a new BatchProducts would be
$("#addrow").click(function() {
var index = (new Date()).getTime(); // unique indexer
var clone = $('#NewBatchProduct').clone(); // clone the BatchProducts item
// Update the index of the clone
clone.html($(clone).html().replace(/\[#\]/g, '[' + index + ']'));
clone.html($(clone).html().replace(/"%"/g, '"' + index + '"'));
$("table.order-list").append(clone.html());
});
In your Post Methode you receive "MyProduct.Web.API.Models.ConnectBatchProductViewModel" as Parameter.
Use the existing model for the Post methode.
Why do you want a IEnumerable from your model? there is only one available including the id in the model.
you can visit this article for complete source code with a video tutorial.
you have to create an action first, from where we can pass the list of object
[HttpGet]
public ActionResult Index()
{
List<Contact> model = new List<Contact>();
using (MyDatabaseEntities dc = new MyDatabaseEntities())
{
model = dc.Contacts.ToList();
}
return View(model);
}
then we need to create a view for that action
#model List<UpdateMultiRecord.Contact>
#{
ViewBag.Title = "Update multiple row at once Using MVC 4 and EF ";
}
#using (#Html.BeginForm("Index","Home", FormMethod.Post))
{
<table>
<tr>
<th></th>
<th>Contact Person</th>
<th>Contact No</th>
<th>Email ID</th>
</tr>
#for (int i = 0; i < Model.Count; i++)
{
<tr>
<td> #Html.HiddenFor(model => model[i].ContactID)</td>
<td>#Html.EditorFor(model => model[i].ContactPerson)</td>
<td>#Html.EditorFor(model => model[i].Contactno)</td>
<td>#Html.EditorFor(model => model[i].EmailID)</td>
</tr>
}
</table>
<p><input type="submit" value="Save" /></p>
<p style="color:green; font-size:12px;">
#ViewBag.Message
</p>
}
#section Scripts{
#Scripts.Render("~/bundles/jqueryval")
}
and then we have to write code for save the list of object to the database
[HttpPost]
public ActionResult Index(List<Contact> list)
{
if (ModelState.IsValid)
{
using (MyDatabaseEntities dc = new MyDatabaseEntities())
{
foreach (var i in list)
{
var c = dc.Contacts.Where(a =>a.ContactID.Equals(i.ContactID)).FirstOrDefault();
if (c != null)
{
c.ContactPerson = i.ContactPerson;
c.Contactno = i.Contactno;
c.EmailID = i.EmailID;
}
}
dc.SaveChanges();
}
ViewBag.Message = "Successfully Updated.";
return View(list);
}
else
{
ViewBag.Message = "Failed ! Please try again.";
return View(list);
}
}
using(Html.BeginForm())
{
// code here
}
While to Post form Data all tags must be included form tag.
Following the principle of DRY, you can create one EditorTemplate for that purpose.
Steps:
1- In Views > Shared > Create new folder named (EditorTemplates)
2- Create a view inside your newly created EditorTemplates folder , the view's model should be BatchProductViewModel according to the OP example. Place your code inside the Editor view. No loop or index is required.
An EditorTemplate will act similar to a PartialView for every child entity but in a more generic way.
3- In your parent entity's view, call your Editor :
#Html.EditorFor(m => m.BatchProducts)
Not only this provides a more organized views, but also let's you re-use the same editor in other views as well.

Categories

Resources