Using ng-repeat to create ng-tables which display info from a List - html

I have a Person object, which has a list of Reports.
public class Person
{
public string IdNum { get; set; }
public string LastName { get; set; }
public Int32 LocFlag { get; set; }
public IList<Report> Reports { get; set; }
}
public class Report
{
public long ReportNum { get; set; }
public DateTime? ReceivedDate { get; set; }
public string Subject { get; set; }
}
I have a list of these people from my controller - vm.Persons and vm.PersonParams.
My intention is to produce a seperate ng-table for each Person, each table should display information from their Reports.
The method I'm using now produces a single empty table:
<div class="table-responsive">
<table ng-table="vm.PersonParams" class="table table-hover">
<tr ng-repeat="row in $data">
<td data-title="'Report Number'" >{{row.Reports.ReportNum }} </td>
<td data-title="'Date'" >{{row.Reports.ReceivedDate }} </td>
<td data-title="'Subject'" >{{row.Reports.Subject }} </td>
</tr>
</table>
</div>
Values of Persons and PersonParams:
vm.Persons = [{"IdNum ":"23713","LastName ":"Smith","LocFlag":0,"Reports":[{"ReportNum":321231,"ReceivedDate":"2010-09-16T15:25:00","Subject":"Tax",}]},{"IdNum":"32552","LastName":"Xavier","LocFlag":1,"Reports":[{"ReportNum":324342,"ReceivedDate":"2013-09-11T07:50:00","Subject":"Filing Request"}]}];
vm.PersonParams = {"data":[]};

If it's the total code you are using, then you missed ng-repeat in the outer div. What is $data here? Probably you made a mistake over there too.
You might need to use it as shown below
<div class="table-responsive" ng-repeat = "person in vm.Persons">
<table class="table table-hover">
<tr ng-repeat="report in person.Reports">
<td data-title="'Report Number'" >{{report.ReportNum }} </td>
<td data-title="'Date'" >{{report.ReceivedDate }} </td>
<td data-title="'Subject'" >{{report.Subject }} </td>
</tr>
</table>
</div>
Let me know if this helps!

Related

Returning the property of another model that is bound to a Model in the first model

I'm trying to access the Question list from within the TestModel and return the QuestionModel's Property.
I need to return it in the TestModel to determine the questions to be contained in a test, but I can't, I can't find where I went wrong.
public class TestModel
{
public int Id { get; set; }
public string Name { get; set; }
public List<QuestionModel> Question { get; set; }=new List<QuestionModel>();
}
public class QuestionModel
{
public int Id { get; set; }
public AppUser User { get; set; }
public string Question { get; set; }
public bool check { get; set; }
public List<TestModel>? Tests { get; set; } = new List<TestModel>();
}
I used TestModel as one of the tuple objects.
Since the code is long, I only shared the area where I had problems.
#model Tuple<IList<TestModel>,IList<UserViewModel>>
<table class="table table-striped">
#{
int i = 0;
}
#foreach (var item in Model.Item1)
{
<form id="form[#i]" class="container m-xl-2">
<tr id="Allquest_#i" hidden="hidden">
<td colspan="5">
<div>
<input asp-for=#Model.Item1[i].Id hidden>
#for (int indexQuest = 0; indexQuest < item.Question.Count; indexQuest++)
{
<input type="checkbox" asp-for="#Model.Item1[i].Question[indexQuest].check" checked="#Model.Item1[i].Question[indexQuest].check">
<a>#Model.Item1[i].Question[indexQuest].Question</a>
<br />
}
</div>
</td>
<td>
<button type="submit" asp-controller="Test" asp-action="DeleteQuestionToTest" formmethod="post" class="btn btn-danger">Seçili Soruları Sil</button>
</td>
</tr>
</form>
i++;
}
Here I tried to capture it as a TestModel. I tried to capture it as a list and as a single model, but I couldn't.
[HttpPost]
public IActionResult DeleteQuestionToTest([Bind(Prefix ="Item1")] IList<TestModel> tests)
{
return View();
}
How can I fix the code?
I came up with a workaround by creating a separate form and specifying it in the html of the models.
#model Tuple<IList<TestModel>,IList<UserViewModel>>
<table class="table table-striped">
#{
int i = 0;
}
<form id="MainForm" asp-controller="Test" asp-action="DeleteQuestionToTest" formmethod="post"></form>
#foreach (var item in Model.Item1)
{
<form id="form[#i]" class="container m-xl-2">
<tr id="Allquest_#i" hidden="hidden">
<input asp-for=#Model.Item1[i].Id form="MainForm" hidden>
<td colspan="5">
<div>
#for (int indexQuest = 0; indexQuest < item.Question.Count; indexQuest++)
{
<input asp-for="#Model.Item1[i].Question[indexQuest].Id" form="MainForm" hidden>
<input type="checkbox" asp-for="#Model.Item1[i].Question[indexQuest].check" form="MainForm" checked="#Model.Item1[i].Question[indexQuest].check">
<a>#Model.Item1[i].Question[indexQuest].Question</a>
<br />
}
</div>
</td>
<td>
<button type="submit" form="MainForm" class="btn btn-danger">Seçili Soruları Sil</button>
</td>
</tr>
</form>
i++;
}
I returned all the tests this was a workaround, I have no idea how to return a single test.

