I have a simple list view with list of tasks.
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.TaskText)
</td>
<td>
#Html.DisplayFor(modelItem => item.TillDate)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.Id }) |
#Html.ActionLink("Delete", "Delete", new { id = item.Id })
<select id="TaskState">
<option>Active</option>
<option>Stoped</option>
<option>Complete</option>
</select>
</td>
</tr>
}
And class for Task:
public class Task
{
public int Id { get; set; }
public string TaskText { get; set; }
public DateTime TillDate { get; set; }
public TaskState State { get; set; }
}
public enum TaskState
{
Active=1,
Stoped,
Complete
}
Now, I want to change Task state by selecting it from drop down list, but can't figure out how to conect it with model. How can I do it?
If you are using ASP.NET MVC 5.1 you can use the EnumDropDownListFor() helper
#Html.EnumDropDownListFor(model => model.State)
Related
I am trying add a model with respect to users (ApplicationUser) and for that i created a model my problem is the data is not displaying in view (username for particular post)
Model
public class OrganizationViewModel
{
public ApplicationUser AppUser { get; set; }
public int OrganizationId { get; set; }
public string Name { get; set; }
}
Controller
public ActionResult Create(OrganizationViewModel organizationviewmodel)
{
var getuserid = User.Identity.GetUserId();
var userid = db.Users.Single(s => s.Id == getuserid);
var organizationvmodel = new Organization
{
AppUser = userid,
Name = organizationviewmodel.Name
};
db.Organizations.Add(organizationvmodel);
db.SaveChanges();
return RedirectToAction("Index");
}
But in view which means index.cshtml when i try to populate it as a list its empty just like this output image
View
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.AppUser.UserName)
#ViewBag.UserName
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id = item.OrganizationId }) |
#Html.ActionLink("Details", "Details", new { id = item.OrganizationId }) |
#Html.ActionLink("Delete", "Delete", new { id = item.OrganizationId })
</td>
</tr>
}
Please give me a good solution because i am very new to asp.net mvc
I'm having some troubles with Models and ViewModels.
I need list all bills and the users in the same view. (users in a dropdown list)
Also: When to use IEnumerable<T>? Because depending I change the view change the error message.
Model
public class Bill
{
public int Id { get; set; }
public string Title { get; set; }
public DateTime Date { get; set; }
public string Category { get; set; }
public double Amount { get; set; }
public Card Card { get; set; }
public int CardId { get; set; }
}
ViewModel
public class UserBills
{
public IEnumerable<ApplicationUser> User { get; set; }
public Bill Bill { get; set; }
}
View
#*#model IEnumerable<Nucontrol.Models.Bill>*#
#model IEnumerable<Nucontrol.ViewModels.UserBills>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Bill.Card.Number)
</td>
<td>
#Html.DisplayFor(modelItem => item.Bill.Title)
</td>
<td>
#Html.DisplayFor(modelItem => item.Bill.Date)
</td>
<td>
#Html.DisplayFor(modelItem => item.Bill.Category)
</td>
<td>
#Html.DisplayFor(modelItem => item.Bill.Amount)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id = item.Bill.Id }) |
#Html.ActionLink("Details", "Details", new { id = item.Bill.Id }) |
#Html.ActionLink("Split", "Split", new { id = item.Bill.Id }, new { data_target = "#myModal", data_toggle = "modal" })
</td>
</tr>
}
<!-- List all users -->
#Html.DropDownListFor(m => User.Identity.Name, new SelectList(User.Identity.Name, "Id", "Name"), "", new { #class = "form-control" })
Controller
public ActionResult Index()
{
var users = _context.Users.ToList();
var bills = _context.Bills.ToList();
var viewModel = new UserBills
{
User = users
};
return View(viewModel);
}
You have some issues in sample code provided:
1) The DropDownListFor uses User.Identity.Name property as model binding, which actually derived from IIdentity.Name which is getter-only property. Declare another property with setter available which holds user ID in your viewmodel.
2) Passing UserBills viewmodel into view which bound to IEnumerable<UserBills> model may cause InvalidOperationException. You need to use either passing IEnumerable<UserBills> from controller or define #model UserBills.
3) I suggest you use IEnumerable<SelectListItem> to create DropDownListFor items from IEnumerable<ApplicationUser> generated by identity data context and pass it to view (see also IdentityUser properties).
Here is initial solution based from my thought:
Model
public class UserBills
{
public int UserId { get; set; }
public IEnumerable<SelectListItem> Users { get; set; }
public IEnumerable<Bill> Bills { get; set; }
}
Controller
public ActionResult Index()
{
var users = _context.Users.ToList();
var bills = _context.Bills.ToList();
var viewModel = new UserBills
{
Users = users.Select(x => new SelectListItem() { Value = x.Id.ToString(), Text = x.UserName.ToString() }),
Bills = bills
}
return View(viewModel);
}
View
#model Nucontrol.ViewModels.UserBills
#foreach (var item in Model.Bills)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Card.Number)
</td>
<!-- other properties -->
</tr>
}
#Html.DropDownListFor(m => m.UserId, Model.Users, "", new { #class = "form-control" })
NB: Since you're getting selected user ID from viewmodel binding, it is possible to create HttpContext.User instance and setting User.Identity.Name property from that ID.
I created a page that I can search the store detail via entity framework
I added a column of checkbox in the table.
I would like to keep the checkbox "checked=True" after I submit via the search button.
What would be the recommend way to achieve that ?
I tried following method, but the checkbox get "unchecked" after I click submit
1. https://www.sitepoint.com/quick-tip-persist-checkbox-checked-state-after-page-reload/
View as following :
#using (Html.BeginForm())
{
<p>
Find by name: #Html.TextBox("SearchString")
<input type="submit" name ="StoreIndexButton" value="Search" />
</p>
}
<table class="table" id="displayresult">
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.name)
</td>
<td>
#Html.DisplayFor(modelItem => item.market)
</td>
<td>
#Html.DisplayFor(modelItem => item.status)
</td>
<td>
#Html.DisplayFor(modelItem => item.oper)
</td>
<td>
#Html.DisplayFor(modelItem => item.operator)
</td>
<td>
#Html.ActionLink("Details", "Details", new { id=item.store1 })
</td>
<td>
#Html.CheckBox("selected",new { value = item.store1, id="selected"+item.store1.ToString() })
</td>
</tr>
}
</table>
Controller as following :
public ActionResult Index(string StoreIndexButton,string searchString)
{
var AR_stores = (from m in db.stores
select m).Take(10);
string[] selectedList = Request.Form.GetValues("selected");
if (!String.IsNullOrEmpty(searchString) && StoreIndexButton =="Search")
{
AR_stores = (from m in db.stores
select m).Where(s => s.name.Contains(searchString));
}
return View(AR_stores);
}
Model as following :
using System;
using System.Collections.Generic;
public partial class store
{
public int store1 { get; set; }
public string name { get; set; }
public string market { get; set; }
public string status { get; set; }
public string oper { get; set; }
public string operator { get; set; }
}
I would on this way :
on partial class add a flag parameter.
public string checkStatus {get; set;}
on default, this will be false and none of choices will be selected.
After submit the function, you have list of selected items and you can set them as selected (checkStatus will be true).
MVC does not have ViewState like ASP.Net WebForms (Not sure viewstate is a feature or drawback). So you have to save the state of the checkbox using a hidden field or a variable. You can try this with jquery and ajax
Continuing from here (thanks #qujck) I've implemented Generic controller which looks like this:
public class GenericLookupController<TModelType> : Controller where TModelType : GenericLookupModel //GenericLookupController.cs
It has all common actions for handling most common tasks in lookup tables like CRUD, toggling active state and such.
I'm trying now to create also generic views for those generic lookup tables.
Model type is GenericLookupModel which basically looks like this:
public class GenericLookupModel : IActive, CustomField
{
public bool is_active { get; set; }
public string value { get; set; }
public DateTime? created_on { get; set; }
public string created_by { get; set; }
public DateTime? updated_on { get; set; }
public string updated_by { get; set; }
public int id {get;set;}
}
So let's take for example country lookup controller and model:
public partial class Country : GenericLookupModel //country lookup model
{
}
and controller:
public class CountryController : GenericLookupController<Country> //CountryController.cs
{
}
Actions are working fine for those, but I have a problem with views. For Index action I'm using:
public virtual ActionResult Index() //GenericLookupController.cs
{
var model = _db.Set<TModelType>().ToList();
return View("__GenericLookupIndex",model);
}
and the __GenericLookupIndex looks like that:
#model IEnumerable<GenericLookupModel> #*__GenericLookupIndex.cshtml*#
#{
Layout = "_AdminLayout.cshtml";
}
...
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.value)
</td>
<td>
#{
if (item.is_active)
{
<i class="fa fa-check"></i>
}
else
{
<i class="fa fa-times-circle"></i>
}
}
</td>
<td>
#Html.DisplayFor(modelItem => item.created_on)
</td>
<td>
#Html.DisplayFor(modelItem => item.created_by)
</td>
<td>
#Html.DisplayFor(modelItem => item.updated_on)
</td>
<td>
#Html.DisplayFor(modelItem => item.updated_by)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { item.id }, new { #class = "btn btn-primary btn-xs" }) |
#Html.ActionLink("Deactivate/Activate", "Toggle", new { item.id }, new { #class = "btn btn-warning btn-xs" })
</td>
</tr>
}
The issue is that item doesn't have enumerated values from Model in the line with foreach. I've tried to do workaround and instead of #foreach (var item in Model) I did #foreach (Country item in Model) and that works but this denies the whole Generic idea. How can I fix it, so that I don't have to specify the type explicitly in the view and get the data properly? Please advice.
Update:
The application doesn't throw any errors, but I don't get proper values while enumeration. Please look into screenshots below:
1) Empty table generated by view
2) Model variable in Watch window
3) Enumerated item variable from Model in Watch window
I am binding objects in a razor foreach in the index.html:
VIEW
#using (Ajax.BeginForm("Save", "Unit", new AjaxOptions { OnSuccess = "onSuccess" }))
{
<button type="submit" class="btn btn-default" id="saveUnits"><i class="fa fa-save"></i></button>
<table>
<tbody>
#foreach (var item in Model)
{
<tr>
#Html.HiddenFor(modelItem => item.UnitId)
<td>
#Html.EditorFor(modelItem => item.Name)
</td>
<td>
#Html.EditorFor(modelItem => item.ErrorText)
</td>
</tr>
}
</tbody>
</table>
}
I have grabbed the data sent to my action parameter with fiddler and got this:
item.UnitId=5&
item.Name=111111111111&
item.ErrorText=fsdddddddddddddddd+&
item.UnitId=5&
item.Name=+&
item.ErrorText=dddddd+&
ACTION
public ActionResult Save(List<Unit> units )
{
return new EmptyResult();
}
VIEWMODEL
public class Unit
{
[HiddenInput(DisplayValue = false)]
public int UnitId { get; set; }
[DataType(DataType.MultilineText)]
public string Name { get; set; }
[DataType(DataType.MultilineText)]
public string ErrorText { get; set;
}
Why is my units instance null? The properties match so they should be bound!
Did I overlook something?
You need to use a for loop not a foreach loop. Also, it would be better to make your Model class have a property which is a collection.
Your model could be something like:
public class UnitsViewModel
{
public List<Unit> Units { get; set; }
public class Unit
{
[HiddenInput(DisplayValue = false)]
public int UnitId { get; set; }
[DataType(DataType.MultilineText)]
public string Name { get; set; }
[DataType(DataType.MultilineText)]
public string ErrorText { get; set; }
}
}
And you could do the following in your cshtml:
#for (int i = 0; i < Model.Count; i++)
{
<tr>
#Html.HiddenFor(m => m.Units[i].UnitId)
<td>
#Html.EditorFor(m => m.Units[i].Name)
</td>
<td>
#Html.EditorFor(m => m.Units[i].ErrorText)
</td>
</tr>
}