BsTable with different Row Background - razor

Bootstrap 4 provides the ability to have different table row background colors.
Right now I am checking a condition in my MVC Index View and choose the background of this row.
#foreach (var item in Model)
{
#if(item.condition1)
{
<tr class="table-success">
<td></td>
</tr>
}
else if(item.condidtion2)
{
<tr class="table-warning">
<td></td>
</tr>
}
else
{
<tr class="table-danger">
<td></td>
</tr>
}
This works without problems, but it is not really good in a long term aspect.
If you have lots of elements in each row you have lots of duplicate code.With more condictions it gets worse. Is there a better way to avoid duplicate code? If I want to change elements, I have to edit or add elements for every row. The usual problems with code redundancy.
I tried to have only a single without closing tags for each condition and after those the and but this gives compiler errors.

You can use the ternary conditional operator(?:) in tr,x?y:z.It works like:
if(x)
{
return y;
}
else
{
return z;
}
Here is a demo worked:
public class Item
{
public bool Condition1 { get; set; }
public bool Condition2 { get; set; }
public bool Condition3 { get; set; }
}
Controller:
public IActionResult TestItem()
{
Item item1 = new Item { Condition1 = false, Condition2 = false, Condition3 = true };
Item item2 = new Item { Condition1 = false, Condition2 = true, Condition3 = false };
Item item3 = new Item { Condition1 = true, Condition2 = false, Condition3 = false };
Item item4 = new Item { Condition1 = false, Condition2 = false, Condition3 = false };
List<Item> l = new List<Item> { item1, item2, item3,item4 };
return View(l);
}
View:
<table>
#foreach (var item in Model)
{
<tr #(item.Condition1 ? "class=table-success" : item.Condition2?"class=table-warning":item.Condition3?"class=table-danger":"")>
<td>TestItem</td>
</tr>
}
</table>
result:

Related

access Enum Items Inside Index View

i am trying to get enum items value inside Index View to Create drop down list for the items of Enum....but i couldn't....how to get enum items value?
the enum:
public enum ReportType
{
[Display(Name = "None")]
None = 0,
[Display(Name = "NotRelated")]
NotRelated = 1,
[Display(Name = "Violation")]
Violation = 2,
[Display(Name = "HateSpeech")]
HateSpeech = 3
};
the drop down list in View:
<select>
#foreach (var item in Model)
{
#if (item.ReportType.ToString()!=1) {
<option value="0">#item.EventNameAr</option>
}
}
</select>
You can try to use :
#if ((int)item.ReportType != 1) {
<option value="0">#item.EventNameAr</option>
}
But you can use display name instead :
#if (item.ReportType.ToString() != "NotRelated") {
<option value="0">#item.EventNameAr</option>
}

How to get text of selected item of drop down in Asp.net MVCrazor

i have a drop down when i select any item it sends its id to Model while i want to send Selected item's Text.How can i do that ?Here is my code that sends Id of selected item and i am also posting code of the method to get selected item.please help me where i am wrong
View
<div class="controls">
<label class="site-label">Assign to</label>
#Html.DropDownListFor(m => m.AssignedTo, (ViewBag.DispatchersList) as IEnumerable<SelectListItem>, new { #class = "" })
#Html.ValidationMessageFor(m => m.AssignedTo)
</div>
Controller
public static object GetSelectListWithSelectOption(dynamic model, int selected, string valuefield, string textfield, bool addSelect = true, string addSelectValue = "-1", bool performSort = false)
{
List<SelectListItem> selectList = null;
if (model != null)
{
selectList = new SelectList(model, valuefield, textfield, selected).ToList();
if (performSort)
selectList = selectList.OrderBy(x => x.Text).ToList();
}
else
{
selectList = new List<SelectListItem>();
}
if (addSelect)
selectList.Insert(0, new SelectListItem { Text = Cygnus.Library.Resources.General.txtSelect, Value = addSelectValue, Selected = true });
return selectList;
}
In order to send the text back, just fill the Value property of the SelectListItems with the same value that you provide to the Text property.
public static object GetSelectListWithSelectOption(dynamic model, int selected, string valuefield, string textfield, bool addSelect = true, string addSelectValue = "Selected Item Text", bool performSort = false)
{
List<SelectListItem> selectList = null;
if (model != null)
{
selectList = new SelectList(model, textfield, textfield, selected).ToList();
if (performSort)
selectList = selectList.OrderBy(x => x.Text).ToList();
}
else
{
selectList = new List<SelectListItem>();
}
if (addSelect)
selectList.Insert(0, new SelectListItem { Text = Cygnus.Library.Resources.General.txtSelect, Value = Cygnus.Library.Resources.General.txtSelect, Selected = true });
return selectList;
}

