ASP.NET MVC 4 passing values between lists - c#

I have a following problem: I have form, which has some dropdowns, textareas etc. and also I have two tables:
- SelectedItems
- AvailableItems
This two tables are a result of rendering two lists in my Model. What I need to do is when user press add button in a defined item row then I move item from AvailableItems to SelectedItems. My idea was to operate on lists so add to one, remove from another. I have no idea how to update lists of objects which can be found in model
public class Model
{
public List<Item> SelectedItems {get; set;}
public List<Item> AvailableItems {get; set;}
//other properties
}
My Partial View is:
<table>
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Description</th>
<th></th>
</tr>
</thead>
#if (Model.SelectedItems != null)
{
foreach (var item in Model.SelectedItems)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.ID)
</td>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.Description)
</td>
<td>
#Html.ActionLink("Add", "RemoveItem", new { ItemID = item.ID}, new { #class = "btn btn-primary" })
</td>
</tr>
}
}
</table>
<table>
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Description</th>
<th></th>
</tr>
</thead>
#if (Model.AvailableItems != null)
{
foreach (var item in Model.AvailableItems)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.ID)
</td>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.Description)
</td>
<td>
#Html.ActionLink("Add", "AddItem", new { ItemID = item.ID}, new { #class = "btn btn-primary" })
</td>
</tr>
}
}
</table>
Problem is that I can't reload whole page. I need to make inserts do db basing on that form so is there any possibility to update model and then start inserts?
Thank you for your help.

Related

Change color in table row depending on cell value (minus/plus) in database