Change the HTML element in a Blazor application by pressing a button?

I wanted to ask if it is possible to change the type of an HTML element in a Blazor application by pressing a button.
That I turn a normal text into a text input field for example.
I have a table where the first column has a button for each entry in the table.
My goal is that when you press the button, the fields turn into input fields in time, so you can edit the values.
This is just a quick photo edit, but this is how I imagined it.
You can use an index array to track the edit status of each company. When the button is clicked, the corresponding value in the index array will be toggled. If the value is set to true, the cell will display an input field where you can edit the company name. The updated name will be saved to the list.
Instead of using a simple string to store company information, you can create a class that contains multiple properties such as the company name and location..
Output:
Demo: https://blazorfiddle.com/s/lil3olrf
Implementation:
#page "/"
<h3>Companies</h3>
<table class="table table-bordered table-sm">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Company</th>
<th scope="col">Location</th>
</tr>
</thead>
<tbody>
#foreach (var company in Companies)
{
var index = Companies.IndexOf(company);
<tr>
<td>
<button type="button" class="btn btn-primary"
#onclick="#(() => { Edits[index] = !Edits[index]; })">
#(Edits[index] ? "Back" : "Edit")
</button>
</td>
<td>
#if (Edits[index])
{
<input class="form-control" type="text"
style="background-color:lightyellow;"
value="#company.Name"
#oninput="#(e => { Companies[index].Name = e.Value.ToString(); })"/>
}
else
{
#company.Name
}
</td>
<td>
#if (Edits[index])
{
<input class="form-control" type="text"
style="background-color:lightyellow;"
value="#company.Location"
#oninput="#(e => { Companies[index].Location = e.Value.ToString(); })"/>
}
else
{
#company.Location
}
</td>
</tr>
}
</tbody>
</table>
<ul>
#*Check realtime changes to Company names when you edit them*#
#foreach (var company in Companies)
{
<li>#company.Name: #company.Location</li>
}
</ul>
#code {
private List<Company> Companies { get; set; } = new List<Company>
{
new Company("Globex Corporation", "Germany"),
new Company("Soylent Corp", "Switzerland"),
new Company("Umbrella Corporation", "Netherlands")
};
private bool[] Edits { get; set; }
protected override void OnInitialized()
{
Edits = new bool[Companies.Count];
}
public class Company
{
public Company(string name, string location)
{
Name = name;
Location = location;
}
public string Name { get; set; }
public string Location { get; set; }
}
}
Here's a basic component and demo page to demonstrate how you can do this. There's a component and a demo page.
#page "/"
<div>
<button class="btn btn-dark" disabled="#isEdit" #onclick="GoEdit">Edit</button>
#if (this.isEdit)
{
#EditControl
}
else
{
#ViewControl
}
</div>
#code {
[Parameter] public RenderFragment ViewControl { get; set; }
[Parameter] public RenderFragment EditControl { get; set; }
protected string disabled => isEdit ? "disabled": "";
protected bool isEdit { get; set; }
private void GoEdit(MouseEventArgs e)
=> isEdit = !isEdit;
}
And a demo page:
#page "/Demo"
<h3>EditorTest</h3>
<CascadingValue Value="model">
<EditForm EditContext="editContext">
<EditFormState #ref="editFormState" EditStateChanged="EditStateChanged"></EditFormState>
<div>
<SwitchedEditorComponent>
<EditControl>
Email: <InputText #bind-Value="model.Email" placeholder="Enter your Email Address"></InputText>
</EditControl>
<ViewControl>
Email: <InputText #bind-Value="model.Email" disabled></InputText>
</ViewControl>
</SwitchedEditorComponent>
</div>
</EditForm>
</CascadingValue>
#code {
private dataModel model { get; set; } = new dataModel();
private EditFormState editFormState;
private EditContext editContext;
protected override Task OnInitializedAsync()
{
this.editContext = new EditContext(model);
return base.OnInitializedAsync();
}
private void EditStateChanged(bool editState)
{
StateHasChanged();
}
public class dataModel
{
public string Email { get; set; }
}
}

ASP.NET Core : moving data from one table into another