Html.ListBoxFor Object reference not set to an instance of an object Error

I am using view model to display a dropdownlist and i am also trying to get the value of the selected list, here is my view model
public class CreateJobViewModel
{
public int[] SelectedIndustriesIds { get; set; }
public IList<SelectListItem> IndustriesList { get; set; }
}
My controller
public ActionResult Create()
{
var industryList = repository.GetAllIndustries();
var model = new CreateJobViewModel
{
IndustriesList = industryList.Select(i => new SelectListItem
{
Value = i.IndustryId.ToString(),
Text = i.Name
}).ToList()
};
return View("~/Views/Dashboard/Job/Create.cshtml", model);
}
My post controller
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(CreateJobViewModel model)
{
try
{
var job = new Job()
{
Title = "hi",
EmploymentHourId = 1,
LocationId = 1,
Salary = 50,
SalaryPeriodId = 1,
PostCode = 2131,
Role = "world",
Description = "hello",
IsPublished = false,
ShiftId = 1,
WorkDayId = 1,
NumberOfPosition = 5,
Meal = false,
SecondYearVisa = true,
Sponsorship = true,
Accommodation = true,
DurationId = 1,
IndustryExperiencePeriod = 5,
Id = User.Identity.GetUserId(),
};
foreach (int id in model.SelectedIndustriesIds)
{
var industry = repository.Industry(id);
job.Industries.Add(industry);
}
foreach (int id in model.SelectedSpecialRequirementsId)
{
var special = repository.SpecialRequirement(id);
job.SpecialRequirements.Add(special);
}
repository.AddJob(job);
return RedirectToAction("Create");
}
catch
{
return View("~/Views/Dashboard/Job/Create.cshtml");
}
}
Every time i try to submit the selected value, i get Object reference not set to an instance of an object Error on the following line in my view:
#model Taw.WebUI.Models.CreateJobViewModel
#Html.ListBoxFor(m => m.SelectedIndustriesIds, Model.IndustriesList) -- here i get the error
Any reason why?
When you submit the form your throwing an exception (confirmed in the comments) and in the catch block you are returning the view, which throws the exception you are seeing because Model.IndustriesList is null. You need to re-assign the value before you return the view.
Since you need to assign SelectLists in the GET method and in the POST method if you return the view, I tend to re-factor this to a separate method to keep the controller code a bit cleaner. Note the following code is based on your model property being public SelectList IndustriesList { get; set; } which is a bit simpler than building IList<SelectListItem>
private void ConfigureViewModel(CreateJobViewModel model)
{
var industryList = repository.GetAllIndustries();
model.IndustriesList = new SelectList(industryList, "IndustryId", "Name")
// any other common stuff
}
and then in the action methods
public ActionResult Create()
{
var model = new CreateJobViewModel();
ConfigureViewModel(model);
return View(model);
}
public ActionResult Create(CreateJobViewModel model)
{
try
{
....
}
catch
{
ConfigureViewModel(model);
return View(model);
}
}
Note its also good practice to test if the model is valid before attempting to save it
public ActionResult Create(CreateJobViewModel model)
{
if (!ModelState.IsValid)
{
ConfigureViewModel(model);
return View(model); // return the view so the user can correct validation errors
}
....

Access a Viewbag like an Array?

Imagine a view bag called
ViewBag.Modes
this contains the following:
Simple
Advanced
Manual
Complete
How can I access the viewbag by index like you would in an array?
e.g Simple is at index 0 then it would look like this
ViewBag.Modes[0]
I tried the above but it doesn't work so...How can I replicate this with viewbag or is there a workaround I can use?
This does the trick for me:
Controller:
public ActionResult Index()
{
var stringArray = new string[3] { "Manual", "Semi", "Auto"};
ViewBag.Collection = stringArray;
return View();
}
View:
#foreach(var str in ViewBag.Collection)
{
#Html.Raw(str); <br/>
}
#for (int i = 0; i <= 2; i++ )
{
#Html.Raw(ViewBag.Collection[i]) <br/>
}
Output:
Sorry for not using your terms. I was scrachting this together from the top of my head.
ViewBag is a dynamic property, which complicates things a bit.
For the behavior you're looking for, you might want to use ViewData instead. ViewData is a dictionary, which means you can access the values of each index using Linq:
this.ViewData.Keys.ElementAt(0);
In your controller:
string[] Modes = {"Simple", "Advanced", "Manual", "Complete" };
ViewData["Modes"] = Modes;
In your View:
<div>
#(((string[])ViewData["Modes"])[0])
</div>
<div>
#(((string[])ViewData["Modes"])[1])
</div>
<div>
#(((string[])ViewData["Modes"])[2])
</div>
Using the ViewBag:
Controller
public ActionResult Index()
{
List<string> modes = new List<string>();
modes.Add("Simple");
modes.Add("Advanced");
modes.Add("Manual");
modes.Add("Complete");
ViewBag["Modes"] = modes;
return View();
}
View
<h1>List of Modes</h1>
#{foreach (var mode in ViewBag.Modes) {
<li>
#hobby
</li>
} }
----------------------------------------------------------------
Using the ViewData:
Controller
public ActionResult Index()
{
string[] Modes = {"Simple", "Advanced", "Manual", "Complete" };
ViewData["Modes"] = Modes;
return View();
}
**View
<h1>List of Modes</h1>
#foreach (string mode in ViewData["Modes"] as string[]) {
<li>
#mode
</li>
}
Thanks for the posts but shortly after writing this I came up with this solution using a model & list as below this could also be done using viewbag instead of model.
List<string> list = new List<string>();
foreach (Models.AppModeInfo blah in Model.theAppModes)
{
list.Add(blah.Name);
}
var AppModeText = "";
switch (item.AppModeId)
{
case 1:
AppModeText = list[0];
break;
case 2:
AppModeText = list[1];
break;
case 3:
AppModeText = list[2];
break;
case 4:
AppModeText = list[3];
break;
case 5:
AppModeText = list[4];
break;
}