I have done a table of history transactions. In my transaction db I have a column named QuantityChange. Where values can be negative or positive.
I would like to set the row color to red, if its a minus value and green if positive (or zero).
What is the best solution to this?
<table class="table">
<thead>
<tr>
<th>
Date
</th>
<th>
Storage
</th>
<th>
Product
</th>
<th>
Quantity change
</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr class="#item.QuantityChange">
<td>
#Html.DisplayFor(modelItem => item.Date)
</td>
<td>
#Html.DisplayFor(modelItem => item.Stock.Storage.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.Stock.Product.Name)
</td>
<td>
#if (item.QuantityChange > 0)
{
#Html.DisplayFor(modelItem => item.QuantityChange, new {
style = "color:#00ff00" })
}
else
{
#Html.DisplayFor(modelItem => item.QuantityChange, new {
style = "color:#ff0000" })
}
</td>
</tr>
}
</tbody>
</table>
This might be a solution for you.
#foreach (var item in Model)
{
<tr style="color:#(item.QuantityChange >= 0 ? "#00ff00" : "#ff0000")">
<!-- insert other columns here -->
<td> <!-- this has been modified -->
#Html.DisplayFor(modelItem => item.QuantityChange)
</td>
</tr>
}
Try this
#{
String color;
}
And in your table add the styling to each element as required.
#foreach (var item in Model)
{
<tr>
#{
switch((item.QuantityChange)
{
case >0:
color:"#00ff00";
break;
default:
color:"color:#ff0000";
break;
}
<td style="color:#color">
#Html.DisplayFor(modelItem => item.QuantityChange)
</td>

How can I retrieve items for a sub-table based on an item ID in the master table in a Razor page?

I have a Razor Page view that simply generates a table of items from a List retrieved from a Model property, like so:
#page
#model Agency.Pages.TypeManagement.CategoryType.IndexModel
#{
ViewData["Title"] = "Index";
}
<h2>Index</h2>
<p>
<a asp-page="Create">Create New</a>
</p>
<table class="table">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.Category[0].CategoryCode)
</th>
<th>
#Html.DisplayNameFor(model => model.Category[0].CategoryName)
</th>
<th>
#Html.DisplayNameFor(model => model.Category[0].CategoryDescription)
</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model.Category) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.CategoryCode)
</td>
<td>
#Html.DisplayFor(modelItem => item.CategoryName)
</td>
<td>
#Html.DisplayFor(modelItem => item.CategoryDescription)
</td>
<td>
<a asp-page="./Edit" asp-route-id="#item.CategoryId">Edit</a> |
<a asp-page="./Details" asp-route-id="#item.CategoryId">Details</a> |
<a asp-page="./Delete" asp-route-id="#item.CategoryId">Delete</a>
</td>
</tr>
}
</tbody>
</table>
What I want to do is to output a sub-table for each item in the table, if any items exist in the sub-table, based on the ID of the item in the master table. I know that I can use a property, like Model.Category, in a Razor statement, but is it also possible to retrieve data from the View based on the value of something like the ID of the current item?
So what I want to end up with is something like this:
#foreach (var item in Model.Category) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.CategoryCode)
</td>
<td>
#Html.DisplayFor(modelItem => item.CategoryName)
</td>
<td>
#Html.DisplayFor(modelItem => item.CategoryDescription)
</td>
<td>
<a asp-page="./Edit" asp-route-id="#item.CategoryId">Edit</a> |
<a asp-page="./Details" asp-route-id="#item.CategoryId">Details</a> |
<a asp-page="./Delete" asp-route-id="#item.CategoryId">Delete</a>
</td>
<table>
<tbody>
#foreach (var subitem in Model.SubCategory) {
<tr>
<td>
#Html.DisplayFor(modelItem => subitem.CategoryCode)
</td>
<td>
#Html.DisplayFor(modelItem => subitem.CategoryName)
</td>
<td>
#Html.DisplayFor(modelItem => subitem.CategoryDescription)
</td>
<td>
<a asp-page="./Edit" asp-route-id="#subitem.CategoryId">Edit</a> |
<a asp-page="./Details" asp-route-id="#subitem.CategoryId">Details</a> |
<a asp-page="./Delete" asp-route-id="#subitem.CategoryId">Delete</a>
</td>
</tr>
}
</tbody
</table
</tr>
}
But I need to filter the SubCategory items based on the ID of the item in the current row of the main table.
Filter subcategories on the current item/row's identifier.
#foreach (var item in Model.Category) {
//...omitted for brevity
var subItems = Model.SubCategory.Where(x => x.CategoryId = item.Id);
if(subItems.Any()) {
<table>
<tbody>
foreach (var subitem in subItems) {
//...omitted for brevity
where item is from the outer foreach loop.
Reference Using the Razor Syntax: Combining Text, Markup, and Code in Code Blocks

Model Properties passing as nulls to Action

I am trying to pass an item with the type "EmployeeDocument" to my action but all of values are coming back as nulls and I am not sure why. I have tried passing the entire model as well as just pieces and they are all null and I am not sure why this is happening.
Here is what my view looks like:
<table id="results-table" class="table table-striped table-bordered table-condensed">
<thead>
<tr>
<th>
<u>#Html.DisplayName("Title")</u>
</th>
<th>
<u>#Html.DisplayName("Document Type")</u>
</th>
<th>
<u>#Html.DisplayName("Created By")</u>
</th>
<th>
<u>#Html.DisplayName("Created Date")</u>
</th>
<th style="width: 180px;"></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Title)
</td>
<td>
#Html.DisplayFor(modelItem => item.DocumentType)
</td>
<td>
#Html.DisplayFor(modelItem => item.CreatedBy)
</td>
<td>
#Html.DisplayFor(modelItem => item.CreatedDate)
</td>
<td>View | #Html.ActionLink("Replace", "ReplaceEmployeeDocument", "Employee",new {title = item.Title, doctype = item.DocumentType, createdDate = item.CreatedDate,createdBy = item.CreatedBy, fullUrl = item.FullUrl}) | #Html.ActionLink("Delete", "DeleteEmployeeDocument",new {fileName = item.FullUrl, employeeNo = item.EmployeeNumber})</td>
</tr>
}
</tbody>
</table>
I am focusing on the replace action link in the table.
This is what my action looks like:
[HttpGet]
public ActionResult ReplaceEmployeeDocument(string title, string doctype, DateTime createdDate, string createdBy, string fullUrl)
{
var doc = new EmployeeDocument();
return PartialView(doc);
}
All of the parameters in the action are null. Is there a reason why these are like that?
You are trying to post back a collection of objects, in order for this to work you need to use a for loop and index the properties with hidden inputs as follows:
#using (Html.BeginForm("ReplaceEmployeeDocument", "Controller"))
{
#for(var i = 0; i < Model.Count(); i++)
{
<tr>
<td>
#Html.HiddenFor(m => m[i].Title)
#Html.DisplayFor(m => m[i].Title)
</td>
<td>
#Html.HiddenFor(m => m[i].DocumentType)
#Html.DisplayFor(m => m[i].DocumentType)
</td>
<td>
#Html.HiddenFor(m => m[i].CreatedBy)
#Html.DisplayFor(m => m[i].CreatedBy)
</td>
<td>
#Html.HiddenFor(m => m[i].CreatedDate)
#Html.DisplayFor(m => m[i].CreatedDate)
</td>
<td>View | <input type="submit" value="Replace"/></td>
</tr>
}
}
You also need a corresponding post method that accepts the model being passed back:
[HttpPost]
public ActionResult ReplaceEmployeeDocument(EmployeeDocument model)
{
var doc = new EmployeeDocument();
return PartialView(doc);
}
You dont seem to be using any #Html.EditorFor which would generate input fields, and you dont have any form or javascript that would send your arguments in either GET or POST method. Therefore none of your fields are sent to the method in the controller. You should wrape the code inside the foreach in a
#Html.BeginForm() {}

