Dynamically add rows in ASP.NET MVC table form - c#

I'm trying to program an "add" button below an ASP.NET MVC table to dynamically append a blank row, and then have a submit button to save each row to the database with one click.
There are several similar questions on SO but none that I have been able to apply to this. I've been trying to apply this example but the "add" button is not appending new rows.
Model:
public class TableForm
{
public int Id { get; set; }
public List<TableFormData> TableFormDatas { get; set; }
}
public class TableFormData
{
public int Id { get; set; }
public string ClientSampleID { get; set; }
public string AdditionalComments { get; set; }
public string AcidStables { get; set; }
Razor view:
#model NewTestSix.Models.TableForm
#{
ViewData["Title"] = "Create";
Layout = "~/Views/Shared/_Layout.cshtml";
}
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<fieldset>
<legend>Sample submission</legend>
<table id="submissionTable" class="table table-bordered">
<thead>
<tr>
<td>Sample ID</td>
<td>Additional Comments</td>
<td>Acid-stable amino acids</td>
</tr>
</thead>
<tr id="tablerow0">
<td>
<div class="editor-field">
<input class="text-box single-line" name="ClientSampleID[0]" type="text" value="" required="required" />
</div>
</td>
<td>
<div class="editor-field">
<input class="text-box single-line" name="AdditionalComments[0]" type="text" value="" required="required" />
</div>
</td>
<td>
<div class="editor-field">
<input class="text-box single-line" name="AcidStables[0]" type="text" value="" />
</div>
</td>
<td>
<button type="button" class="btn btn-primary" onclick="removeTr(0);">Delete</button>
</td>
<td>
</td>
</tr>
</table>
<p>
<button id="add" type="submit" class="btn btn-primary">Add</button>
</p>
<hr />
<p>
<input type="submit" value="Create" class="btn btn-default" />
</p>
</fieldset>
}
#section Scripts {
<script src="~/bundles/jqueryval.js" type="text/javascript">
var counter = 1;
$(function () {
$('#add').click(function () {
$('<tr id="tablerow' + counter + '"><td>' +
'<input type="text" class="text-box single-line" name="ClientSampleID[' + counter + ']" value="" required="required" />' +
'</td>' +
'<td>' +
'<input type="text" class="text-box single-line" name="AdditionalComments[' + counter + ']" value="" required="required" />' +
'</td>' +
'<td>' +
'<input type="text" class="text-box single-line" name="AcidStables[' + counter + ']" value="" required="required" />' +
'</td>' +
'<td>' +
'<button type="button" class="btn btn-primary" onclick="removeTr(' + counter + ');">Delete</button>' +
'</td>' +
'</tr>').appendTo('#submissionTable');
counter++;
return false;
});
});
function removeTr(index) {
if (counter > 1) {
$('#tablerow' + index).remove();
counter--;
}
return false;
}
</script>
I'm not too fussed about model binding with the controller at this stage, I just want to get this add button working. example controller:
[HttpPost]
public ActionResult Index(string any = "")
{
IList<TableForm> _TableForm = new List<TableForm>();
//Loop through the forms
for (int i = 0; i <= Request.Form.Count; i++)
{
var ClientSampleID = Request.Form["ClientSampleID[" + i + "]"];
var additionalComments = Request.Form["AdditionalComments[" + i + "]"];
var acidStables = Request.Form["AcidStables[" + i + "]"];
if (!String.IsNullOrEmpty(ClientSampleID))
{
_TableForm.Add(new TableForm { ClientSampleID = ClientSampleID, AcidStables = acidStables, AdditionalComments = additionalComments });
}
}
return View();
}
Thanks for any insights.
Current:
Desired after clicking "add" button:

