I am having a main view and few partial views.
The main view is something which displays the list of registered users like this :
The main view code :
#model WebApplication9.Models.User
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
<link ref="~/Styles/UserManagement.css" rel="stylesheet" />
<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
</head>
<body>
<p>
<button type="submit" name="btnDefineTraj" onclick="AddUserBtnClick()" id="button1">Create New User</button>
</p>
<div hidden id="divAddUser" title="Add new user" style="border-radius: 7px">
#Html.Partial("~/Views/UserManagement/CreateUser.cshtml")
</div>
<div hidden id="divEditUser" title="Edit user" style="border-radius: 7px">
#Html.Partial("~/Views/UserManagement/EditUser.cshtml", Model)
</div>
<table>
<tr>
<th>UserID
</th>
<th>Username
</th>
<th>Password
</th>
<th>FirstName
</th>
<th>LastName
</th>
<th>DisplayName
</th>
<th>Email
</th>
<th>Pref. Language
</th>
<th>CreatedBy
</th>
<th>CreatedTime
</th>
<th>ModifiedTime
</th>
<th>IsAdmin
</th>
<th>IsActive
</th>
<th></th>
</tr>
#foreach (var item in Model.usersList)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.userId)
</td>
<td>
#Html.DisplayFor(modelItem => item.userName)
</td>
<td>
#Html.DisplayFor(modelItem => item.password)
</td>
<td>
#Html.DisplayFor(modelItem => item.firstName)
</td>
<td>
#Html.DisplayFor(modelItem => item.lastName)
</td>
<td>
#Html.DisplayFor(modelItem => item.displayName)
</td>
<td>
#Html.DisplayFor(modelItem => item.email)
</td>
<td>
#Html.DisplayFor(modelItem => item.languagePreference)
</td>
<td>
#Html.DisplayFor(modelItem => item.createdBy)
</td>
<td>
#Html.DisplayFor(modelItem => item.createdTime)
</td>
<td>
#Html.DisplayFor(modelItem => item.modifiedTime)
</td>
<td>
#Html.DisplayFor(modelItem => item.isAdmin)
</td>
<td>
#Html.DisplayFor(modelItem => item.isActive)
</td>
<td>
<button type="submit" name="btnEditUser" onclick="EditUserBtnClick(#item.userId)" id="buttonEdit">
<img src="~/Images/edit-icon.png" width="20" height="20" />
</button>
</td>
<td>
<button type="submit" name="btnDeleteUser" onclick="DeleteUserBtnClick(#item.userId)" id="buttonDelete">
<img src="~/Images/delete-icon.png" width="20" height="20" /></button>
#* #Html.ActionLink("Edit", "EditUser", new { id=item.userId } ) |
#Html.ActionLink("Delete", "DeleteUser", new { id=item.userId })*#
</td>
</tr>
}
</table>
</body>
</html>
My model class User code is :
public class User
{
public int UserId { get; set; }
public string userName { get; set; }
public string passWord { get; set; }
public string firstName { get; set; }
public string lastName { get; set; }
public string displayName { get; set; }
public string emailID { get; set; }
public string languagePreference { get; set; }
public bool isAdministrator { get; set; }
public bool isActive { get; set; }
public IEnumerable<usermaster> usersList{ get; set; }
public usermaster EditUserData { get; set; }
}
As you can see, the table is loaded from usersList in the model.
Now I am trying to implement the edit user functionality. When user clicks on edit button I am opening a partial view :
<div hidden id="divEditUser" title="Edit user" style="border-radius: 7px">
#Html.Partial("~/Views/UserManagement/EditUser.cshtml", Model)
</div>
by passing the id to the controller and getting back the user data so that it can be displayed in the new partial view
function EditUserBtnClick(userid) {
$.ajax({
type: "POST",
url: "/UserManagement/EditUser",
data: JSON.stringify({ userID: userid }),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (edituserDataObj) {
if (msg != null) {
$("#divEditUser").dialog({ width: 350 });
}
else {
$('#lblResult').val("Failed to delete user.");
}
},
error: function () {
return "error";
}
});
I am getting the edituserDataObj properly here. But I am not sure how to pass it to the partial view EditUser.cshtml. I tried to edit the model by adding the new edit user data to a model class property public usermaster EditUserData { get; set; }. But when I access this from my partial view, the data is null.
[HttpPost]
public JsonResult EditUser(int userID)
{
var user = DBManager.Instance.GetUserData(userID);
return Json(user);
}
Is there any way to pass the edit user data to the partial view?
Related
When I run the page, and click on the value in the partial table nothing happens with the onclick event. the values are not populating on the textboxes.I set the style of the anchor element to cursor: pointer. Debugging the code as shown in the images, the values populate correctly they just do not appear in the textboxes.
index.cshtml
#page "{id?}"
#model IndexModel
#{ViewData["Title"] = "Test";}
<div class="container">
<div class="row">
<div class="text-center">
<h1 class="display-4">#Model.PageTitle</h1>
</div>
</div>
<div class="row">
<form class="mt-0" method="get">
<div class="row">
<div class="col-3 offset-1" id="ApplicationResult">
</div>
<div class="col-4" id="ApplicationOwnerResult">
</div>
<div class="col-3" id="ApplicationDmvResult">
</div>
</div>
</form>
</div>
<div class="row">
<form class="mt-0" method="post">
<div class="row">
<label class="col-2 offset-4 col-form-label">Date of Birth:</label>
<div class="col-2">
<input class="form-control" title="Date of birth" oninput="validate()" asp-for="DateOfBirth">
<span asp-validation-for="DateOfBirth"></span>
</div>
</div>
<br>
<div class="row">
<label class="col-2 offset-4 col-form-label">Driver's License Number:</label>
<div class="col-2">
<input class="form-control" title="Driver's license number" oninput="validate()" asp-for="DriversLicenseNumber">
<span asp-validation-for="DriversLicenseNumber"></span>
</div>
</div>
<br>
<div class="row">
<button class="btn btn-outline-dark col-1 offset-5" type="submit" id="Submit" disabled asp-page-handler="Submit">Submit</button>
<button class="btn btn-outline-dark col-1" type="button" id="Reset" onclick="clearAll()">Reset</button>
</div>
<br>
</form>
</div>
</div>
#section Scripts {
<script>
// Any exemption applications found will be displayed when the page initially loads. On POST request GET form will be hidden
$(document).ready(function () {
if ("#Model.Exist" == "DivIsVisible") {
$.ajax({
url: "Index/?handler=Display",
type: "GET",
data: { value: #Model.Id },
headers: { RequestVerificationToken: $('input:hidden[name="__RequestVerificationToken"]').val() },
success: function (data) { $("#ApplicationResult").html(data); }
});
}
else {
$("#ApplicationResult").hide();
}
});
// autofill the inputs
function displayOwnerInfo(id) {
$.ajax({
url: "Index/?handler=DisplayOwnerInfo&value=" + id,
type: "GET",
success: function (data) { $("#DateOfBirth").val(data.DateOfBirth); $("#DriversLicenseNumber").val(data.DriversLicenseNumber); }
});
}
</script>
}
index.cshtml.cs
using DMVServiceReference;
using DMV.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using System;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Net.Http;
using System.Runtime.Serialization;
using System.Threading.Tasks;
namespace DMV.Pages
{
public class IndexModel : PageModel
{
public Assess50Context _context;
// Id property refers to checking the PropertyId value for the URL
[BindProperty(SupportsGet = true)] public int Id { get; set; }
// Exist property refers to checking if GetDivs exist on POST request
[BindProperty] public string PageTitle { get; set; } = "Residency Check";
public ResidencyCheckCriteria CheckCriteria { get; set; }
[BindProperty, DataMember, MaxLength(8, ErrorMessage = " "), MinLength(8, ErrorMessage = " "), RegularExpression(#"^([0-9]{8}$)", ErrorMessage = " "), Required(ErrorMessage = " ")] public string DateOfBirth { get => CheckCriteria.DateOfBirth; set => CheckCriteria.DateOfBirth = value; }
[BindProperty, DataMember, MaxLength(13, ErrorMessage = " "), MinLength(13, ErrorMessage = " "), RegularExpression(#"^([A-Za-z0-9]{13}$)", ErrorMessage = " "), Required(ErrorMessage = " ")] public string DriversLicenseNumber { get => CheckCriteria.DriverLicenseNumber; set => CheckCriteria.DriverLicenseNumber = value; }
[BindProperty(SupportsGet = true)] public string Exist { get; set; } = "DivIsVisible";
public IndexModel(Assess50Context context)
{
_context = context;
CheckCriteria = new ResidencyCheckCriteria();
}
// Reads all exemption application table information by property id
public PartialViewResult OnGetDisplay(int value) => Partial("_DisplayApplicationPartial", _context.ExemptionApplications.Where(x => x.PropertyId == value).ToList());
// Reads all exemption application owner information by exemption application id
public PartialViewResult OnGetDisplayOwner(int value) => Partial("_DisplayOwnerPartial", _context.ExemptionApplicationOwners.Where(x => x.ExemptionApplicationId == value).GroupBy(x => x.ExemptionApplicationOwnerId).Select(x => x.First()).ToList());
// Reads the dmv information by application owner ID
// public PartialViewResult OnGetDisplayOwnerInfo(int value) => Partial("_DisplayDMVPartial", _context.ExemptionApplicationDmvinformations.Where(x => x.ExemptionApplicationOwnerId == value).ToList());
public JsonResult OnGetDisplayOwnerInfo(int value)
{
ExemptionApplicationDmvinformation data = _context.ExemptionApplicationDmvinformations.Where(x => x.ExemptionApplicationOwnerId == value).First();
return new JsonResult(new { DateOfBirth = data.DmvDob.ToString(), DriversLicenseNumber = data.DriverLicense });
}
DbContext.cs
using Microsoft.EntityFrameworkCore;
namespace DMV.Models
{
public partial class Assess50Context : DbContext
{
public virtual DbSet<ExemptionApplication> ExemptionApplications { get; set; } = null!;
public virtual DbSet<ExemptionApplicationDmvinformation> ExemptionApplicationDmvinformations { get; set; } = null!;
public virtual DbSet<ExemptionApplicationOwner> ExemptionApplicationOwners { get; set; } = null!;
public Assess50Context() {}
public Assess50Context(DbContextOptions<Assess50Context> options) : base(options) {}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
}
partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
}
}
Application.cs model
using System;
using System.ComponentModel.DataAnnotations;
namespace DMV.Models
{
public partial class ExemptionApplication
{
public int PropertyId { get; set; }
[Display(Name = "Year")] public short YearId { get; set; }
[Display(Name = "App ID")] public int ExemptionApplicationId { get; set; }
[Display(Name = "Reference Number")] public string? ApplicationReference { get; set; }
}
}
Owner.cs model
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace DMV.Models
{
public partial class ExemptionApplicationOwner
{
public int PropertyId { get; set; }
public int ExemptionApplicationId { get; set; }
[Display(Name = "Application Owner ID")] public int ExemptionApplicationOwnerId { get; set; }
[Display(Name = "Owner ID")] public int? OwnerId { get; set; }
public string? FirstName { get; set; }
public string? LastName { get; set; }
[Display(Name = "Name")]public string? AssessProName { get; set; }
}
}
DmvInformation.cs model
using SoapCore.ServiceModel;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace DMV.Models
{
public partial class ExemptionApplicationDmvinformation
{
public int PropertyId { get; set; }
public int ExemptionApplicationId { get; set; }
public int ExemptionApplicationOwnerId { get; set; }
[Display(Name = "DOB")] public DateTime? DmvDob { get; set; }
[Display(Name = "Driver's License #")] public string? DriverLicense { get; set; }
}
}
_DisplayApplicationPartial.cshtml
#model IEnumerable<Models.ExemptionApplication>
#if (Model.Count() != 0)
{
<div id="ExemptionApplicationNav">
<table class="PartialTable">
<thead>
<tr>
<th class="PartialTableRowData" colspan="3">Exemption Applications</th>
</tr>
</thead>
<tbody>
<tr>
<td class="PartialTableRowCategoryData">#Html.DisplayNameFor(m => m.YearId)</td>
<td class="PartialTableRowCategoryData">#Html.DisplayNameFor(m => m.ApplicationReference)</td>
<td class="PartialTableRowCategoryData">#Html.DisplayNameFor(m => m.ExemptionApplicationId)</td>
</tr>
#foreach (Models.ExemptionApplication item in Model)
{
<tr>
<td class="PartialTableRowData">#item.YearId</td>
<td class="PartialTableRowData">#item.ApplicationReference</td>
<td class="PartialTableRowData">
<a class="DMVLabelsTexts" href="Index/?handler=DisplayOwner&value=#item.ExemptionApplicationId">#item.ExemptionApplicationId</a>
</td>
</tr>
}
</tbody>
</table>
</div>
}
else
{
<p>No exemption applications found for this Property ID</p>
}
<script>
$('#ExemptionApplicationNav a').click(function (e) {
$('#ApplicationOwnerResult').hide().load($(this).attr('href'), function () {
$('#ApplicationOwnerResult').show()
})
return false
})
</script>
_DisplayOwnerPartial.cshtml
#model IEnumerable<Models.ExemptionApplicationOwner>
#if (Model.Count() != 0)
{
<div id="OwnerNav">
<table class="PartialTable">
<thead>
<tr>
<th class="PartialTableRowData" colspan="3">Owner Information</th>
</tr>
</thead>
<tbody>
<tr>
<td class="PartialTableRowCategoryData">#Html.DisplayNameFor(m => m.ExemptionApplicationOwnerId)</td>
<td class="PartialTableRowCategoryData" colspan="2">#Html.DisplayNameFor(m => m.AssessProName)</td>
</tr>
#foreach (Models.ExemptionApplicationOwner item in Model)
{
<tr>
<td class="PartialTableRowData">
<a class="DMVLabelsTexts" onclick="displayOwnerInfo('#item.ExemptionApplicationOwnerId')">#item.ExemptionApplicationOwnerId</a>
<!-- <a class="DMVLabelsTexts" href="Index/?handler=DisplayOwnerInfo&value=#item.ExemptionApplicationOwnerId">#item.ExemptionApplicationOwnerId</a> -->
</td>
<td class="PartialTableRowMultipleData">#item.FirstName</td>
<td class="PartialTableRowMultipleData">#item.LastName</td>
</tr>
}
</tbody>
</table>
</div>
}
else
{
<p>No owner data available</p>
}
<!--
<script>
$('#OwnerNav a').click(function (e) {
$('#ApplicationDmvResult').hide().load($(this).attr('href'), function () {
$('#ApplicationDmvResult').show()
})
return false
})
</script>
-->
_DisplayDMVPartial.cshtml
#model IEnumerable<Models.ExemptionApplicationDmvinformation>
#if (Model.Count() != 0)
{
<div id="DmvNav">
<table style=" border: 1px solid black;">
<thead>
<tr>
<th colspan="2" style="border: 1px solid black; text-align: center;">DMV Information</th>
</tr>
</thead>
<tbody>
<tr>
<td style="border: 1px solid black; font-weight: bold; text-align: center;">#Html.DisplayNameFor(m => m.DmvDob)</td>
<td style="border: 1px solid black; font-weight: bold; text-align: center;">#Html.DisplayNameFor(m => m.DriverLicense)</td>
</tr>
#foreach (Models.ExemptionApplicationDmvinformation item in Model)
{
<tr>
<!-- <td style="border: 1px solid black; text-align: center;">item.DmvDob.Value.ToString("MMddyyyy")</td> -->
<td style="border: 1px solid black; text-align: center;">#item.DmvDob</td>
<td style="border: 1px solid black; text-align: center;">#item.DriverLicense</td>
</tr>
}
</tbody>
</table>
</div>
}
else
{
<p>No owner data available</p>
}
Try to change your ajax in the Index.cshtml like below:
// autofill the inputs
function displayOwnerInfo(id) {
$.ajax({
url: "Index/?handler=DisplayOwnerInfo&value=" + id,
type: "GET",
success: function (data) {
$("#DateOfBirth").val(data.dateOfBirth);
$("#DriversLicenseNumber").val(data.driversLicenseNumber);
}
resut:
Scripts in Partials which are themselves loaded by script will not execute. You should place the code that adds the click event handler to the #OwnerNav a element(s) to Index.cshtml. However, you need to use the on method and apply it to an element that exists when the page is initially rendered (e.g. 'body'), passing in the target selector after the name of the event handler:
$('body').on('click', '#OwnerNav a', function (e) {
//
I have a dynamic form that I'm needing to submit to my Controller. I'm attempting to do this using an ajax request after building my Javascript Array of Objects.
When I try to send only a string value to the controller, my model is constantly null. However when I'm trying to send my Javascript array, I'm getting a 400 (Bad Request) reponse.
My dynamic form is used to create an overall Ticket. The Ticket is made up of Entries which can be as many as the End-User is needing as they are able to add a new row to the form table.
The inputs for the form: AccountNumber, AccountDescription, DebitAmount, CreditAmount, PostingDescription, PostDate.
The form table:
#model Areas.TicketEntry.Models.FormTicketSubmissionModel
...
<div class="postDate">
<label asp-for="PostDate" class="control-label"></label>
<input id="PostDateInput" autocomplete="off" />
<span asp-validation-for="PostDate" class="text-danger"></span>
</div>
<form action="Create" method="post" class="ticketForm">
<div class="ticketTable">
<table class="table" id="inputTable">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.AccountNumber)
</th>
<th>
#Html.DisplayNameFor(model => model.AccountDescription)
</th>
<th>
#Html.DisplayNameFor(model => model.DebitAmount)
</th>
<th>
#Html.DisplayNameFor(model => model.CreditAmount)
</th>
<th>
#Html.DisplayNameFor(model => model.PostingDescription)
</th>
<th>
<input type="checkbox" id="checkAllCheckBox" class="allRowCheckBox" value="all" />
</th>
</tr>
</thead>
<tbody>
#for (int i = 0; i < 2; i++)
{
<tr>
<td class="tableAccountNumber">
<input id="#($"form{i}AccountInfo")" list="AccountList" class="AccountInfo">
</td>
<td class="tableAccountDescription">
<input id="#($"form{i}AccountDescription")" class="AccountDescription" />
<span asp-validation-for="AccountDescription" class="text-danger"></span>
</td>
<td class="tableDebitAmount">
<input type="text" data-type="currency" id="#($"form{i}DebitAmount")" class="debitAmount" asp-for="DebitAmount" asp-format="{0:C}" value="0.00" />
<span asp-validation-for="DebitAmount" class="text-danger"></span>
</td>
<td class="tableCreditAmount">
<input type="text" data-type="currency" id="#($"form{i}CreditAmount")" class="creditAmount" asp-for="CreditAmount" asp-format="{0:C}" value="0.00" />
<span asp-validation-for="CreditAmount" class="text-danger"></span>
</td>
<td class="tablePostingDescription">
<input type="text" id="#($"form{i}PostingDescription")" class="postDescrip" value="" />
<span asp-validation-for="PostingDescription" class="text-danger"></span>
</td>
<td class="tableSelectBox">
<input type="checkbox" id="#($"form{i}CheckBox")" class="rowCheckBox" value="selected" />
</td>
</tr>
}
</tbody>
</table>
<div class="tableModifyButtons">
<button id="addRow" type="button">Add Row</button>
<button id="deleteRow" type="button">Delete Row</button>
</div>
</div>
<div class="formButtons">
<button id="submitButton" type="button" class="btn btn-primary">Submit Ticket</button>
</div>
</form>
My Javascript is triggered by my #submitButton being clicked. This iterates over the Ids of the #inputTable and adds the row values to and returns an array.
I can print the array of objects to console and all the values are as expected. I'm currently attempting to stringify the array using JSON to pass it to my controller.
My Javascript for submitting the form:
// Function for submitting data to controller
function submitTickets() {
// Iterate through table and generate type array for ticket submission
// - Add to array of tickets
// - using JSON and stringify it
// - Pass to controller with AJAX
let tickets = getTableTickets('inputTable');
let authToken = $('input[name="__RequestVerificationToken"]');
if (!validateTickets(tickets)) {
setWarningMessage('Invalid Ticket Entries detected. Please review your entries and try again.', 'block');
return;
}
let jsonTickets = JSON.stringify({ "tickets": tickets });
// Ajax it to server
// How to send JSON to server?
$.ajax({
url: "/TicketEntry/Tickets/Create",
type: "POST",
contentType: 'application/json; charset=utf-8',
dataType: 'json',
traditional: true,
data: {
__RequestVerificationToken: authToken,
model: jsonTickets
},
success: function (data, textStatus, jqXHR) {
setMessage('SUCCESS: ' + data.Message, 'block');
},
error: function (jqXHR, textStatus, errorThrown) {
setWarningMessage('Error: ' + jqXHR.statusText + ' - ' + textStatus + ' - ' + errorThrown, 'block');
}
});
console.log(jsonTickets);
console.log('ticket input length: ' + tickets.length);
}
JSON.Stringified array output:
{"model":[{"AccountNumber":"0000000","AccountDescription":"TEST ACCOUNT","DebitAmount":"25.00","CreditAmount":"0.00","PostingDescription":"TEST","PostDate":"07/15/2021"},{"AccountNumber":"0000001","AccountDescription":"TEST ACCOUNT 2","DebitAmount":"25.00","CreditAmount":"0.00","PostingDescription":"TEST","PostDate":"07/15/2021"},{"AccountNumber":"0000002","AccountDescription":"TEST ACCOUNT 3","DebitAmount":"0.00","CreditAmount":"50.00","PostingDescription":"TEST","PostDate":"07/15/2021"}]}
My current View Model:
public class FormTicketSubmissionModel
{
[Display(Name = "Account Number")]
public string AccountNumber { get; set; }
[DataType(DataType.Text)]
[StringLength(29, ErrorMessage = "Description is too long!")]
[RegularExpression(#"^[a-zA-Z0-9+&.""/'\s-]*$")]
[Display(Name = "Account Description")]
public string AccountDescription { get; set; }
[Display(Name = "Posting Description")]
[StringLength(29, ErrorMessage = "Posting Description is too long!")]
[RegularExpression(#"^[a-zA-Z0-9+&.""/'\s-]*$")]
public string PostingDescription { get; set; }
[Display(Name = "Post Date")]
[DataType(DataType.Date)]
public DateTime PostDate { get; set; }
[Display(Name = "Debit Amount")]
[DataType(DataType.Currency)]
[Column(TypeName = "decimal(18,2)")]
[Required]
public decimal DebitAmount { get; set; } = 0.00m;
[Display(Name = "Credit Amount")]
[DataType(DataType.Currency)]
[Column(TypeName = "decimal(18,2)")]
[Required]
public decimal CreditAmount { get; set; } = 0.00m;
}
I've tried passing only string values using my Ajax, but my model was consistantly null.
Here is my current Action Method:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([FromBody]List<FormTicketSubmissionModel> model)
{
if (ModelState.IsValid)
{
// Validate data within models and save them to database
// ...
return RedirectToAction(nameof(Index));
}
return View(model);
}
How can I pass an Array of Objects from Javascript to my Controller?
Thank you in advance for any help!
After revisiting #Llama 's shared link, I re-designed my model(s) and form. Also, in my View's Form, I had <form action="Create" .../> instead of <form asp-action="Create" .../>. This caused my form's submission to respond with a 400. My solution no longer needs JavaScript/Ajax.
New models:
public class FormTicketSubmissionModel
{
[HiddenInput]
public int Id { get; set; }
// Stores the values of the entries
public FormTicketEntryModel[] TicketEntries { get; set; }
[Display(Name = "Post Date")]
[DataType(DataType.Date)]
public DateTime PostDate { get; set; }
[DataType(DataType.Text)]
[RegularExpression(#"^[a-zA-Z0-9]*$")]
public string UserName { get; set; }
}
public class FormTicketEntryModel
{
[HiddenInput]
public int Id { get; set; }
[Display(Name = "Account Number")]
public string AccountNumber { get; set; }
[DataType(DataType.Text)]
[StringLength(29, ErrorMessage = "Description is too long!")]
[RegularExpression(#"^[a-zA-Z0-9+&.""/'\s-]*$")]
[Display(Name = "Account Description")]
public string AccountDescription { get; set; }
[Display(Name = "Posting Description")]
[StringLength(29, ErrorMessage = "Posting Description is too long!")]
[RegularExpression(#"^[a-zA-Z0-9+&.""/'\s-]*$")]
public string PostingDescription { get; set; }
[Display(Name = "Debit Amount")]
[DataType(DataType.Currency)]
[Column(TypeName = "decimal(18,2)")]
[Required]
public decimal DebitAmount { get; set; } = 0.00m;
[Display(Name = "Credit Amount")]
[DataType(DataType.Currency)]
[Column(TypeName = "decimal(18,2)")]
[Required]
public decimal CreditAmount { get; set; } = 0.00m;
}
My new View:
<form asp-action="Create" method="post" class="ticketForm">
<input asp-for="Id" />
<div class="ticketTable">
<table class="table" id="inputTable">
<thead>
<tr>
<th>
<label>Account Number</label>
</th>
<th>
<label>Account Description</label>
</th>
<th>
<label>Debit Amount</label>
</th>
<th>
<label>Credit Amount</label>
</th>
<th>
<label>Posting Description</label>
</th>
<th>
<input type="checkbox" id="checkAllCheckBox" class="allRowCheckBox" value="all" />
</th>
</tr>
</thead>
<tbody>
#for (int i = 0; i < 2; i++)
{
<tr>
<td class="tableAccountNumber">
<input id="#($"form{i}AccountInfo")" asp-for="#Model.TicketEntries[i].AccountNumber" list="AccountList" class="AccountInfo">
</td>
<td class="tableAccountDescription">
<input id="#($"form{i}AccountDescription")" asp-for="#Model.TicketEntries[i].AccountDescription" class="AccountDescription" />
<span asp-validation-for="#Model.TicketEntries[i].AccountDescription" class="text-danger"></span>
</td>
<td class="tableDebitAmount">
<input type="text" data-type="currency" id="#($"form{i}DebitAmount")" class="debitAmount" asp-for="#Model.TicketEntries[i].DebitAmount" asp-format="{0:C}" value="0.00" />
<span asp-validation-for="#Model.TicketEntries[i].DebitAmount" class="text-danger"></span>
</td>
<td class="tableCreditAmount">
<input type="text" data-type="currency" id="#($"form{i}CreditAmount")" class="creditAmount" asp-for="#Model.TicketEntries[i].CreditAmount" asp-format="{0:C}" value="0.00" />
<span asp-validation-for="#Model.TicketEntries[i].CreditAmount" class="text-danger"></span>
</td>
<td class="tablePostingDescription">
<input type="text" id="#($"form{i}PostingDescription")" asp-for="#Model.TicketEntries[i].PostingDescription" class="postDescrip" value="" />
<span asp-validation-for="#Model.TicketEntries[i].PostingDescription" class="text-danger"></span>
</td>
<td class="tableSelectBox">
<input type="checkbox" id="#($"form{i}CheckBox")" class="rowCheckBox" value="selected" />
</td>
</tr>
}
</tbody>
</table>
<div class="tableModifyButtons">
<button id="addRow" type="button">Add Row</button>
<button id="deleteRow" type="button">Delete Row</button>
</div>
</div>
<div class="formButtons">
<button id="submitButton" type="submit" class="btn btn-primary">Submit Ticket</button>
</div>
</form>
I'm working on ASP.NET Core web application where I have a table in my view that displays all requests. each record with drop-down populated with all analysts successfully from my database, So the manager can assign the analyst from drop-down then approve the request.
My questions:
Can I implement this using form for each record instead using JavaScript, I mean using only asp tags?
If that should done using JavaScript, Here is my attempt to implement this.
The following code is working only if the Analyst id is integer, but in my case the analyst id is string, so whenever I try to execute this, I got either "null" or "Zero" for the analyst id in the controller. Here is my ViewModel
public class RequestViewModel
{
public IEnumerable<Request> Requests { get; set; }
public IEnumerable<ApplicationUser> AnalystList { get; set; }
public Institution Institution { get; set; }
public string selectedAnalyst { get; set; }
}
Here is my controller
public async Task<IActionResult> ApproveRequest(int id, int Analystid)
{
Request Req = await _db.Request
.Include(c => c.Institution)
.FirstOrDefaultAsync(c => c.Id == id);
if (Req.Type == SD.TypeRegister)
{
Req.Institution.Status = SD.StatusApproved;
Req.Institution.ApprovalDate = DateTime.Now;
Req.Institution.Seats = Req.Seats; // new
Req.Institution.AnalystId = Analystid.ToString(); //Here I want to get the id as string
}
else if (Req.Type == SD.TypeSeat)
{
Req.Institution.Seats += Req.Seats;
}
else if (Req.Type == SD.TypeSubscription)
{
Req.Institution.Seats = Req.Seats;
Req.Institution.Status = SD.StatusApproved;
Req.Institution.ApprovalDate = DateTime.Now;
}
Req.isDone = true;
await _db.SaveChangesAsync();
return await CreateApproval(id, SD.StatusApproved);
}
Here is my View
#model TestApplication.Models.ViewModels.RequestViewModel
#using TestApplication.Extensions
#{
ViewData["Title"] = "Index";
}
<div class="tab-pane fade show active" id="Register" role="tabpanel" aria-labelledby="Register-tab">
Registration Requests
<div>
#if (Model.Requests.Count() > 0)
{
<table class="table table-striped">
<tr class="table-secondary">
<th>
Institution Name
</th>
<th>
Date
</th>
<th>
Actual seat
</th>
<th>
Seats
</th>
<th>
New Seat
</th>
<th>
Choose Analyst
</th>
<th>
Accept / Reject
</th>
<th>
Details
</th>
<th>
</th>
</tr>
#foreach (var item in Model.Requests)
{
#if (item.Type == "Register" && item.Institution.Status == "Pending") #*need one*#
{
<tr>
<td>
#Html.DisplayFor(m => item.Institution.Name)
</td>
<td>
#Html.DisplayFor(m => item.Date)
</td>
<td>
#Html.DisplayFor(m => item.Institution.Seats)
</td>
<td>
#Html.DisplayFor(m => item.ActualSeats)
</td>
<td>
#Html.DisplayFor(m => item.Seats)
</td>
<td>
<select id="selectedAnalyst_#item.Id" asp-for="selectedAnalyst" asp-items=" Model.AnalystList.ToSelectListItem(Model.selectedAnalyst)" class="form-control">
<option selected value="">--- Choose ---</option>
</select>
</td>
<td>
<a class="btn btn-info" asp-controller="Request" asp-action="ApproveRequest" asp-route-id="#item.Id"> accept </a>
<a class="btn btn-info" asp-controller="Request" asp-action="RejectRequest" asp-route-id="#item.Id"> Reject </a>
</td>
<td>
<button type="submit" class="btn btn-success anchorDetail" data-target="#modal-#item.Institution.Id" data-toggle="modal">
View Details
</button>
</td>
<td>
<div class="modal fade" id="modal-#item.Institution.Id" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog-centered modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header bg-success text-light justify-content-center">
<h5 class="modal-title">Request Details</h5>
</div>
<div class="modal-body justify-content-center" id="MyModalContent">
#await Html.PartialAsync("_RequestDetails", item)
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">إغلاق</button>
</div>
</div>
</div>
</div>
</td>
</tr>
}
}
</table>
}
else
{
<p>No Institutions Exists...</p>
}
</div>
</div>
#section scripts
{
<script>
function accept(id) {
var aid = $('#selectedAnalyst_' + id).val()
location.href = "/Request/ApproveRequest?id=" + id + "&Analystid=" + aid
}
var PostBackURL = '/Request/RequestDetails';
$(function () {
$(".anchorDetail").click(function () {
var $buttonClicked = $(this);
var id = $buttonClicked.attr('data-id');
$.ajax({
type: "GET",
url: PostBackURL,
contentType: "application/json; charset=utf-8",
data: { "Id": id },
cache: false,
datatype: "json",
success: function (data) {
$('#MyModalContent').html(data);
$('#myModal').modal('show');
},
error: function () {
alert("Dynamic content load failed.");
}
});
})
</script>
}
<div class="modal fade" id="MyModal" tabindex="-1" role="dialog"
aria-labelledby="myModalLabel">
<div id='MyModalContent'></div>
</div>
If you want to pass #item.id and $('#selectedAnalyst_' + id).val() to controller with form,you can do like this.Here is a demo worked(put form outside dropdownlist and button):
<form method="post"
asp-controller="Request"
asp-action="ApproveRequest"
asp-route-id="#item.Id">
<td>
<select id="selectedAnalyst_#item.Id" asp-for="selectedAnalyst" class="form-control">
<option selected value="">--- Choose ---</option>
<option selected value="1">1</option>
<option selected value="2">2</option>
<option selected value="3">3</option>
</select>
</td>
<td>
<button type="submit">Accept</button>
</td>
</form>
Controller(change Analystid to selectedAnalyst,so that you can bind asp-for="selectedAnalyst",and if you want to get string parameter,you can change it to string selectedAnalyst):
public IActionResult ApproveRequest(int id,string selectedAnalyst)
{
return Ok();
}
result:
I am using .NET CORE MVC for making some forms for the user to add people to a system (A manual process). One of the forms I've got is a simple multi-add user form that allows the user to enter names on the form and click submit, where it is then serialized and converted into a PDF document to be saved to the local machine.
I wanted to make this with a dynamic HTML Table in mind so I've got the following setup. The intent here is to allow a table to start initially with a single empty, editable row and give the ability to add rows as they need, while binding each row to a list of objects on the model.
User class
[Serializable]
public class User
{
[Display(Name = "M.I.")]
public string MiddleInitial { get; set; }
[Display(Name = "Suffix")]
public string NameSuffix { get; set; }
[Required(AllowEmptyStrings = false)]
[Display(Name = "First Name")]
public string FirstName { get; set; }
[Required(AllowEmptyStrings = false)]
[Display(Name = "Last Name")]
public string LastName { get; set; }
}
MultiAddUser class
[Serializable]
public class MultiAddUser
{
[Required]
[Display(Name = "Start Date")]
public DateTime StartDate { get; set; }
public List<User> Users { get; set; }
public MultiAddUser()
{
Users = new List<User>();
}
}
My view has the following code that displays the basic table with inputs in the cells with the ability to add cells on the fly.
#using Contract
#model MultiAddUser
#section Scripts{
<script>
function addRow() {
var table = document.getElementById("MultiAddUserTable");
var row = table.insertRow(-1);
var cell1 = row.insertCell(0);
cell1.innerHTML = '<input type="text" />';
var cell2 = row.insertCell(1);
cell2.innerHTML = '<input type="text" />';
var cell3 = row.insertCell(2);
cell3.innerHTML = '<input type="text" />';
var cell4 = row.insertCell(3);
cell4.innerHTML = '<input type="text" />';
}
</script>
}
<style>
input {
width: 100%;
}
</style>
<body>
<h2 class="formtitle">ADD MULTIPLE USERS</h2>
<form method="post" asp-action="AddMultipleUsers" id="addMultiUsers">
<div class="form-group">
<div class="form-row">
<div class="form-group col-sm-2">
<label asp-for="StartDate"></label>
<input type="date" asp-for="StartDate" class="form-control" />
<span asp-validation-for="StartDate" class="text-danger"></span>
</div>
</div>
<table id="AddMultipleUsersTable">
<tr>
<th>First Name</th>
<th>Middle Initial</th>
<th>Last Name</th>
<th>Suffix</th>
</tr>
<tr>
<td><input type="text" /></td>
<td><input type="text" /></td>
<td><input type="text" /></td>
<td><input type="text" /></td>
</tr>
</table>
<button type="button" onclick="addRow()">Add</button>
<hr />
<div class="form-row">
<div id="submitbutton">
<input id="submit" class="btn btn-primary btn-lg" style="background-color: #4CAF50; color:white;" type="submit" />
</div>
</form>
</body>
Now normally with ASP.NET Core MVC you would just have something like asp-for="#Model.Property[IndexIfNeeded]" in the input tag helper but since the list starts empty and is not bound by a database, I'm having trouble piecing together how I would go about adding each new row as a new item to the list on the model once the entire form is submitted.
I may be over complicating this since the data never needs to be entered into a database, but it does need to be serialized and converted into a PDF document and be printed at the end of the process so any insight as to alternative methods to accomplish that would be appreciated.
In summary, How can I bind the rows / columns added dynamically to this table to my model objects, while maintaining validation rules on each required property?
Since your data is not associated with the database, I recommend that you create public variables to store the added and new added data.
And the 'td' tag in view does not support the 'asp-for' attribute, so you can add the input box in 'td' to add new data.
public class HomeController : Controller
{
public static MultiAddUser multiAddUser = new MultiAddUser { };
public static List<User> users = new List<User> { };
public IActionResult Index()
{
ViewBag.UserList = multiAddUser.Users;
return View();
}
public IActionResult Add(User user)
{
if (!ModelState.IsValid)
{
ViewBag.UserList = multiAddUser.Users;
return View("Index");
}
users.Add(user);
multiAddUser.Users = users;
return RedirectToAction("Index");
}
}
Index.cshtml:
#model WebApplication_core.Models.User
#{
ViewData["Title"] = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h1>Index</h1>
<form asp-controller="Home" asp-action="Add">
<table id="MultiAddUserTable" class="table">
<tr>
<th>First Name</th>
<th>Middle Initial</th>
<th>Last Name</th>
<th>Suffix</th>
</tr>
#foreach (var item in (IEnumerable<WebApplication_core.Models.User>)ViewBag.UserList)
{
<tr>
<td>#item.FirstName</td>
<td>#item.MiddleInitial</td>
<td>#item.LastName</td>
<td>#item.NameSuffix</td>
</tr>
}
<tr>
<td contenteditable="true">
<input id="Text1" type="text" asp-for="#Model.FirstName" />
<br /><span asp-validation-for="#Model.FirstName" class="text-danger"></span>
</td>
<td contenteditable="true">
<input id="Text2" type="text" asp-for="#Model.MiddleInitial" />
<br /><span asp-validation-for="#Model.MiddleInitial" class="text-danger"></span>
</td>
<td contenteditable="true">
<input id="Text3" type="text" asp-for="#Model.LastName" />
<br /> <span asp-validation-for="#Model.LastName" class="text-danger"></span>
</td>
<td contenteditable="true">
<input id="Text4" type="text" asp-for="#Model.NameSuffix" />
<br /> <span asp-validation-for="#Model.NameSuffix class="text-danger"></span>
</td>
</tr>
</table>
<input id="Button1" type="submit" value="Add" />
</form>
Here is the result :
Update(2020/3/5) :
public class HomeController: Controller
{
public static List<User> users = new List<User> { new User { } };
public static MultiAddUser multiAddUser = new MultiAddUser
{
Users = users
};
public IActionResult Index()
{
ViewBag.UserList = multiAddUser.Users;
return View();
}
public IActionResult Add(List<User> userLists)
{
if (!ModelState.IsValid)
{
ViewBag.UserList = multiAddUser.Users;
return View("Index");
}
users = userLists;
users.Add(new User { });
multiAddUser.Users = users;
return RedirectToAction("Index");
}
}
Index.cshtml:
#model IList<WebApplication_core.Models.User>
#{
ViewData["Title"] = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
var Model = (IList<WebApplication_core.Models.User>)ViewBag.UserList;
}
<h1>Index</h1>
<form asp-controller="Home" asp-action="Add">
<table id="MultiAddUserTable" class="table">
<tr>
<th>First Name</th>
<th>Middle Initial</th>
<th>Last Name</th>
<th>Suffix</th>
</tr>
#for (int i = 0; i < Model.Count(); i++)
{
<tr>
<td>
<input id="Text1" type="text" asp-for="#Model[i].FirstName" />
<br /><span asp-validation-for="#Model[i].FirstName" class="text-danger"></span>
</td>
<td>
<input id="Text2" type="text" asp-for="#Model[i].MiddleInitial" />
<br /><span asp-validation-for="#Model[i].MiddleInitial" class="text-danger"></span>
</td>
<td>
<input id="Text3" type="text" asp-for="#Model[i].LastName" />
<br /> <span asp-validation-for="#Model[i].LastName" class="text-danger"></span>
</td>
<td>
<input id="Text4" type="text" asp-for="#Model[i].NameSuffix" />
<br /> <span asp-validation-for="#Model[i].NameSuffix" class="text-danger"></span>
</td>
</tr>
}
</table>
<input id="Button1" type="submit" value="Add" />
</form>
Here is the new result :
can somebody help me..
this is my Code:
Index.cshtml
<!DOCTYPE html>
<html>
<head>
<title>jQuery With Example</title>
#Scripts.Render("~/bundles/jquery")
<script type="text/javascript">
$(function () {
$('.chkview').change(function () {
$(this).closest('tr').find('.chkitem').prop('checked', this.checked);
});
$(".chkitem").change(function () {
var $tr = $(this).closest('tr'), $items = $tr.find('.chkitem');
$tr.find('.chkview').prop('checked', $items.filter(':checked').length == $items.length);
});
});
function Save() {
$.ajax({
url: #Url.Action("Index", "Home" , "Index"),
type: "POST",
data: formData ,
dataType: "json",
success: function(data){
alert(data.RoleID)
},
error: function(e){
debugger;
}
}
</script>
</head>
<body>
<h2>Access Control-Home</h2>
<br />
#using (Html.BeginForm("Index", "Home", FormMethod.Post, new { RoleID="RoleID" }))
{
<input type="hidden" name="RoleID" value="1" id="RoleID" />
<table id="mytable">
<tr>
<td>View</td>
<td>Insert</td>
<td>Update</td>
<td>Delete</td>
</tr>
<tr>
<td>Administrator</td>
<td>
<input type="checkbox" class="chkview chkview-1" />
</td>
<td>
<input type="checkbox" class="chkitem chkitem-1" />
</td>
<td>
<input type="checkbox" class="chkitem chkitem-1" />
</td>
<td>
<input type="checkbox" class="chkitem chkitem-1" />
</td>
</tr>
<tr>
<td>Free User</td>
<td>
<input type="checkbox" class="chkview chkview-2" />
</td>
<td>
<input type="checkbox" class="chkitem chkitem-2" />
</td>
<td>
<input type="checkbox" class="chkitem chkitem-2" />
</td>
<td>
<input type="checkbox" class="chkitem chkitem-2" />
</td>
</tr>
</table>
<br />
<button type="submit" class="buttons buttons-style-1" onclick="Save()">Save</button>
}
</body>
</html>
HomeController.cs
[HttpPost]
public ActionResult Index(string RoleID)
{
var _roleID = RoleID;
return View();
}
i want to ask 2 question.
how i can parsing value of list checked checkbox using ajax? i want parsing classname of checkbox which i checked example i need list of array if i checked row administrator, { 'chkinsert-1','chkupdate-2' }
how i can get value collection of array in controller post?
example:
public ActionResult Index(string RoleID, array[] collChecbox) contents of collChecbox = { 'chkinsert-1','chkupdate-2'} in accordance with the user checked of checkbox input.
can somebody help me??
Why don't you use Ajax.BeginForm() this makes so easy to send posted form value.
Also, you should create proper model first.
MODEL
public class UserRole
{
public Administrator Administrator { get; set; }
public FreeUser FreeUser { get; set; }
}
public class Administrator
{
public int Checkbox1 { get; set; }
}
public class FreeUser
{
public int Checkbox1 { get; set; }
}
Do following in View.
#model Model.UserRole
<div id="result"></div>
#using (Ajax.BeginForm(new AjaxOptions { UpdateTargetId = "result" }))
{
<input type="hidden" name="RoleID" value="1" id="RoleID" />
<table id="mytable">
<tr>
<td>View</td>
<td>Insert</td>
<td>Update</td>
<td>Delete</td>
</tr>
<tr>
<td>Administrator</td>
<td>
#Html.CheckBoxFor(m => m.Administrator.Checkbox1)
</td>
</tr>
<tr>
<td>Free User</td>
<td>
#Html.CheckBoxFor(m => m.FreeUser.Checkbox1)
</td>
</tr>
</table>
<br />
<button type="submit" class="buttons buttons-style-1" onclick="Save()">Save</button>
}
Controller action
[HttpPost]
public ActionResult Index(UserRole model)
{
return View();
}
Also don't forget to include ajax library.
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")" type="text/javascript"></script>