cshtml view if inside of foreach inside of else

I'm trying to display records in my view. I only want to display records that don't have a null value for the TABLE_NUMBER1 field. I've set this up, but am having a weird issue where it won't recognize the closing tag for the else, only the foreach and if. Specifically, if I add a closing tag for the else, it recognizes it as the closing tag for the entire razer section (aka it's gold).
#if (Model.Count() == 0)
{
<tbody>
<tr>
<td colspan="7">
No Records match search criteria
</td>
</tr>
</tbody>
}
else{
foreach (var item in Model)
{
var hiderows = #Html.DisplayFor(modelItem => item.TABLE_NUMBER1).ToString();
if (hiderows != null)
{
<tbody>
<tr>
<td>
<p class="one">#Html.DisplayFor(modelItem => item.PNTR_MAX)</p>
</td>
<td>
<p class="one">#Html.DisplayFor(modelItem => item.EFFECTIVE_DATE1)</p>
</td>
<td>
<p class="one">#Html.DisplayFor(modelItem => item.BANK_ROUTING_NUMBER)</p>
</td>
<td>
<p class="one">#Html.DisplayFor(modelItem => item.TAX_ID)</p>
</td>
<td>
<p class="one">#Html.DisplayFor(modelItem => item.BANK_NAME)</p>
</td>
<td>
<p class="one">#Html.DisplayFor(modelItem => item.COMPANY_NAME1)</p>
</td>
<td>
#Html.ActionLink("Edit", "..\\Table9\\Edit", new { id = item.EFTID })
#Html.ActionLink("Details", "..\\Table9\\Details", new { id = item.EFTID })
#Html.ActionLink("Delete", "..\\Table9\\Delete", new { id = item.EFTID })
</td>
</tr>
</tbody>
}
}
}
This is wrong:
var hiderows = #Html.DisplayFor(modelItem => item.TABLE_NUMBER1);
change it to :
#Html.DisplayFor(modelItem => item.TABLE_NUMBER1)
if (item.TABLE_NUMBER1!= null)
{

Model Count check in MVC3 view

Here is my view code:
#model IEnumerable<StudentRegistrationPortal.Models.CourseRegisterModel>
#{
ViewBag.Title = "Welcome Student";
}
<h2>Welcome
#Context.User.Identity.Name
</h2>
#Html.ActionLink("[Sign Out]", "SignOut", "Student")
<ul>
<li>#Html.ActionLink("Register Courses", "registerCourses", "Course")</li>
</ul>
<%if (Model.Count == 5) { %>
<table border="1">
<tr>
<th>
RollNumber
</th>
<th>
Course Code
</th>
<th>
Course Name
</th>
<th>Add/Drop</th>
</tr>
<tr>
<td>
#Context.User.Identity.Name
</td>
<td>
#Html.DisplayFor(modelItem => Model.ElementAt(0).Course.Code)
</td>
<td>
#Html.DisplayFor(modelItem => Model.ElementAt(0).Course.Name)
</td>
<td>
#Html.ActionLink("Drop", "Drop", new { id=-1 })
</td>
</tr>
<tr>
<td>
#Context.User.Identity.Name
</td>
<td>
#Html.DisplayFor(modelItem => Model.ElementAt(1).Course.Code)
</td>
<td>
#Html.DisplayFor(modelItem => Model.ElementAt(1).Course.Name)
</td>
<td>
#Html.ActionLink("Drop", "Drop", new { id=-1 })
</td>
</tr>
<tr>
<td>
#Context.User.Identity.Name
</td>
<td>
#Html.DisplayFor(modelItem => Model.ElementAt(2).Course.Code)
</td>
<td>
#Html.DisplayFor(modelItem => Model.ElementAt(2).Course.Name)
</td>
<td>
#Html.ActionLink("Drop", "Drop", new { id=-1 })
</td>
</tr>
<tr>
<td>
#Context.User.Identity.Name
</td>
<td>
#Html.DisplayFor(modelItem => Model.ElementAt(3).Course.Code)
</td>
<td>
#Html.DisplayFor(modelItem => Model.ElementAt(3).Course.Name)
</td>
<td>
#Html.ActionLink("Drop", "Drop", new { id=-1 })
</td>
</tr>
<tr>
<td>
#Context.User.Identity.Name
</td>
<td>
#Html.DisplayFor(modelItem => Model.ElementAt(4).Course.Code)
</td>
<td>
#Html.DisplayFor(modelItem => Model.ElementAt(4).Course.Name)
</td>
<td>
#Html.ActionLink("Drop", "Drop", new { id=-1 })
</td>
</tr>
</table>
<% } %>
I have added IF condition to only draw table if model count is equals to 5 but still if model contains no data then it gives error that:
Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
What is wrong with IF condition?
Thanks.
your code will only work if you have exactly 5 CourseRegisterModel. This is your issue.
why don't you just iterate the model(s)
#foreach(StudentRegistrationPortal.Models.CourseRegisterModel modelValue in Model)
{
<tr>
<td>
#Context.User.Identity.Name
</td>
<td>
#Html.DisplayFor(modelItem => modelValue.Course.Code)
</td>
<td>
#Html.DisplayFor(modelItem => modelValue.Course.Name)
</td>
<td>
#Html.ActionLink("Drop", "Drop", new { id=-1 })
</td>
</tr>
}
if you really insist on doing this logic inside the view, then you can use operator precedence and check for the Model containing items. Without further addo, edit you line:
<%if (Model.Count == 5) { %>
to:
// check will only continue if Model.Any() evaluates to true
#if (Model.Any() && Model.Count == 5) { ... }
I would personally do this in my viewModel inside my service or controller class and really flesh out the logic required for this hardcoded Count == 5 existing. You aslo seem to be mixing razon and webforms syntax.
Why are you using <% syntax in if clause, change it to use #
#if (Model.Count == 5)
{
also at the end change <% } %> to following
}
If Model is Null then accessing to the count would be throw an exception. so before that you have to check that if the model is null or not.
#if(Mode != null && Mode.Count == 5)
{
//....

Categories