Change your
<button id="add" type="submit" class="btn btn-primary">Add</button>
into
<button id="add" type="button" class="btn btn-primary">Add</button>
...as I don't think the "Add" button should ever make the browser do a form submission when clicked, it should only invoke your button's client-side 'click' event-handler.
Then remove src="~/bundles/jqueryval.js" part from your script element's opening tag: inline scripts cannot have a src="" attribute.
Like this:
<script type="text/javascript">
var counter = 1;
//... the rest of your code is here...
</script>
If you actually have a jqueryval.js file, put it in another <script> tag.
Here is the result you are expecting if I'm not mistaken.
var counter = 1;
$(function () {
$('#add').click(function () {
$('<tr id="tablerow' + counter + '"><td>' +
'<input type="text" class="text-box single-line" name="ClientSampleID[' + counter + ']" value="" required="required" />' +
'</td>' +
'<td>' +
'<input type="text" class="text-box single-line" name="AdditionalComments[' + counter + ']" value="" required="required" />' +
'</td>' +
'<td>' +
'<input type="text" class="text-box single-line" name="AcidStables[' + counter + ']" value="" required="required" />' +
'</td>' +
'<td>' +
'<button type="button" class="btn btn-primary" onclick="removeTr(' + counter + ');">Delete</button>' +
'</td>' +
'</tr>').appendTo('#submissionTable');
counter++;
return false;
});
});
function removeTr(index) {
if (counter > 1) {
$('#tablerow' + index).remove();
counter--;
}
return false;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<fieldset>
<legend>Sample submission</legend>
<table id="submissionTable" class="table table-bordered">
<thead>
<tr>
<td>Sample ID</td>
<td>Additional Comments</td>
<td>Acid-stable amino acids</td>
</tr>
</thead>
<tr id="tablerow0">
<td>
<div class="editor-field">
<input class="text-box single-line" name="ClientSampleID[0]" type="text" value="" required="required" />
</div>
</td>
<td>
<div class="editor-field">
<input class="text-box single-line" name="AdditionalComments[0]" type="text" value="" required="required" />
</div>
</td>
<td>
<div class="editor-field">
<input class="text-box single-line" name="AcidStables[0]" type="text" value="" />
</div>
</td>
<td>
<button type="button" class="btn btn-primary" onclick="removeTr(0);">Delete</button>
</td>
<td></td>
</tr>
</table>
<p>
<button id="add" type="button" class="btn btn-primary">Add</button>
</p>
<hr />
<p>
<input type="submit" value="Create" class="btn btn-default" />
</p>
</fieldset>
Let me know if it helps.

You can used jQuery jqGrid
It is jquery plugin which is free and open source. This is completely
Ajax enabled to display tabular data and to manipulate. Additionally,
we can apply different Jquery UI theme, see the demo.
Action Method: There is nothing here since we will be getting product details using Ajax in json format.
public ActionResult GetProducts(string sidx, string sord, int page, int rows)
{
var products = Product.GetSampleProducts();
int pageIndex = Convert.ToInt32(page) - 1;
int pageSize = rows;
int totalRecords = products.Count();
int totalPages = (int)Math.Ceiling((float)totalRecords / (float)pageSize);
var data = products.OrderBy(x => x.Id)
.Skip(pageSize * (page - 1))
.Take(pageSize).ToList();
var jsonData = new
{
total = totalPages,
page = page,
records = totalRecords,
rows = data
};
return Json(jsonData, JsonRequestBehavior.AllowGet);
}
And add this tag to target page
<table id="jqGrid"></table>
<div id="jqGridPager"></div>
After that in script section add this:
<script>
var myGrid = $('#jqGrid');
myGrid.jqGrid({
url: '/Home/GetProducts/',
datatype: "json",
contentType: "application/json; charset-utf-8",
mtype: 'GET',
colNames: ['ProductID', 'Name', 'Price', 'Department', 'Action'],
colModel: [
{ name: 'Id', key: true, width: 75 },
{ name: 'Name', key: true, width: 200 },
{ name: 'Price', key: true, width: 75 },
{ name: 'Department', key: true, width: 200 },
{ name: 'Edit', key: true, width: 100, editable: true, formatter: editButton }
],
rowNum: 4,
pager: '#jqGridPager',
gridview: true,
rownumbers: true,
pagerpos: 'center'
});
</script>
Original post is here

var counter = 2;
$(function () {
$('#add').click(function () {
$('<tr id="tablerow' + counter + '"><td>' +
'<input type="text" class="text-box single-line" name="ClientSampleID[' + counter + ']" value="" required="required" />' +
'</td>' +
'<td>' +
'<input type="text" class="text-box single-line" name="AdditionalComments[' + counter + ']" value="" required="required" />' +
'</td>' +
'<td>' +
'<input type="text" class="text-box single-line" name="AcidStables[' + counter + ']" value="" required="required" />' +
'</td>' +
'<td>' +
'<button type="button" class="btn btn-primary" onclick="removeTr(' + counter + ');">Delete</button>' +
'</td>' +
'</tr>').appendTo('#submissionTable');
counter++;
return false;
});
});
function removeTr(index) {
if (counter > 1) {
$('#tablerow' + index).remove();
counter--;
}
return false;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<fieldset>
<legend>Sample submission</legend>
<table id="submissionTable" class="table table-bordered">
<thead>
<tr>
<td>Sample ID</td>
<td>Additional Comments</td>
<td>Acid-stable amino acids</td>
</tr>
</thead>
<tr id="tablerow0">
<td>
<div class="editor-field">
<input class="text-box single-line" name="ClientSampleID[0]" type="text" value="" required="required" />
</div>
</td>
<td>
<div class="editor-field">
<input class="text-box single-line" name="AdditionalComments[0]" type="text" value="" required="required" />
</div>
</td>
<td>
<div class="editor-field">
<input class="text-box single-line" name="AcidStables[0]" type="text" value="" />
</div>
</td>
<td>
<button type="button" class="btn btn-primary" onclick="removeTr(0);">Delete</button>
</td>
<td></td>
</tr>
</table>
<p>
<button id="add" type="button" class="btn btn-primary">Add</button>
</p>
<hr />
<p>
<input type="submit" value="Create" class="btn btn-default" />
</p>
</fieldset>

Related

ASP Core model binding not working after adding some elements by AJAX

I added some html elements (drop-downs) by using AJAX. After that, when I want to bind their inputs to my DTO(CreateSmsPattern) via submitting my form, seems not be bind correctly.
JQuery code:
$.ajax({
url: '/api/SmsPattern/GetSmsPatternParameterPersianName',
beforeSend: function (xhr) {
xhr.setRequestHeader("XSRF-TOKEN",
$('input:hidden[name="__RequestVerificationToken"]').val());
},
contentType: false,
processData: false,
type: 'GET',
success: function (resp) {
if (resp != null) {
var options = "";
var json = JSON.parse(resp);
options += '<option value="0">انتخاب متغیر...</option>';
for (var i in json) {
var subJson = json[i];
var name = subJson.Name;
var id = subJson.Id;
options += '<option value="' + id + '">' + name + '</option>'
}
var first = $('#smsPatternParametersList').firstElementChild;
while (first) {
first.remove();
first = e.firstElementChild;
}
for (var i = 0; i < count; i++) {
$('#smsPatternParametersList').append(
`<select class="form-control" asp-for="Command.Parameter` + i + `">` + options + `</select>
<span asp-validation-for="Command.Parameter` + i + `" class="error"></span>
`);
}
}
}
});
My form (count of drop-downs depends on number that user types in input element id=smsPatternParametersCount):
<form method="post">
<div class="row">
<div class="col-md-4">
<div class="form-group">
<label asp-for="Command.Name" class="control-label">عنوان</label>
<input type="text" class="form-control" asp-for="Command.Name">
<span asp-validation-for="Command.Name" class="error"></span>
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label class="control-label" asp-for="Command.SpecialListId">فهرست ویژه</label>
<select class="form-control" asp-for="Command.SpecialListId" asp-items='new SelectList(Model.SmsSpecialLists, "Id", "Name")'>
<option value="0">انتخاب فهرست ویژه...</option>
</select>
<span asp-validation-for="Command.SpecialListId" class="error"></span>
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label asp-for="Command.ParametersCount" class="control-label">تعداد متغیرها</label>
<input type="number" id="smsPatternParametersCount" class="form-control" asp-for="Command.ParametersCount" min="1">
<span asp-validation-for="Command.ParametersCount" class="error"></span>
</div>
</div>
</div>
<div class="row">
<div class="col-md-4">
<div class="form-group no-margin">
<label asp-for="Command.Message" class="control-label">متن همراه با متغیرها</label>
<textarea class="form-control" asp-for="Command.Message"
style="overflow: hidden; word-wrap: break-word; resize:none" rows="5"></textarea>
<span asp-validation-for="Command.Message" class="error"></span>
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label class="control-label">فهرست متغیرها</label>
<div id="smsPatternParametersList">
</div>
</div>
</div>
</div>
<a asp-page="Index" class="btn btn-dark m-b-5">بازگشت</a>
<button permission="#(int)SmsPermissions.SmsPattern.Create" type="submit" class="btn btn-info">ایجاد</button>
</form>
and back-end screenshot (هیچکدام means 'none'):
screenshot
I solved this problem. Just changed below part of jquery code:
$('#smsPatternParametersList').append(
`<select class="form-control" asp-for="Command.Parameter` + i + `">` + options + `</select>
<span asp-validation-for="Command.Parameter` + i + `" class="error"></span>
`);
to
$('#SmsPatternParametersList').append(
`<select class="form-control" id="Command_Parameter` + i + `" name="Command.Parameter` + i + `">` + options + `</select>
<span data-valmsg-replace="true" data-valmsg-for="Command.Parameter` + i + `" class="error field-validation-valid"></span>
`);
Seems when Ajax is fullfilling html, ASP.NET tag helper (ex. 'asp-for' or 'asp-validation-for') is not working at all. Thus, I used native html attributes.

Checkbox always show False either it is True

I am try to understand what happened with checkbox status. So I have Create Page where I insert Patient
and when I click Emergency to True in Index Page I always get False
IndexPage.cshtml
#if (Model.Count() > 0)
{
<table class="table table-bordered table-striped" style="width:100%">
<thead>
<tr>
<th>
Doctor Full Name - CODE
</th>
<th>
Patient Full Name
</th>
<th>
Date and Time
</th>
<th>
Emergency
</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var obj in Model)
{
<tr>
<td width="25%">#obj.Doctor.Firstname #obj.Doctor.Lastname #obj.Doctor.Code</td>
<td width="25%">#obj.Patient.FirstName #obj.Patient.LastName</td>
<td width="25%">#obj.DateAndTime</td>
<td width="25%" class="blink_me">#obj.Emergency</td>
<td class="text-center">
<div class="w-75 btn-group" role="group">
<a asp-route-Id="#obj.Id" asp-action="Upsert" class="btn btn-primary mx-2">
<i class="fas fa-edit"></i>
</a>
<a asp-route-Id="#obj.Id" asp-action="Delete" class="btn btn-danger mx-2">
<i class="far fa-trash-alt"></i>
</a>
</div>
</td>
</tr>
}
</tbody>
</table>
}
else
{
<p> No Admission Patient exists.</p>
}
Create
#model BergClinics.Models.ViewModel.AdmisionVM
#{
ViewData["Title"] = "Upsert";
var title = "Create Admission Patient";
}
<form method="post" enctype="multipart/form-data">
#if (Model.AdmissionPatient.Id != 0)
{
<input asp-for="AdmissionPatient.Id" hidden />
title = "Edit Admission Patient";
}
<div class="border p-3">
<div class="form-group row">
<h2 class="text-info pl-3">#title</h2>
</div>
<div class="row">
<div class="col-8">
<div class="form-group row py-2">
<div class="col-4">
<label>Doctor Full Name : </label>
</div>
<div class="col-8">
<select asp-for="AdmissionPatient.DoctorId" asp-items="#Model.DoctorSelectList" class="form-control">
<option disabled selected>--Select Docotor--</option>
</select>
</div>
</div>
<div class="form-group row py-2">
<div class="col-4">
<label>Patient Full Name: </label>
</div>
<div class="col-8">
<select asp-for="AdmissionPatient.PatientId" asp-items="#Model.PatientSelectList" class="form-control">
<option disabled selected>--Select Patient--</option>
</select>
</div>
</div>
<div class="form-group row py-2">
<div class="col-4">
<label>Date and Time :</label>
</div>
<div class="col-8">
<input asp-for="AdmissionPatient.DateAndTime" asp-format="{0:dd/MM/yyyy}" type="text" name="date" class="form-control datepicker" autocomplete="off">
</div>
</div>
<div class="form-group row py-2">
<div class="col-4">
<label>Patient Image :</label>
</div>
<div class="col-3">
<input type="file" name="files" id="imageBox" multiple class="form-control" />
</div>
</div>
<div class="form-group row py-2">
<div class="col-4">
<label>Emergency reception :</label>
</div>
<div class="col-8">
<input type="checkbox" class="form-control" id="emergencyId">
<label class="form-check-label" for="exampleCheck1"></label>
</div>
</div>
<div class="form-group row py-2">
<div class="col-8 offset-4 row">
<div class="col">
#if (Model.AdmissionPatient.Id != 0)
{
//update
<input type="submit" class="btn btn-info w-100" value="Update" />
}
else
{
//create
<input type="submit" onclick="return validateInput()" class="btn btn-primary w-100" value="Create" />
}
</div>
</div>
</div>
</div>
<div class="col-4">
#if (Model.AdmissionPatient.Id != 0)
{
<img src="#Constans.imagePath#Model.AdmissionPatient.Image" width="100%" style="border-radius:5px; border:1px solid #bbb" />
}
</div>
</div>
</div>
</form>
#section Scripts{
#{
<partial name="_ValidationScriptsPartial" />
}
<script>
function validateInput() {
if (document.getElementById("imageBox").value == "") {
Swal.fire(
'Error!',
'Please upload an Image!',
'error'
)
return false;
}
return true;
}
</script>
<script>
$('.datepicker').datepicker({
startDate: new Date()
});
</script>
}
Controller Post Action
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Upsert(AdmisionVM admissionVM)
{
if (ModelState.IsValid)
{
var files = HttpContext.Request.Form.Files;
string webRootPath = _webHostEnvironment.WebRootPath;
if (admissionVM.AdmissionPatient.Id == 0)
{
//Creating
string upload = webRootPath + Constans.imagePath;
string fileName = Guid.NewGuid().ToString();
string extension = Path.GetExtension(files[0].FileName);
using (var fileStream = new FileStream(Path.Combine(upload, fileName + extension), FileMode.Create))
{
files[0].CopyTo(fileStream);
}
admissionVM.AdmissionPatient.Image = fileName + extension;
_db.AdmissionPacients.Add(admissionVM.AdmissionPatient);
}
else
{
//Updating
var objFromDb = _db.AdmissionPacients.AsNoTracking().FirstOrDefault(u => u.Id == admissionVM.AdmissionPatient.Id);
if (files.Count > 0)
{
string upload = webRootPath + Constans.imagePath;
string fileName = Guid.NewGuid().ToString();
string extension = Path.GetExtension(files[0].FileName);
var oldFile = Path.Combine(upload, objFromDb.Image);
if (System.IO.File.Exists(oldFile))
{
System.IO.File.Delete(oldFile);
}
using (var fileStream = new FileStream(Path.Combine(upload, fileName + extension), FileMode.Create))
{
files[0].CopyTo(fileStream);
}
admissionVM.AdmissionPatient.Image = fileName + extension;
}
else
{
admissionVM.AdmissionPatient.Image = objFromDb.Image;
}
_db.AdmissionPacients.Update(admissionVM.AdmissionPatient);
}
_db.SaveChanges();
return RedirectToAction("Index");
}
admissionVM.PatientSelectList = _db.Patients.Select(i => new SelectListItem
{
Text = i.FirstName + i.LastName,
Value = i.Id.ToString()
});
admissionVM.DoctorSelectList = _db.Doctors.Select(i => new SelectListItem
{
Text = i.Firstname + i.Lastname,
Value = i.Id.ToString()
});
return View(admissionVM);
}
try add name to this line:
<input type="checkbox" class="form-control" id="emergencyId">
to
<input name="Emergency" type="checkbox" class="form-control" id="emergencyId">