I'm currently developing an e-commerce website using ASP.NET Core. I'm trying to move data from the Products table into the Items table using a button press so that the data in the items table can be presented on the basket page. Any help would be appreciated.
The relevant button is using the asp-action=AddToCart:
<div class="card-body">
<h3 class="card-title">#product.Name</h3>
<svg class="bd-placeholder-img card-img-top" width="100%" >
<img float="left" width="450" height="450" src="~/assets/Clothing/#product.ProductImage" alt="Image of #product.Name" />
</svg>
<p class="card-text">#product.Description</p>
<div class="d-flex justify-content-between align-items-center">
<div class="btn-group">
#if (User.IsInRole("Admin"))
{
<a class="btn btn-sm btn-outline-secondary" asp-page="/UpdateProductInfo"
asp-route-id="#product.Id">Update</a>
}
<a class="btn" asp-action="AddToCart">Add to Cart</a>
<p class="float-right card-text" >£#product.Price</p>
</div>
</div>
</div>
C#
[BindProperty]
public Item Items { get; set; }
public IActionResult addToCart()
{
_db.Items.Add(Items);
_db.SaveChanges();
return Page();
}
product.cs model
public class Product
{
public String Id { get; set; }
[ForeignKey("Name")]
public String Name { get; set; }
public String Description { get; set; }
[ForeignKey("Price")]
public int Price { get; set; }
[ForeignKey("ProductImage")]
public String ProductImage { get; set; }
public String ProductImageName { get; set; }
}
Item.cs model
public class Item
{
[Key]
[ForeignKey("Name")]
public String Name { get; set; }
[ForeignKey("Price")]
public int Price { get; set; }
[ForeignKey("ProductImage")]
public String ProductImage { get; set; }
}
item class must be like this :
public class Item
{
[Key]
public int ItemId { get; set; }
public Product Product { get; set; }
[ForeignKey("Product")]
public int ProductId { get; set; }
public String ProductImage { get; set; }
}
and your product class :
public class Product
{
[Key]
public int ProductId { get; set; }
public string Name{ get; set; }
public int Price { get; set; }
public int Description{ get; set; }
public string ProductImage { get; set; }
public string ProductImageName { get; set; }
}
it was a (single to single) relationship between two tables
I'm trying to move data from the Products table into the Items table
using a button press so that the data in the items table can be
presented on the basket page. Any help would be appreciated.
From your description, I assume in the main page, you are listed the Products and each row of the product will have an "Add to Cart" button, after clicking it, it will add the selected Product to the Item table, right?
Since your application is an Asp.net core Razor Page application, for the "Add to Cart" button, you could use the handler method to transfer the route parameter to the method, and then add the selected product to Item table. Refer the following sample:
Model:
public class Product
{
public String Id { get; set; }
public String Name { get; set; }
public String Description { get; set; }
public int Price { get; set; }
public String ProductImage { get; set; }
public String ProductImageName { get; set; }
}
public class Item
{
[Key]
public String Name { get; set; }
public int Price { get; set; }
public String ProductImage { get; set; }
}
ProductIndex.cshtml:
#page
#model RazorPageSample.Pages.ProductIndexModel
<div class="row">
<div class="col-md-6">
<form method="post">
<table class="table">
<thead>
<tr><th colspan="5">Product Table</th></tr>
<tr>
<th>
Product ID
</th>
<th>
Product Name
</th>
<th>
Description
</th>
<th>
Price
</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model.Products)
{
<tr>
<td>
#item.Id
</td>
<td>
#item.Name
</td>
<td class="text-right">
#item.Description
</td>
<td class="text-right">
£#item.Price
</td>
<td class="text-right">
<button asp-page-handler="AddToCart" class="btn btn-primary" asp-route-id="#item.Id">Add to Cart</button>
</td>
</tr>
}
</tbody>
</table>
</form>
</div>
<div class="col-md-6">
<table class="table">
<thead><tr><th colspan="5">Item Table</th></tr>
<tr>
<th>
Item Name
</th>
<th>
Price
</th>
<th></th>
</tr>
</thead>
<tbody>
#if (Model.Items !=null && Model.Items.Count > 0)
{
foreach (var item in Model.Items)
{
<tr>
<td>
#item.Name
</td>
<td class="text-right">
£#item.Price
</td>
<td class="text-right">
</td>
</tr>
}
}
</tbody>
</table>
</div>
</div>
ProductIndex.cshtml.cs:
public class ProductIndexModel : PageModel
{
//Here I use a DataRepository to set the initial data.
private readonly IDataRepository _repository;
public ProductIndexModel(IDataRepository repository)
{
_repository = repository;
}
[BindProperty]
public List<Item> Items { get; set; } //item list.
public List<Product> Products { get; set; } // product list
public void OnGet()
{
Products = _repository.GetProducts();
}
public async Task<IActionResult> OnPostAddToCartAsync(string id)
{
// use session to store the items.
// you could directly store the new item into database. in this scenario, you could query the database and get the existing items.
if (HttpContext.Session.Get<List<Item>>("_Items") != default)
{
Items = (List<Item>)HttpContext.Session.Get<List<Item>>("_Items");
}
if (id != null)
{
var product = _repository.GetProducts().Where(c => c.Id == id).FirstOrDefault();
Item newitem = new Item()
{
Name = product.Name,
Price = product.Price
};
Items.Add(newitem);
HttpContext.Session.Set<List<Item>>("_Items", Items);
}
//reset the Products.
Products = _repository.GetProducts();
return Page();
}
}
The screenshot as below:
More detail information, you could refer the following links:
Handler Methods in Razor Pages
Write a basic form
Session and state management in ASP.NET Core
[Note]If you want to use Session to store the Object,after configuring your application use session, remember to add SessionExtensions.

