This post is entirely updated to put all code in one class and to try to make it as straight-forward as possible.
The project works perfectly EXCEPT for one thing: When a student record is updated, the database is updated, but the visible list does not update.
The only way I've been able to see the changes is when I refresh the entire page (see NavigationManager line at bottom of code).
Can you please help me understand what I'm not doing right here.
#page "/Students2";
#using ParentChild.Models;
#inject IJSRuntime JS; // Used for Confirmation Dialog & Alert Box
#inject NavigationManager NavigationManager // Used to Refresh Entire Page
<h3>Students 2</h3>
#if (byStudents == null)
{
<p><em>Loading...</em></p>
}
else if (!byStudents.Any())
{
<p><em>No students in database. Please add some.</em></p>
}
else
{
<table class="table">
<thead>
<tr>
<th>First</th>
<th>Last</th>
<th>Street</th>
<th>City</th>
<th>State</th>
<th>Zip</th>
<th>Cell</th>
<th>Home</th>
<th>Email</th>
<th>Note</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var byStudent in byStudents)
{
<tr>
<td>#byStudent.SFirst</td>
<td>#byStudent.SLast</td>
<td>#byStudent.SStreet</td>
<td>#byStudent.SCity</td>
<td>#byStudent.SState</td>
<td>#byStudent.SZip</td>
<td>#byStudent.SCell</td>
<td>#byStudent.SHome</td>
<td>#byStudent.SEmail</td>
<td>#byStudent.SNote</td>
<td>
<input type="button" class="btn btn-primary" #onclick="#(() => OpenEditStudent(#byStudent.SId))" value="Edit" />
<nbsp></nbsp>
<input type="button" class="btn btn-danger" #onclick="#(async () => await DeleteStudentAction(#byStudent.SId))" value="Delete" />
</td>
</tr>
}
</tbody>
</table>
}
<button class="btn btn-primary" #onclick="() => OpenAddStudent()">Add New Student</button>
#if (showBackdrop)
{
<div class="modal-backdrop fade show"></div>
}
<!-- Define Modal Pop-UP in this Page -->
<div class="modal #modalClass" tabindex="-1" role="dialog" style="display:#modalDisplay; overflow-y: auto;">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">
<!-- Pop-Up Title Section -->
#{
var txt = "";
if ((SId == null) | (SId == ""))
{
txt = "Add Student";
#txt;
}
else
{
txt = "Edit Student";
#txt;
}
}
</h5>
<!-- Pop-Up Close Button at Top -->
<button type="button" class="close" data-dismiss="modal" aria-label="Close" #onclick="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<!-- Pop-Up Body Section -->
<div class="form-group row">
<input id="SId" #bind="SId" type="hidden" class="col-sm-4 form-control" />
</div>
<div class="form-group row">
<label for="#SFirst" class="col-sm-8 col-form-label">First Name:</label>
<input id="SFirst" #bind="SFirst" class="col-sm-4 form-control" />
</div>
<div class="form-group row">
<label for="#SLast" class="col-sm-8 col-form-label">Last Name:</label>
<input id="SLast" #bind="SLast" class="col-sm-4 form-control" />
</div>
<div class="form-group row">
<label for="#SStreet" class="col-sm-8 col-form-label">Street:</label>
<input id="#SStreet" #bind="SStreet" class="col-sm-4 form-control" />
</div>
<div class="form-group row">
<label for="#SCity" class="col-sm-8 col-form-label">City:</label>
<input id="#SCity" #bind="SCity" class="col-sm-4 form-control" />
</div>
<div class="form-group row">
<label for="#SState" class="col-sm-8 col-form-label">State:</label>
<input id="#SState" #bind="SState" class="col-sm-4 form-control" />
</div>
<div class="form-group row">
<label for="#SZip" class="col-sm-8 col-form-label">Zip:</label>
<input id="#SZip" #bind="SZip" class="col-sm-4 form-control" />
</div>
<div class="form-group row">
<label for="#SCell" class="col-sm-8 col-form-label">Cell #:</label>
<input id="#SCell" #bind="SCell" class="col-sm-4 form-control" />
</div>
<div class="form-group row">
<label for="#SHome" class="col-sm-8 col-form-label">Home #:</label>
<input id="#SHome" #bind="SHome" class="col-sm-4 form-control" />
</div>
<div class="form-group row">
<label for="#SEmail" class="col-sm-8 col-form-label">Email:</label>
<input id="#SEmail" #bind="SEmail" class="col-sm-4 form-control" />
</div>
<div class="form-group row">
<label for="#SNote" class="col-sm-8 col-form-label">Note:</label>
<input id="#SNote" #bind="SNote" class="col-sm-4 form-control" />
</div>
</div>
<div class="modal-footer">
<!-- Pop-Up Body Section -->
#{
if ((SId == null) | (SId == ""))
{
<button type="button" class="btn btn-primary" #onclick="async () => await AddStudentAction()">Add</button>
}
else
{
<button type="button" class="btn btn-primary" #onclick="async () => await UpdateStudentAction(this.SId)">Update</button>
}
}
<button type="button" class="btn btn-secondary" data-dismiss="modal" #onclick="() => this.Close()">Close</button>
</div>
</div>
</div>
</div>
#code {
//-------------------------------------------------------------------------
// Modal Control Variables and Code
//-------------------------------------------------------------------------
private string modalDisplay = "none;";
private string modalClass = "";
private bool showBackdrop = false;
//--- Open Modal...
public void Open()
{
modalDisplay = "block;";
modalClass = "show";
showBackdrop = true;
}
//--- Close Modal...
public void Close()
{
modalDisplay = "none";
modalClass = "";
showBackdrop = false;
}
//-------------------------------------------------------------------------
// Student List from Database
//-------------------------------------------------------------------------
DB_136837_byogaContext db = new DB_136837_byogaContext();
private List<ByStudents> byStudents;
//--- Build Student List on Page Initialization...
protected override void OnInitialized()
{
byStudents = db.ByStudents.ToList();
}
//-------------------------------------------------------------------------
// Modal Parameters
//-------------------------------------------------------------------------
private Modal modal { get; set; }
[Parameter]
public string SId { get; set; } = "";
[Parameter]
public string SFirst { get; set; } = "";
[Parameter]
public string SLast { get; set; } = "";
[Parameter]
public string SStreet { get; set; } = "";
[Parameter]
public string SCity { get; set; } = "";
[Parameter]
public string SState { get; set; } = "";
[Parameter]
public string SZip { get; set; } = "";
[Parameter]
public string SCell { get; set; } = "";
[Parameter]
public string SHome { get; set; } = "";
[Parameter]
public string SEmail { get; set; } = "";
[Parameter]
public string SNote { get; set; } = "";
//-------------------------------------------------------------------------
// Open Modal to Add Student
//-------------------------------------------------------------------------
protected void OpenAddStudent()
{
//-- Clear Any Info Set in Previous Edit Requests...
SId = "";
SFirst = "";
SLast = "";
SStreet = "";
SCity = "";
SState = "";
SZip = "";
SCell = "";
SHome = "";
SEmail = "";
SNote = "";
//--- Open Modal Popup...
this.Open();
}
//-------------------------------------------------------------------------
// Open Modal to Edit Student
//-------------------------------------------------------------------------
protected void OpenEditStudent(int myID)
{
//--- Build & Run SQL Select Statement...
using (var myContext = new DB_136837_byogaContext())
{
//--- Grab Info for Selected Student...
var myQuery = (from s in myContext.ByStudents where s.SId == myID select s).Single();
//--- Set Fields on Popup Form...
this.SId = myQuery.SId.ToString();
this.SFirst = myQuery.SFirst;
this.SLast = myQuery.SLast;
this.SStreet = myQuery.SStreet;
this.SCity = myQuery.SCity;
this.SState = myQuery.SState;
this.SZip = myQuery.SZip;
this.SCell = myQuery.SCell;
this.SHome = myQuery.SHome;
this.SEmail = myQuery.SEmail;
this.SNote = myQuery.SNote;
}
//--- Open Modal Form...
this.Open();
}
//-------------------------------------------------------------------------
// Delete Selected Student from Database with Confirmation Dialog
//-------------------------------------------------------------------------
protected async Task DeleteStudentAction(int myID)
{
bool isConfirmed = await JS.InvokeAsync<bool>("confirm", $"Do you sure you want to permanently delete whis record?");
if (isConfirmed)
{
//--- Build & Run SQL Delete Statement...
using (var myContext = new DB_136837_byogaContext())
{
var myQuery = (from d in myContext.ByStudents where d.SId == myID select d).Single();
myContext.ByStudents.Remove(myQuery);
myContext.SaveChanges();
}
//--- Delete Complete Dialog...
await JS.InvokeVoidAsync("alert", "Record Deleted");
//--- Refresh Page...
await InvokeAsync(() =>
{
StateHasChanged();
this.OnInitialized();
});
}
}
//-------------------------------------------------------------------------
// Add Student to Database
//-------------------------------------------------------------------------
protected async Task AddStudentAction()
{
//--- Define the New Student...
var newStudent = new ByStudents();
newStudent.SFirst = SFirst;
newStudent.SLast = SLast;
newStudent.SStreet = SStreet;
newStudent.SCity = SCity;
newStudent.SState = SState;
newStudent.SZip = SZip;
newStudent.SCell = SCell;
newStudent.SHome = SHome;
newStudent.SEmail = SEmail;
newStudent.SNote = SNote;
//--- Add New Student to Database...
using (var myContext = new DB_136837_byogaContext())
{
myContext.ByStudents.Add(newStudent);
myContext.SaveChanges();
}
//--- Close the Popup...
this.Close();
//--- Refresh Page...
await InvokeAsync(() =>
{
StateHasChanged();
this.OnInitialized();
});
}
//-------------------------------------------------------------------------
// Update Student in Database
//-------------------------------------------------------------------------
protected async Task UpdateStudentAction(string myID)
{
//--- Build & Run SQL Select Statement...
using (var myContext = new DB_136837_byogaContext())
{
//--- Update Info for Selected Student...
var myQuery = (from d in myContext.ByStudents where d.SId == Convert.ToInt32(myID) select d).Single();
myQuery.SFirst = this.SFirst;
myQuery.SLast = this.SLast;
myQuery.SStreet = this.SStreet;
myQuery.SCity = this.SCity;
myQuery.SState = this.SState;
myQuery.SZip = this.SZip;
myQuery.SCell = this.SCell;
myQuery.SHome = this.SHome;
myQuery.SEmail = this.SEmail;
myQuery.SNote = this.SNote;
myContext.ByStudents.Update(myQuery);
myContext.SaveChanges();
}
//--- Close the Popup...
this.Close();
//--- Refresh Page...
await InvokeAsync(() =>
{
StateHasChanged();
this.OnInitialized();
});
//--- Refresh Page by Reloading...SHOULD NOT HAVE TO DO THIS!
//NavigationManager.NavigateTo("Refresh/Students2");
}
}
Any and all help is appreciated. Thanks!
On your add/update page, after you are done with your operation and you are navigating back to your list, add the 'true' parameter to force a reload of the list page.
NavigationManager.NavigateTo("students", true);
See this link
If I understand correctly, you have a child component modal that handles the crud responsible for data displayed by a parent component.
I believe if you call StateHasChanged() from a child component the state is updated in the child component's scope unless the parent is notified its state should be updated. I would try adding an eventcallback from your child component modal to the parent that triggers a StateHasChanged() on the parent level. You could manually invoke the callback on any child crud methods after the work is done.
Something similar to this: Blazor - Execute a parent component's method when a child component onclick event occurs
Related
I am new to ASP.NET Core MVC, and I want to see if it ok to implement sorting and to filter this way. I have seen Microsoft tutorials about it, but I could not implement it like them.
The context will be changed later with View Model.
Index view:
#model ProductListVM
#{
}
<h2>All Products</h2>
<hr />
<form class="row form-inline" onsubmit="onSubmit()" asp-action="Index" method="get" id="productsForm">
<div class="col-sm-2">
<select class="form-select" asp-for="CategoryId" onchange="filterAndSortProducts()" asp-items="ViewBag.Categories" style="width: 100%;">
<option>Select Category</option>
</select>
</div>
<div class="col-sm-2">
<select asp-for="SortParam" onchange="filterAndSortProducts()" class="form-select" style="width: 100%;" asp-items="ViewBag.SortItems">
<option value="">Sort By</option>
</select>
</div>
<div class="col-sm-3">
<div class="input-group">
<input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search" name="SearchString" value="#ViewData["CurrentFilter"]" />
<button class="btn btn-outline-primary my-2 my-sm-0" type="submit" onsubmit="onsubmit()">Search</button>
</div>
</div>
</form>
<hr />
<div class="row">
#foreach(var item in Model.Products) {
<div class="col-md-3 col-sm-6">
<div class="product-grid">
<div class="product-image">
<a href="#" class="image">
<img class="pic-1" src="~/images/#item.ImagePath">
</a>
#if(item.IsOnSale) {
<span class="product-sale-label">Sale!</span>
}
<ul class="product-links">
<li><i class="fa fa-shopping-bag"></i> Add to cart</li>
<li><i class="fa fa-search"></i>Quick View
</li>
</ul>
</div>
<div class="product-content">
<h3 class="title">#item.Name</h3>
<div class="price">#if (item.IsOnSale)
{
<span>$#item.Price</span>
} $#item.CurrentPrice</div>
</div>
</div>
</div>
}
</div>
<script>
function filterAndSortProducts(e) {
var form = document.getElementById("productsForm");
form.submit();
}
function onSubmit(e) {
e.preventDefault();
}
</script>
View Model:
namespace ECommerce.Common.Models
{
public class ProductListVM
{
public string? SortParam { get; set; }
public int CategoryId { get; set; }
public List<ProductVM>? Products { get; set; }
}
}
Controller, Index action:
public async Task<IActionResult> Index(string searchString, ProductListVM model)
{
var sortParam = model.SortParam;
var categoryFilterId = model.CategoryId;
ViewData["CurrentFilter"] = searchString;
var products = new List<Product>();
if (!string.IsNullOrEmpty(searchString))
{
products = await productRepository.GetAllWithSearchStringAsync(searchString);
}
else
{
products = await productRepository.GetAllAsync();
};
switch (sortParam)
{
case "price_desc":
products = products.OrderByDescending(s => s.Price).ToList();
break;
case "price_asc":
products = products.OrderBy(s => s.Price).ToList();
break;
case "date_desc":
products = products.OrderByDescending(s => s.DateCreated).ToList();
break;
case "date_asc":
products = products.OrderBy(s => s.DateCreated).ToList();
break;
default:
products = products.OrderBy(s => s.DateCreated).ToList();
break;
}
if(categoryFilterId != 0)
products = products.Where(q => q.ProductCategoryId == categoryFilterId).ToList();
ViewBag.SortItems = new List<SelectListItem>()
{
new SelectListItem() { Text = "Price: Highest to Lowest", Value = "price_desc"},
new SelectListItem() { Text = "Price: Lowest to Highest", Value = "price_asc"},
new SelectListItem() { Text = "Date: Newest to Oldest", Value = "date_desc"},
new SelectListItem() { Text = "Date: Oldest to Newest", Value = "date_asc"},
};
ViewBag.Categories = new SelectList(context.Categories, "Id", "Name");
model = new ProductListVM
{
Products = mapper.Map<List<ProductVM>>(products)
};
return View(model);
}
Dates also will be changed, it is just an example at the moment.
Any suggestion, critique, or tip is helpful. I am in learning progress.
I think your using EF and the productRepository is a DBContext. This gives you back a IEnumerable which is only evaluatet if you use the Data. My Tipp for you to call .ToList() just in the End. It makes a big difference in performance.
List<Product> products = productRepository.Products;
if (!string.IsNullOrEmpty(searchString))
{
products = await products.WhereAsync(p = p.Where(s => s.Name.Contains(searchString)));
}
if (categoryFilterId != 0)
{
products = products.Where(q => q.ProductCategoryId == categoryFilterId);
}
switch (model.SortParam)
{
case SortOrder.price_desc:
products = products.OrderByDescending(s => s.Price);
break;
case SortOrder.price_asc:
products = products.OrderBy(s => s.Price);
break;
case SortOrder.date_desc:
products = products.OrderByDescending(s => s.DateCreated);
break;
default:
products = products.OrderBy(s => s.DateCreated);
break;
}
I would also use a Enum for you SortParam.
public enum SortOrder
{
price_desc,
price_asc,
date_desc,
date_asc
}
Hope that helps
I have the following application, where I have to upload an image directly from modal to the page.
Note that:
The image is already uploaded by the admin to this modal.
The images are saved in "static" file in "wwwroot" folder. So, No database is required for this step.
All what I need is when I click in the image in the modal, it should be uploaded to the view. So, I can save it later in the database.
Here is Image Bank Controller
public IActionResult Index()
{
var webRoot = _hostingEnvironment.WebRootPath;
var appData = System.IO.Path.Combine(webRoot, "static");
var files = Directory.GetFiles(appData, "*.*", SearchOption.AllDirectories);
var model = new ImageBankViewModel()
{
ImagesListUrls = files.Select(i=>Path.GetFileName(i))
};
return View(model);
}
[HttpPost]
public IActionResult Upload(ImageBankViewModel model)
{
if (ModelState.IsValid)
{
if (model.Image != null)
{
string webRootPath = _hostingEnvironment.WebRootPath;
var path = Path.Combine(webRootPath, "static");
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
var extension = Path.GetExtension(model.Image.FileName);
var newFileName = model.Type + "-" + DateTime.Now.Ticks;
using (var filesStream = new FileStream(Path.Combine(path, newFileName + extension), FileMode.Create))
{
model.Image.CopyTo(filesStream);
}
return RedirectToAction("Index");
}
}
ImageBankViewModel modelVM = new ImageBankViewModel()
{
Image = model.Image,
ImagesListUrls = model.ImagesListUrls,
Type = model.Type
};
return RedirectToAction("Index",modelVM);//Unsuccessful Upload , fix invalid model
}
public IActionResult CreateStory()
{
return View();
}
public ActionResult GetImagesPartial()
{
var webRoot = _hostingEnvironment.WebRootPath;
var appData = System.IO.Path.Combine(webRoot, "static");
var files = Directory.GetFiles(appData, "*.*", SearchOption.AllDirectories);
var model = new ImageBankViewModel()
{
ImagesListUrls = files.Select(i => Path.GetFileName(i))
};
return PartialView("_ImagesBankModal",model);
}
public void ImageDelete(string image)
{
}
public void SelectImage(string image)
{
// Here I want to get the selected image from the modal
}
}
}
Create Story View
#{
ViewData["Title"] = "CreateStory";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h1>CreateStory</h1>
<div class="row">
<div class="col-md-1">
<label>Pic1</label>
</div>
<div class="col-md-8">
<input type="file" accept="image/*" class="form-control" />
</div>
<div class="col-md-3">
<a class="btn btn-outline-dark" asp-area="" asp-controller="Bank" asp-action="GetImagesPartial" data-toggle="modal" data-target="#myModal" id="sel">Select from image bank</a>
<div class="modal" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div id="partial"></div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-1">
<label>Pic2</label>
</div>
<div class="col-md-8">
<input type="file" accept="image/*" class="form-control" />
</div>
<div class="col-md-3">
<button class="btn btn-outline-dark">Select from image bank</button>
</div>
</div>
#section Scripts{
<script type="text/javascript">
$(function () {
$('#sel').click(function () {
var route = '#Url.Action("GetImagesPartial", "Bank")';
$('#partial').load(route);
});
});
</script>
}
Modal Partial View
#model TestApplication.Models.ViewModels.ImageBankViewModel
<div class="modal-header">
<h2 class="modal-title">Choose</h2>
</div>
<div class="modal-body">
#if (Model.ImagesListUrls.Any())
{
<table>
#foreach (var image in Model.ImagesListUrls)
{
<tr>
<td>
<a asp-area="" asp-controller="Bank" asp-action="SelectImage" asp-route-image="#image" class="btn btn-light position-absolute" style="right:0">Select</a>
<img src="~/static/#image" class="img-thumbnail" />
</td>
</tr>
}
</table>
}
else
{
<h5>no images exists...</h5>
}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-success" data-dismiss="modal">Cancel</button>
</div>
You can store the relative path of the selected picture in an input and pass them to the action.
The following is an example, you can refer to it.
Index
<form asp-action="Upload" asp-controller="ImageBank" method="post" enctype="multipart/form-data">
<div class="row">
<div class="col-md-1">
<label>Pic1</label>
</div>
<div class="col-md-8">
<input type="file" accept="image/*" class="form-control" name="model.Image"/>
<ul class="selectedpic">
</ul>
</div>
<div class="col-md-3">
<a class="btn btn-outline-dark sel">Select from image bank</a>
</div>
<div class="col-md-8 addedimg">
</div>
</div>
<div class="modal" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div id="partial"></div>
</div>
</div>
</div>
<button type="submit">submit</button>
</form>
#section Scripts{
<script type="text/javascript">
var currentsel="";
$('body').on("click",".sel",function () {
localStorage.setItem("currentsel",$(this).attr("class"));
var route = '#Url.Action("GetImagesPartial", "ImageBank")';
$("#myModal").modal("show");
$('#partial').load(route);
});
$('body').on("click",".selectbtn",function () {
var currenttd=$(this).closest("td");
console.log(currenttd.find("img").attr("src"))
var classarry=localStorage.getItem("currentsel").split(" ");
var currentsel="."+classarry[classarry.length-1];
var currentaddedimg=$(currentsel).closest(".row").find(".addedimg");
var addsrc=currenttd.find("img").attr("src");
if(checkisexsist(currentaddedimg,addsrc)){
$(currentsel).closest(".row").find(".selectedpic").append("<li>"+addsrc+"</li>");
$(currentsel).closest(".row").find(".addedimg").append("<input hidden name='selimages' value='"+addsrc+"'/>");
$("#myModal").modal("hide");
$('#myModal').on('hidden.bs.modal', function (e) {
localStorage.removeItem("currentsel");
});
}else{
alert("has selected");
}
});
function checkisexsist(currentaddedimg,addsrc){
var flag=true;
$.each(currentaddedimg.find("input[name='selimages']"), function( index, value ) {
if($(value).val()==addsrc){
flag=false;
}
});
return flag;
}
</script>
}
Controller
[HttpPost]
public IActionResult Upload(ImageBankViewModel model,List<string> selimages)
{
if (ModelState.IsValid)
{
if (model.Image != null)
{
string webRootPath = _hostingEnvironment.WebRootPath;
var path =Path.Combine(webRootPath, "static");
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
var extension = Path.GetExtension(model.Image.FileName);
var newFileName = model.Type + "-" + DateTime.Now.Ticks;
using (var filesStream = new FileStream(Path.Combine(path, newFileName + extension), FileMode.Create))
{
model.Image.CopyTo(filesStream);
}
}
if(selimages!=null& selimages.Count != 0)
{
string webRootPath = _hostingEnvironment.WebRootPath;
var path = Path.Combine(webRootPath, "static");
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
selimages.ForEach(m =>
{
var newFileName = Guid.NewGuid().ToString();
var extension = "." + m.Split(".")[m.Split(".").Length - 1];
var oldpath =webRootPath+m.Replace("/", "\\"); var newpath = Path.Combine(path, newFileName + extension);
System.IO.File.Copy(oldpath,newpath);
});
}
return RedirectToAction("Index");
}
ImageBankViewModel modelVM = new ImageBankViewModel()
{
Image = model.Image,
ImagesListUrls = model.ImagesListUrls,
Type = model.Type
};
return RedirectToAction("Index", modelVM);//Unsuccessful Upload , fix invalid model
}
_ImagesBankModal(Only give the modified place)
<a class="btn btn-light position-absolute selectbtn">Select</a>
Result
I have problem regarding showing correct time in IndexPage. When I create Patient I want to be display DateTime, currently It is only represent Date but in Index Page I get time.
What I try so far is to add DataAnnotation in my Model something like:
public class AdmissionPacients
{
[Key]
public int Id { get; set; }
[Required]
[Display(Name = "Date and Time")]
//[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
//[DataType(DataType.Date)]
public DateTime DateAndTime { get; set; }
[Required]
[Display(Name = "Emergency Admission")]
public bool Emergency { get; set; }
public string Image { get; set; }
// Doctor
[Display(Name = "Doctor Name")]
public int DoctorId { get; set; }
[ForeignKey("DoctorId")]
public virtual Doctor Doctor { get; set; }
//Patient
[Display(Name = "Patient Name")]
public int PatientId { get; set; }
[ForeignKey("PatientId")]
public virtual Patient Patient { get; set; }
}
Create.cshtml
#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" type="text" class="form-control datepicker">
</div>
</div>
#*<div class="form-group row py-2">
<div class="col-4">
<label asp-for="AdmissionPatient.DateAndTime"></label>
</div>
<div class="col-8">
<input asp-for="AdmissionPatient.DateAndTime" class="form-control datepicker" />
<span asp-validation-for="AdmissionPatient.DateAndTime" class="text-danger"></span>
</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 asp-for="AdmissionPatient.Emergency" 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 src="~/js/admissionPatient.js"></script>
}
Index
<div class="container p-3 bg-white">
<div class="row pt-4">
<div class="col-6">
<h2 class="text-primary">Admission Patient List</h2>
</div>
<div class="col-6 text-right">
<a asp-action="Upsert" class="btn btn-primary">
<i class="fas fa-plus"></i> Create New Doctor
</a>
</div>
</div>
<br /><br />
#*<form asp-action="Index">
<p>
Date From: <input type="datetime" name="search" />
Date To: <input type="datetime" name="search">
<input type="submit" value="Search" />
</p>
</form>*#
#if (Model.Count() > 0)
{
<table id="tblData" class="table table-striped border" style="width:100%">
<thead>
<tr class="table-dark">
<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>
#if (obj.Emergency == true)
{
<td width="25%" class="blink_me"><span class="blink_me">Emergency</span></td>
}
else
{
<td width="25%"><span class="text-info">#obj.Emergency</span></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>
}
</div>
#section Scripts{
<script src="~/js/admissionPatient.js"></script>
}
Controller
public class AdmissionPatientController : Controller
{
private readonly ApplicationDbContext _db;
private readonly IWebHostEnvironment _webHostEnvironment;
public AdmissionPatientController(ApplicationDbContext db, IWebHostEnvironment webHostEnvironment)
{
_db = db;
_webHostEnvironment = webHostEnvironment;
}
public IActionResult Index(string search)
{
IEnumerable<AdmissionPacients> admissionPatient = _db.AdmissionPacients
.Include(u => u.Patient)
.Include(d => d.Doctor);
if (!string.IsNullOrEmpty(search))
{
if (DateTime.TryParse(search, out var dateTime))
{
admissionPatient = admissionPatient.Where
(x => x.DateAndTime.ToShortDateString().Equals(dateTime.ToShortDateString())).ToList();
}
}
return View(admissionPatient);
}
//UPSERT GET
//UPdate and insERT
public IActionResult Upsert(int? Id)
{
AdmisionVM admissionVM = new AdmisionVM
{
AdmissionPatient = new AdmissionPacients(),
PatientSelectList = _db.Patients.Select(i => new SelectListItem
{
Text = i.FirstName + i.LastName,
Value = i.Id.ToString()
}),
DoctorSelectList = _db.Doctors.Select(i => new SelectListItem
{
Text = i.Firstname + i.Lastname,
Value = i.Id.ToString()
})
};
AdmissionPacients admissionPatient = new AdmissionPacients();
if (Id == null)
{
// this is for create
return View(admissionVM);
}
else
{
// this is for edit
admissionVM.AdmissionPatient = _db.AdmissionPacients.Find(Id);
if (admissionVM.AdmissionPatient == null)
{
return NotFound();
}
return View(admissionVM);
}
}
[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);
}
//GET - DELETE
public IActionResult Delete(int? id)
{
if (id == null || id == 0)
{
return NotFound();
}
AdmissionPacients admissionPatient = _db.AdmissionPacients
.Include(u => u.Patient)
.Include(d => d.Doctor)
.FirstOrDefault(u => u.Id == id);
if (admissionPatient == null)
{
return NotFound();
}
return View(admissionPatient);
}
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public IActionResult DeleteAdmission(int? Id)
{
var obj = _db.AdmissionPacients.Find(Id);
if (obj == null)
{
return NotFound();
}
string upload = _webHostEnvironment.WebRootPath + Constans.imagePath;
var oldfile = Path.Combine(upload, obj.Image);
if (System.IO.File.Exists(oldfile))
{
System.IO.File.Delete(oldfile);
}
_db.AdmissionPacients.Remove(obj);
_db.SaveChanges();
return RedirectToAction("Index");
}
}
Nothing works!
So I want as user to be able to select DateTime and this DateTime needs to be represent in IndexPage
Anyone know where did I make mistake ? What I made wrong here ?
I think you should use DateTime.ToString() formatting. There are many formats of datetimes are available in C# . Please check the link => DateTime Formatting Link
DateTime DateAndTime = new DateTime(2020, 5, 29, 5, 50, 0);
DateAndTime.ToString("dddd, dd MMMM yyyy");//Output:Friday, 29 May 2020 05:50
DateAndTime.ToString("dddd, dd MMMM yyyy");//Output:Friday, 29 May 2020 05:50 AM
DateAndTime.ToString("dddd, dd MMMM yyyy");//Output:Friday, 29 May 2020 5:50
DateAndTime.ToString("dddd, dd MMMM yyyy");//Output:Friday, 29 May 2020 5:50 AM
DateAndTime.ToString("dddd, dd MMMM yyyy HH:mm:ss");//Output:Friday, 29 May 2020 05:50:06
DateAndTime.ToString("MM/dd/yyyy HH:mm");//Output:05/29/2020 05:50
DateAndTime.ToString("MM/dd/yyyy hh:mm tt");//Output:05/29/2020 05:50 AM
DateAndTime.ToString("MM/dd/yyyy H:mm");//Output:05/29/2020 5:50
DateAndTime.ToString("MM/dd/yyyy h:mm tt");//Output:05/29/2020 5:50 AM
DateAndTime.ToString("MM/dd/yyyy HH:mm:ss");//Output:05/29/2020 05:50:06
Note: Here Outputs are dummy data output. Please check your code with "ToString" and let me know.
OR
You can use Annotation too like=>
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:yyyy-MM-ddTHH:mm:ss}")]`
OR
You can also check that link to on stackoverflow. Link
How to get the data-id sent to another controller in ASP.NET MVC?
The employee submits the form, automatically determines the id and department position, and then sends it to the manager for approval.
The manager clicks approval or reject on this page, and the form is sent to the next person for approval. At this step, the page prompts that id = null cannot be run. What should I do?
But Google background shows that I got this Id, how to send this Id to action?
public PartialViewResult saveStatus(int id, string Status, string AddDate, string Remark)
{
int approvalId;
if (id == 0 && Session["AppId"] == null)
{
var staff = db.Staffs.Where(s => s.UserName == User.Identity.Name).FirstOrDefault();
RequestForApproval ap = new RequestForApproval
{
RequestToStaffId = staff.Id,
RequestDate = DateTime.Now,
};
db.RequestForApprovals.Add(ap);
db.SaveChanges();
Session["AppId"] = ap.ReimbursementID;
approvalId = ap.Id;
}
else
{
approvalId = int.Parse(Session["AppId"].ToString());
}
ApprovalStatus temp = new ApprovalStatus
{
Id = approvalId,
Remark = Remark,
AddDate = DateTime.Now
};
db.ApprovalStatuses.Add(temp);
db.SaveChanges();
var df = db.ApprovalStatuses.Where(s => s.Id == approvalId).ToList();
return PartialView(df);
}
public JsonResult CreateStatus()
{
List<ApprovalStatus> mv = new List<ApprovalStatus>();
if(Session["AppId"] == null)
{
ViewBag.Ae = 0;
}
else
{
ViewBag.Ae = Session["AppId"];
int approvalId = int.Parse(Session["AppId"].ToString());
mv = db.ApprovalStatuses.Where(s => s.Id == approvalId).ToList();
}
return Json(mv);
}
public ActionResult AddRequestForApproval()
{
// var staffUser = db.StaffPositions.Where(a => a.Staff.UserName == System.Web.HttpContext.Current.User.Identity.GetUserId());
var rmid = Session["RmId"].ToString();
if (string.IsNullOrEmpty(rmid))
{
return RedirectToAction("Index");
}
int reimbursementId = int.Parse(rmid);
Session["RmId"] = null;
var Res = db.Reimbursements.Find(reimbursementId);
var managerId = GetByStaffId(Res.StaffId,reimbursementId);
RequestForApproval temp = new RequestForApproval();
temp.ReimbursementID = reimbursementId;
temp.RequestDate = DateTime.Now;
temp.RequestToStaffId = managerId;
db.RequestForApprovals.Add(temp);
db.SaveChanges();
return RedirectToAction("Index");
}
View:
#model Reimbursements.Models.RequesViewModel
#{
ViewBag.Title = "Index";
var add = Session["AppId"];
}
<h2>Index</h2>
<table class="table" id="table1">
<tr>
<th></th>
<th>
Staff Fname
</th>
<th>
RequestDate
</th>
<th></th>
</tr>
#foreach (var item in Model.GetReApproval)
{
<tr>
<td>
#item.ReimbursementId
</td>
<td>
#item.StaffName
</td>
<td>
#item.RequestDate
</td>
<td>
<button type="button" class="btn btn-primary" data-toggle="modal" data-id="#item.RequerForApprovalId" data-target="#exampleModal" id="SelectBtn">Select</button>
<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" id="Title">Select and Confirm</h4>
</div>
<div class="modal-body">
<form>
<div class="form-group" >
<input type="hidden" id="Reid" />
#Html.DropDownList("ApprovalStatus", null, new { #class = "btn btn-info",id="enumId" })
#*#Html.DropDownList("Index", ViewBag.DropDownList as SelectList,null, new { #class = "btn btn-info",#id="DropDownList" })*#
</div>
<hr />
<div class="form-group" style="visibility:visible" id="remarktext">
<label for="message-text" class="control-label">Remark:</label>
<textarea class="form-control" id="message-text" ></textarea>
</div>
</form>
</div>
<div class="modal-footer">
#*<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Confirme</button>*#
<button data-id="#item.ReimbursementId" class="btn btn-primary" id="Submit" #*onclick="location.href='#Url.Action("AddRequestForApproval","Reimbursements")'"*#>Submit</button>
<button class="btn btn-default" data-dismiss="modal" type="reset" id="Clear">Close</button>
</div>
</div>
</div>
</div>
</td>
</tr>
}
</table>
#section Scripts {
<script src="~/Scripts/jquery-3.3.1.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$("#table1").on('click', '#SelectBtn', function () {
$('#Submit').click('#enumId', function () {
var bid = $(this).attr('data-id');
var status = $("#enumId option:selected").val();
var mess = $('#message-text').val();
var Rmid;
console.log(bid, status, mess);
// var b = $("#NewId");
#*if ($("#NewId").val() == undefined) {
Rmid = 0;
} else {
Rmid = $("#NewId").val();
}
$.ajax({
type: 'POST',
dataType: 'html',
url: '#Url.Action("saveStatus")',
data: { id: bid, status: status, Remark: mess },
success: function (data) {
console.log(data);
status.val('').url(data);
mess.val('');
}, error: function (data) {
alert("error");
},
})*#
})
})
})
</script>
}
Instead of putting data-id there, you can just put it as value of a hidden filed in your form so that it gets posted when the form submitted:
<input type = "hidden" name="id" value="#item.ReimbursementId" />
If the value may change that you want to send different values when different buttons are clicked, then you can have a hidden input and set its value before submit:
$('#Submit').click('#enumId', function () {
var bid = $(this).data('id');
$('[name="id"]').val(bid);
// rest of your code....
});
Edit: if you are going to post it with ajax, please note that you should get data like:
$(this).data('id');
I am trying to save data and edit that data using the button with Id btnSaveAnContinue. Now, whenever I click on Save And Continue button to save data, the command parameter in post method i.e gets Saveandcontinue which is defined in the button as per required.
But whenever, I try to edit the data and save it by clicking on same button, the command parameter in AddEdit POST method does not get Saveandcontinue, it is null.
The View:
<form asp-controller="Doctor" asp-action="AddEdit" method="post" class="form-horizontal" id="DoctorAddEdit" role="form">
#Html.HiddenFor(c => c.DoctorId)
<div class="m-b-md heading-tp-cls">
<h3 class="m-b-none pull-left">Doctor Information <small id="currentUsersInCase"></small></h3>
<div class="doc-buttons pull-right relative">
<button type="submit" class="btn btn-s-md btn-success saveButton" id="btnSave"><i class="fa fa-save fa-fw"></i>Save And Close</button>
<button type="submit" name="command" value="Saveandcontinue" id="btnSaveAnContinue" class="btn btn-s-md btn-success saveButton "><i class="fa fa-save fa-fw"></i>Save And Continue</button>
</div>
<div class="clearfix"></div>
</div>
<section class="panel panel-default tp-section-cls no-left-right-borders" style="padding-top: 10px;">
<div class="row m-l-none m-r-none bg-light lter">
<section>
<div class="col-lg-2 col-md-2 col-sm-6 error-holder-form hideSubject" id="claimanatFirstNameDiv">
<label>First Name<span class="requAstrik">*</span></label>
<input asp-for="FirstName" id="DFirstName" class="form-control subjectHide" placeholder="" type="text">
<span asp-validation-for="FirstName" class="text-danger error"></span>
</div>
<div class="col-lg-2 col-md-2 col-sm-6 hideSubject" id="claimanatMiddleInitialDiv">
<label>Middle Name</label>
<input asp-for="MiddleInitial" id="DMidName" class="form-control subjectHide" placeholder="" type="text">
</div>
</section>
</div>
</section>
</form>
GET method for AddEdit:
public IActionResult AddEdit(int id = 0, bool flag = false)
{
var getDoctorById = _doctorService.GetDoctorInfoById(id);
return View(getDoctorById);
}
POST method for AddEdit:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> AddEdit(DoctorInfoModel doctorInfo, string command)
{
bool isAjaxCall = HttpContext.Request.Headers["x-requested-with"] == "XMLHttpRequest";
if (isAjaxCall)
{
return Content("Saved");
}
if (ModelState.IsValid)
{
var result = 0;
int userId = User.GetUserId();
doctorInfo.CreatedBy = userId;
var saveAndGetUserId = 0;
if (doctorInfo.DoctorId == 0)
{
saveAndGetUserId = _doctorService.SaveUserInfo(doctorInfo);
var user = new ApplicationUser { UserName = doctorInfo.UserName, Email = doctorInfo.DocEmail, UserId = saveAndGetUserId };
var getResult = await _userManager.CreateAsync(user, doctorInfo.Password);
_doctorService.SaveUserRole(user.Id);
}
else
{
var getUserId = _doctorService.GetUser(doctorInfo);
var user = _userManager.Users.FirstOrDefault(c => c.UserId == getUserId);
user.UserName = doctorInfo.UserName;
user.Email = doctorInfo.DocEmail;
if (doctorInfo.Password != null && !"Password#123".Equals(doctorInfo.Password))
{
user.PasswordHash = _userManager.PasswordHasher.HashPassword(user, doctorInfo.Password);
}
try
{
var result1 = await _userManager.UpdateAsync(user);
}
catch (Exception ex)
{
throw;
}
}
var getSaveResult = _doctorService.SaveDoctor(doctorInfo, saveAndGetUserId);
if (getSaveResult.Id > 0)
{
Success(getSaveResult.MessageBody);
}
else
{
Warning(getSaveResult.MessageBody);
}
if (command == "Saveandcontinue")
{
return RedirectToAction(nameof(DoctorController.AddEdit), new { id = getSaveResult.Id, flag = true });
}
else
{
return RedirectToAction(nameof(HomeController.Index), "Doctor");
}
}
Warning("Failed to save Doctor, try again later.");
return View("AddEdit", doctorInfo);
}