Insert time and datetime in azure db using C# and AngularJS

right now I am working on a web-site and I need to insert some users into my database using C# for backend and AngularJS for frontend. If I use postman, everything works fine, the routes are good, but I have a problem when I try to insert them via angularJS. Here is my db structure
my HTML code
<div class="main" ng-controller="newcandidateController as vm">
<form>
<div class="myInputs">
<div class="form-group">
<input type="text" placeholder=" Full name" id="i1" ng-model="vm.name">
</div>
<div class="form-group">
<input type="text" placeholder=" Email" ng-model="vm.email">
</div>
<div class="form-group">
<input type="text" placeholder=" Phone" ng-model="vm.phone">
</div>
<p id="username">Username: </p>
<p id="password">Password: </p>
<div>
<p>Position</p>
<select class="form-control" ng-model="vm.position">
<option ng-repeat="obj in vm.Tests">{{obj.testType}}</option>
</select>
</div>
<div class="form-check">
<br />
<label>Admin: </label>
<input type="checkbox" name="admin" id="checkbox" ng-model="vm.isadmin">
</div>
<input class="btn btn-info" type="button" value="Generate credentials" id="g" ng-click="vm.generate()">
<input class="btn btn-info" type="button" value="Submit" ng-click="vm.postUser()">
</div>
</form>
and my JavaScript file
vm.postUser = function () {
if (vm.position == "SysAdmin") {
vm.test = 2;
} else if (vm.position == "Java soft engineer") {
vm.test = 3;
} else if (vm.position == "SQL Solutions Architect") {
vm.test = 4;
} else {
vm.test = 5;
}
vm.date = "";
vm.time = "";
dataContext.addUser(vm.name, vm.email, vm.phone, vm.position, vm.username, vm.password, vm.isadmin, vm.test, vm.date, vm.time).then(
function (response) {
console.log(vm.name + " " + vm.email + " " + vm.phone + " " + vm.position + " " + vm.username + " " + vm.password + " " + vm.isadmin + " " + vm.test + " " + vm.date + " " + vm.time);
alert("It worked!");
},
function (error) {
console.log(error);
}
);
};
I don't know how to define a default value for date and time cuz at first I want them to be 0 and update it later.
Any help would be awesome, thank you!
edit:
Here is method where I post a user
public User CreateUser(User user)
{
db.User.Add(user);
db.SaveChanges();
return user;
}