#html.TextBox() is not passing in the controller in actionlink

I`m trying to pass value in a controller from a text box. i google this problem. but not get any suitable solution which works for me.
below is my controller.
WebProductController
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using DatabaseService_WebAPI.Models;
namespace DatabaseService_WebAPI.Controllers
{
public class WebProductController : Controller
{
private ProductContext db = new ProductContext();
private LocalDBContext ldb = new LocalDBContext();
private ProductTypeContext pdb = new ProductTypeContext();
//
// GET: /WebProduct/
public ActionResult Index()
{
var temp = from tpro in db.Products
where tpro.User==User.Identity.Name
select tpro;
return View(temp.ToList());
}
public ActionResult TypeT()
{
var temp = from ttpro in pdb.ProductTypes
where ttpro.Type == "Tablet"
select ttpro;
return View(temp.ToList());
}
public ActionResult TypeC()
{
var temp = from ctpro in pdb.ProductTypes
where ctpro.Type == "Capsule"
select ctpro;
return View(temp.ToList());
}
public ActionResult TypeS()
{
var temp = from stpro in pdb.ProductTypes
where stpro.Type == "Syrup"
select stpro;
return View(temp.ToList());
}
//
// GET: /WebProduct/Details/5
public ActionResult Details(int id = 0)
{
Product product = db.Products.Find(id);
if (product == null)
{
return HttpNotFound();
}
return View(product);
}
//
// GET: /WebProduct/Create
public ActionResult Create()
{
return View();
}
//
// POST: /WebProduct/Create
[HttpPost]
public ActionResult Create(Product product)
{
if (ModelState.IsValid)
{
LocalDB tobj = ldb.LocalDBs.Single(s => s.User == User.Identity.Name);
product.city = tobj.City;
product.OrderDate = DateTime.Now.Date.ToShortDateString();
product.ShopName = tobj.ShopName;
product.User = tobj.User;
db.Products.Add(product);
db.SaveChanges();
return RedirectToAction("Index", "WebProduct");
}
return View(product);
}
[HttpPost]
public ActionResult Add(ProductType type, string quantity)
{
Product product = new Product();
if (type.Type=="Tablet")
{
//string order = type.Name + " " + type.Quantity;
LocalDB tobj = ldb.LocalDBs.Single(s => s.User == User.Identity.Name);
product.city = tobj.City;
product.OrderDate = DateTime.Now.Date.ToShortDateString();
product.ShopName = tobj.ShopName;
product.User = tobj.User;
//product.OrderDetail = order;
db.Products.Add(product);
db.SaveChanges();
return RedirectToAction("TypeT", "WebProduct");
}
else if (type.Type == "Syrup")
{
//string order = type.Name + " " + type.Quantity;
LocalDB tobj = ldb.LocalDBs.Single(s => s.User == User.Identity.Name);
product.city = tobj.City;
product.OrderDate = DateTime.Now.Date.ToShortDateString();
product.ShopName = tobj.ShopName;
product.User = tobj.User;
// product.OrderDetail = order;
db.Products.Add(product);
db.SaveChanges();
return RedirectToAction("TypeS", "WebProduct");
}
else
{
// string order = type.Name + " " + type.Quantity;
LocalDB tobj = ldb.LocalDBs.Single(s => s.User == User.Identity.Name);
product.city = tobj.City;
product.OrderDate = DateTime.Now.Date.ToShortDateString();
product.ShopName = tobj.ShopName;
product.User = tobj.User;
// product.OrderDetail = order;
db.Products.Add(product);
db.SaveChanges();
return RedirectToAction("TypeC", "WebProduct");
}
return View();
}
//
// GET: /WebProduct/Edit/5
public ActionResult Edit(int id = 0)
{
Product product = db.Products.Find(id);
if (product == null)
{
return HttpNotFound();
}
return View(product);
}
//
// POST: /WebProduct/Edit/5
[HttpPost]
public ActionResult Edit(Product product)
{
if (ModelState.IsValid)
{
db.Entry(product).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index", "WebProduct");
}
return View(product);
}
//
// GET: /WebProduct/Delete/5
public ActionResult Delete(int id = 0)
{
Product product = db.Products.Find(id);
if (product == null)
{
return HttpNotFound();
}
return View(product);
}
//
// POST: /WebProduct/Delete/5
[HttpPost, ActionName("Delete")]
public ActionResult DeleteConfirmed(int id)
{
Product product = db.Products.Find(id);
db.Products.Remove(product);
db.SaveChanges();
return RedirectToAction("Index", "WebProduct");
}
protected override void Dispose(bool disposing)
{
db.Dispose();
base.Dispose(disposing);
}
}
}
TypeT.cshtml
#model IEnumerable<DatabaseService_WebAPI.Models.ProductType>
#{
ViewBag.Title = "Tablets";
<script type="text/javascript">
$(function () {
$('#edit').click(function() {
var name = $('#quantity').val();
this.href = this.href + '/' + encodeURIComponent(name);
});
});
</script>
}
<h2>Tablets</h2>
#*#using (Html.BeginForm("Add", "WebProductController",FormMethod.Post)) {
#Html.ValidationSummary(true)
*#
<table>
<tr>
<th>
#Html.DisplayNameFor(model => model.Name)
</th>
<th>
#Html.DisplayNameFor(model => model.Price)
</th>
<th>
#Html.DisplayNameFor(model => model.Batch)
</th>
<th>
#Html.DisplayNameFor(model => model.Expiry)
</th>
<th>
#Html.DisplayNameFor(model => model.Quantity)
</th>
#* <th>
#Html.DisplayNameFor(model => model.Type)
</th>*#
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.Price)
</td>
<td>
#Html.DisplayFor(modelItem => item.Batch)
</td>
<td>
#Html.DisplayFor(modelItem => item.Expiry)
</td>
<td>
#Html.TextBox("quantity")
</td>
#Html.Hidden("idText", item.Id)
<td>
#Html.ActionLink("Add", "Add", new { id = item.Id, name=item.Name, type=item.Type }, null)
#*#Html.ActionLink("Add", "Add", null, new { id = "edit" })*#
#*<input type="submit" value="Add" />*#
</td>
</tr>
}
</table>
#*}*#
<div>
#Html.ActionLink("Back to List", "Create")
</div>
In my controller i`m calling Add() method. in action result it is passing values in the controller but not passing the textbox value. when i try to use
#using (Html.BeginForm("Add", "WebProductController",FormMethod.Post))
Then the form doesnt recognize my method when i use button to sending data in my form.
im stuck in this problem. but no solution:(
Your Controller should look like:
public ActionResult Add(IList<ShoppingItemModel> items){
foreach(ShopingItemModel item in items){
if (item.Id != null){
ShopingItem shopingItem = service.GetById(item.Id);
... Add Item to whatever
}
}
}
Your ShoppingItemModel:
public class ShoppingItemModel{
[Required]
public Id{get;set;}
[Required]
public Amount{get;set;}
...
}
Your View (I Skipped Java Script):
#model IList<ShoppingItemModel>
<h2>Tablets</h2>
#using (Html.BeginForm("Add", "WebProductController",FormMethod.Post)) {
#Html.ValidationSummary(true)
<table>
<tr>
<th>
Name
</th>
<th>
Price
</th>
...
<th>Amount</th>
</tr>
#for(int index; index < Model.Count; index++) {
<tr>
<td>
#Html.HiddenFor(model => model[index].Id)
#Html.DisplayFor(model => model[index].Name)
</td>
<td>
#Html.DisplayFor(model => model[index].Price)
</td>
<td>
#Html.DisplayFor(model => model[index].Batch)
</td>
...
<td>
#Html.TextBoxFor(model => model[index].Quantity)
</td>
</tr>
}
</table>
<input type="submit" value="Add" />
}
That is not the complete solution. Just a hint.
Tobi