ASP.NET Core Model null error in the Index view

Please see the Error section below. Other related code is as follows:
Model:
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
public List<Post> Posts { get; set; }
}
public class Post
{
public int PostId { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public int BlogId { get; set; }
public Blog Blog { get; set; }
}
BlogPostController
public IActionResult Index()
{
return View("~/Views/BlogsTest/Index.cshtml");
}
View [Index.cshtml]:
#model IEnumerable<ASPCoreCodeFirstApp.Models.Blog>
<p>
<a asp-controller="BlogPost" asp-action="Create">Create New</a>
</p>
<table class="table">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.Url)
</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Url)
</td>
<td>
<a asp-controller="BlogPost" asp-action="Edit" asp-route-id="#item.BlogId">Edit</a>
</td>
<td>
<a asp-controller="BlogPost" asp-action="Create" asp-route-id="#item.BlogId">Edit</a>
</td>
</tr>
}
</tbody>
</table>
Error at #foreach (var item in Model)....line:
I can see the Index method gets called and when I put the breakpoint at the #foreach (var item in Model) line of Index.cshtml file I get Model as null and the browser throws the following error. Blogs table does have data. Even if it did not have data the foreach loop should have returned empty result instead of an NULL exception error. The view relative path in the Index action method seems write since Index.cshtml view does get called. What I may be missing?:
NullReferenceException: Object reference not set to an instance of an object.
MoveNext in Index.cshtml, line 22
Folder Hierarchy:
Model above is in Model.cs file highlighted below:
Your view is a strongly typed view requiring a list (to be precise, IEnumerable) of Blog objects :
#model IEnumerable<ASPCoreCodeFirstApp.Models.Blog>
For strongly typed views, you have to pass an object of the type that the view requires from your controller action for the view engine to be able to render the view ( Even if it's just an empty list ) :
View("ViewName", new List<Blog>())

Generate multi level customer receipt for order

My target is to generate a view for customer receipt which they will get after they submit an order. The receipt should contain all the food items they order. Each food item can contain multiple sub items.
Model is returning data like below;
if you see carefully, those who have parentitemid are sub items. and they should be shown under their parent item.
The target should look like as below;
Now the problem is i have tried many things (i.e. if-else inside the foreach and etc)
but did not get this view.
Will it be possible to generate such view from this kind of data ??
Can anyone help me out with some idea plzzz !
EDIT:
I have some progress..here how it looks now..
Now, how would i show the price of sub item under the main item...??
here is my code
<%foreach (var i in Model.OrderItems)
{ %>
<tr>
<td style="vertical-align:top;">1</td>
<td style="width:40%;"><%:i.fiitemName%>
<br />
<table style="margin-left:10px;">
<%foreach (var k in Model.getOrderSubItems("36-171012-2", i.fiID))
{ %>
<tr style="height:30px;">
<td style="width:100px;"><%:k.FoodItemName %></td>
<td style="width:100px;"><%:k.SubItemPrice %></td>
</tr>
<%} %>
</table>
</td>
<td style="vertical-align:top;"><%:i.msize%></td>
<td style="vertical-align:top;"><%:i.ItemNote %></td>
<td style="vertical-align:top;"><%:i.mprice%></td>
</tr>
<%} %>
How does your model look ? A simple model example:
public class Order
{
public int Id { get; set; }
public List<Item> Items { get; set; }
public class Item
{
public int Id { get; set; }
public string Name { get; set; }
public int Qty { get; set; }
public decimal Price { get; set; }
public List<Item> SubItems { get; set; }
}
}
Then to display you can loop through all items on an order and then in that item loop any sub items.
foreach (var item in Order.Items)
{
foreach (var subItems in item.SubItems)
{
}
}