from table it read only int value from EmpID but when it string its show error

This is the webmethod with ajax and jquery. when the EmpID is like 123,12,123456 it open the popup box and show the output as i want but when EmpID is like A001,ABC it show the error like "Error while retrieving data of :" how to solve...
Thanks in Advance
Query Data:-
$(document).on("click", ".editButton", function () {
$("#myModal").focus();
var id = $(this).attr("data-id");
console.log(id);
$("#btnUpdate").attr("edit-id", id);
//alert(id);
$.ajax({
type: "Post",
contentType: "application/json; charset=utf-8",
url: "Default3.aspx/EditData",
data: '{eid: ' + id + '}',
dataType: "json",
success: function (data) {
var empDetails = $.parseJSON(data.d);
$.each(empDetails, function (index, value) {
$("#FirstName1").val(value.EmpID);
$("#MiddleName1").val(value.EmpName);
$("#Surname1").val(value.EmpAddress);
//alert("hi");
});
},
error: function () {
alert("Error while retrieving data of :" + id);
}
});
});
});
Html Table:-
<div class="row">
<div class="col-lg-12">
<br />
<br />
<div class="col-lg-12">
<div class="panel panel-default">
<div class="panel-heading">
Admin Employee Details Tables
</div>
<!-- /.panel-heading -->
<div class="panel-body">
<div class="dataTable_wrapper">
<div id="dataTables-example_wrapper" class="dataTables_wrapper form-inline dt-bootstrap no-footer">
<div class="row">
<div class="col-sm-6">
<div class="dataTables_length" id="dataTables-example_length">
<label>
Show
<select name="dataTables-example_length" aria-controls="dataTables-example" class="form-control input-sm" id="select">
<option value="5">5</option>
<option value="10">10</option>
<option value="25">25</option>
<option value="50">50</option>
<option value="100">100</option>
</select>
entries</label>
</div>
</div>
<div class="col-sm-6">
<div id="dataTables-example_filter" class="dataTables_filter">
<label>Search:<input type="search" class="form-control input-sm" placeholder="" aria-controls="dataTables-example" id="searchtxt" /></label>
</div>
</div>
</div>
<div class="row">
<div class="table-responsive">
<table id="dataTables-example" class="table table-striped table-bordered table-hover dataTable no-footer " role="grid" aria-describedby="dataTables-example_info">
<thead>
<tr role="row">
<th class="sorting_asc" tabindex="0" aria-controls="dataTables-example" rowspan="1" colspan="1" style="width: 175px;" aria-sort="ascending" aria-label="Rendering engine: activate to sort column descending">Emp ID</th>
<th class="sorting" tabindex="0" aria-controls="dataTables-example" rowspan="1" colspan="1" style="width: 203px;" aria-label="Browser: activate to sort column ascending">Emp Name</th>
<th class="sorting" tabindex="0" aria-controls="dataTables-example" rowspan="1" colspan="1" style="width: 184px;" aria-label="Platform(s): activate to sort column ascending">Emp Address</th>
</tr>
</thead>
<tbody>
<% for (var data = 0; data < TableData.Rows.Count; data++)
{ %>
<tr class="gradeA odd " role="row">
<td class="sorting_1">
<%=TableData.Rows[data]["EmpID"]%>
</td>
<td>
<%=TableData.Rows[data]["EmpName"]%>
</td>
<td>
<%=TableData.Rows[data]["EmpAddress"]%>
</td>
<td>
<input type="button" class="btn btn-primary editButton" data-id="<%=TableData.Rows[data]["EmpID"] %>" data-toggle="modal" data-target="#myModal" name="submitButton" id="btnEdit" value="Edit" />
</td>
<td>
<input type="button" class="btn btn-primary deleteButton" data-id="<%=TableData.Rows[data]["EmpId"] %>" name="submitButton" id="btnDelete" value="Delete" />
</td>
</tr>
<% } %>
</tbody>
</table>
</div>
</div>
</div>
</div>
<!-- /.table-responsive -->
</div>
<!-- /.panel-body -->
</div>
<!-- /.panel -->
</div>
</div>
</div>
C# Code-
[WebMethod]
public static string EditData(string eid)
{
string jsondata;
using(var con=new SqlConnection(ConnectString))
{
var query = "Select * from NewEmp where EmpID='" + eid + "' ";
using(var cmd=new SqlCommand(query, con))
{
using(var sda=new SqlDataAdapter())
{
cmd.Connection = con;
sda.SelectCommand = cmd;
TableData.Clear();
sda.Fill(TableData);
jsondata = JsonConvert.SerializeObject(TableData);
}
}
}
return jsondata;
}
Sounds like the ID field is set as an integer value somewhere, such that numbers will work but letters will throw an error. Your JSON looks messed up, too, with weird field mapping:
$("#FirstName1").val(value.EmpID);
$("#MiddleName1").val(value.EmpName);
$("#Surname1").val(value.EmpAddress);
FirstName may not map to EmpID well. Middlename to EmpName, etc.
But overall, it sounds like something is expecting an integer input and you're giving it letters. Look for that and either change the input expectation to varchar/string or change the input to only consist of numbers.

