I'm currently developing an application that involves three key tables: Clients, Attendance, and Panels.
The Panels table allows for the assignment of Attendance to Clients. On the page for creating Attendance records, there's a dropdown list that displays the names of the available Panels. Below this dropdown, I've set up fields to show the panel cost, the amount already paid by the client, and the remaining outstanding balance.
Within the Panels table, there are details such as the date, name, and the cost (Panel Fee) associated with each panel.
My goal for the Create Attendance page is to populate the Panel Cost field automatically when a user selects a Panel Name from the dropdown and clicks outside it. It should retrieve the associated Panel Cost from the Panels table based on the selected option.
Once the Panel Cost is populated in this field, which should be read-only, I will input the Amount Paid, and the script should then calculate and display the Amount Outstanding.
As I lack JavaScript knowledge, I have made some progress with external help and through research, but I am unsure how to properly reference the Panel Name and Panel Cost fields to achieve this functionality.
Below is my current code configuration:
Attendance Create.cshtml:
@page @model SampleApp.Pages.Attendances.CreateModel
Add Client to Panel
---Select Client Id--- ---Select Panel---
---Status---Add Panel -> Return to Client Return to Client@section Scripts
{
function populatePanelCost() {
var selectedPanel = document.getElementById(“PanelDropdown”).value;
if (selectedPanel) {
var cost = panelCosts[selectedPanel];
document.getElementById(“PanelCostField”).value = cost;
}
}$(document).ready(function () { function calculateOutstanding() { var panelCost = parseFloat($('#PanelCostField').val()) || 0; var amountPaid = parseFloat($('#AmountPaidField').val()) || 0; $('#OutstandingAmountField').val(panelCost - amountPaid); } $('#PanelCostField, #AmountPaidField').on('input', calculateOutstanding); }); </script> @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
}
Additionally, in the Attendances Create.cs file:
namespace SampleApp.Pages.Attendances;
[BindProperties]
public class CreateModel : PageModel
{
private readonly ApplicationDbContext _db;public Attendance Attendance { get; set; } = new Attendance(); public Client Client { get; set; } public Panel Panel { get; set; } public CreateModel(ApplicationDbContext db) { _db = db; } public IEnumerable<Panel> DisplayPanelData { get; set; } public IEnumerable<Client> DisplayClientData { get; set; } public IEnumerable<Status> DisplayStatusData { get; set; } public async Task OnGet(int clientid) { Attendance.ClientId = clientid; await _db.Panel.Select(a => a.PanelName).ToListAsync(); DisplayPanelData = await _db.Panel.ToListAsync(); await _db.Client.Select(a => a.Id).ToListAsync(); DisplayClientData = await _db.Client.ToListAsync(); await _db.Status.Select(a => a.StatusDesc).ToListAsync(); DisplayStatusData = await _db.Status.ToListAsync(); } public async Task<IActionResult> OnPost() { if (ModelState.IsValid) { _db.Attendance.Add(Attendance); await _db.SaveChangesAsync(); TempData["success"] = "Client Panel Attendance added successfully."; ViewData["clientid2"] = Attendance.ClientId; return RedirectToPage("/Clients/Edit", new { id = ViewData["clientid2"] }); } return Page(); }
}
Information about the Panel model:
namespace SampleApp.Model
{
public class Panel
{
[Key]
[Required]
public int Id { get; set; }[Display(Name = "Panel Name")] public string? PanelName { get; set; } [Display(Name = "Panel Date")] [DataType(DataType.Date)] public DateTime? PanelDate { get; set; } [Display(Name ="Fee")] [DataType(DataType.Currency)] [Column(TypeName = "decimal(6,2)")] public decimal? PanelFee { get; set; } }
}
I would be grateful for any guidance you could provide. Thank you!
UPDATE: My current JavaScript code is:
$(document).ready(function () {
const panelCosts = {
@foreach (var p in Model.DisplayPanelData) {
“@p.PanelName”: “@p.PanelFee”.ToString(System.Globalization.CultureInfo.InvariantCulture),
}
};function populatePanelCost() { const cost = panelCosts[$("#PanelDropdown").val()]; $("#PanelCostField").val(cost).trigger('input'); } function calculateOutstanding() { const panelCost = parseFloat($('#PanelCostField').val()) || 0; const amountPaid = parseFloat($('#AmountPaidField').val()) || 0; $('#OutstandingAmountField').val(panelCost - amountPaid); } $('#PanelCostField, #AmountPaidField').on('input', calculateOutstanding); } </script>
This implementation does not seem to work. What am I doing wrong? After selecting an option in the Panel Assigned dropdown and moving away from it, the Panel Cost field remains empty. Furthermore, while entering the Amount Paid, the Outstanding Amount stays blank, likely because the Panel Cost is never assigned correctly. Do I need to adjust the updatePanelBalance function to something other than ‘input’?