How to remove a selected row from a table when using KnockoutJS

I am simply binding a list of observable objects to a TR inside an html table. When the user selects a row(only one can be selected), i want that selected row or observable object to be removed from the observable array. I have the remove working but it's completely ignoring whether the row is selected or not. I am using a flag on each row to determine whether they are checked or not but the value is always true...even if you uncheck the checkbox on the row which is why it removes them all. Can someone please shed light on the below knockout setup...days of research and testing but KO just hates me :(
<table class="accountGroups" id="tblAccountGroups">
<tr>
<td width="150px;" style="font-weight: bold;">StandardAccountNo</td>
<td width="100px;" style="font-weight: bold;">Primary</td>
<td style="font-weight: bold;">Effective Date</td>
<td style="font-weight: bold;">End Date</td>
</tr>
<!-- ko foreach: NewAccountGroupDetails-->
<tr id="Model.NewAccountGroupDetails[0].AccountGroupName" rowindex="$index()" class="acctgrp-row" data-bind="click: $root.selectedRow">
<td>
<div>
<input type="text" data-bind="value: StandardAccountNo, attr: {name: 'NewAccountGroupDetails[' + $index() + '].StandardAccountNo'}" />
</div>
</td>
<td style="border:2px inset;border-color:gray;">
<div style="text-align:center;">
<input type="radio" data-bind="value: IsPrimary, attr: {name: 'NewAccountGroupDetails[' + $index() + '].IsPrimary'}" />
</div>
</td>
<td>
<div style="width:115px;">
<input type="text" data-bind="value: EffectiveDate, attr: {name: 'NewAccountGroupDetails[' + $index() + '].EffectiveDate'}" readonly="readonly" />
</div>
</td>
<td>
<div style="width:115px;">
<input type="text" data-bind="value: EndDate, attr: {name: 'NewAccountGroupDetails[' + $index() + '].EndDate'}" readonly="readonly" />
</div>
</td>
<td>
<input type="hidden" data-bind="value: ContractType, attr: {name: 'NewAccountGroupDetails[' + $index() + '].ContractType'}" />
<input type="hidden" data-bind="value: CompanyID, attr: {name: 'NewAccountGroupDetails[' + $index() + '].CompanyID'}" />
<input type="hidden" data-bind="value: AccountGroupName, attr: {name: 'NewAccountGroupDetails[' + $index() + '].AccountGroupName'}" />
<input type="checkbox" data-bind="checked: IsSelected, attr: {name: 'NewAccountGroupDetails[' + $index() + '].IsSelected'}" />
</td>
</tr>
<!-- /ko -->
</table>
</div>
</div>
<br />
<div class="row">
<div class="col-lg-2 col-sm-2"> </div>
<div class="col-lg-2 col-sm-2" style="text-align:right;">
<input type="button" value="New" data-bind="click: addNew" />
</div>
<div class="col-lg-2 col-sm-2">
<input type="button" value="Remove" data-bind="click: remove" />
</div>
<div class="col-lg-3 col-sm-2"> </div>
<div class="col-lg-2 col-sm-2">
<input type="button" value="Save" id="btnSave" />
</div>
</div>
JS
$(document).on('ready', function () {
ko.applyBindings(new AccountGroupViewModel());
});
function AccountGroupViewModel() {
var viewModel = this;
//Convert Model property into observable array for KO
var rawList = '#Html.Raw(new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(Model.NewAccountGroupDetails))';
viewModel.NewAccountGroupDetails = ko.observableArray(convertJSONToKoObservableObject($.parseJSON(rawList)));
//Add properties to the vm and an empty ko object to the array
viewModel.NewAccountGroupDetails.push(newAccountGroupDetail());
viewModel.addNew = function () {
viewModel.NewAccountGroupDetails.push(newAccountGroupDetail());
}
viewModel.remove = function (row) {
viewModel.NewAccountGroupDetails.remove(function (item) {
return item.IsSelected();
});
}
}
function convertJSONToKoObservableObject(json) {
var ret = [];
$.each(json, function (i, obj) {
var newOBJ = {};
for (prop in obj) {
newOBJ[prop] = ko.observable(obj[prop]);
}
ret.push(newOBJ);
});
return ret;
}
function newAccountGroupDetail() {
this.StandardAccountNo = ko.observable('');
this.IsPrimary = ko.observable(false);
this.EffectiveDate = ko.observable(new Date());
this.EndDate = ko.observable(new Date());
this.AccountGroupName = ko.observable($('#txtAccountGroupName').val());
this.ContractType = ko.observable($('#ddlContractTypes').val());
this.CompanyID = ko.observable($('#ddlCompany').val());
this.IsSelected = ko.observable(false);
return this;
}
You have couple of mistakes here
viewModel.selectedDetails = ko.computed(function () {
ko.utils.arrayForEach(viewModel.NewAccountGroupDetails(), function (row) {
row.IsSelected(true);
});
});
This piece of code row.IsSelected(true); is actually set IsSelected observable value to true.
To remove item from ObservableArray you should use something like:
viewModel.NewAccountGroupDetails.remove(function(item) {
return item.IsSelected();
});
Also to convert json value to viewModel, take a look at the mapping plugin

Categories

Resources