I want to produce the below list of typed checkbox
When i inspect each checkbox (eg levelOne) i want to see each having a unique ID and name like the below
I have a Service (ReplayService) that provides a list of objects (HierarchyLevels) which will be used to create the list of Checkboxes
public IEnumerable<HierarchyLevels> GetHierarchyLevels()
{
return new List<HierarchyLevels>()
{
new HierarchyLevels{Name="LevelOne",ShortName="L1", IsSelected = false},
new HierarchyLevels{Name="LevelTwo",ShortName="L2", IsSelected = false},
new HierarchyLevels{Name="TLevelThree",ShortName="L3", IsSelected = false},
new HierarchyLevels{Name="LevelFour",ShortName="L4", IsSelected = false},
};
}
My Controller Class uses the List of HierarchyLevels (created by the service) to create a new Object viewModel.HierarchyLevels (In the Model) of type IEnumerable
public ActionResult Index()
{
var vm = new MyViewModel();
PopulateViewModel(vm.viewModel);
return View(viewModel);
}
private void PopulateViewModel(ContentReplayViewModelBase viewModel)
{
var hierarchyLevels = replayService.GetHierarchyLevels();
viewModel.HierarchyLevels = hierarchyLevels.Select(h => new SelectListItem {Text = h.Name, Selected = h.IsSelected}).ToArray();
}
My Model class has defined properties for each checkbox that will be created.
public abstract class ReplayViewModelBase
{
public IEnumerable<SelectListItem> HierarchyLevels { get; set; }
....
....
}
public class ReplayByHierarchyLevels : ReplayViewModelBase
{
public bool levelOne { get; set; }
public bool leveltwo { get; set; }
public bool levelThree { get; set; }
public bool levelFour { get; set; }
.....
.....
}
In my View i an looping through the list of HierarchyLevels and producing a List of checkbox. the problem I'm having is I'm not sure how to loop through the list of objects and assign a unique bool property in the Model. In the code snippet below I'm assigning bool property "levelOne" to all the created checkbox (as a result all have the same ID and Name)
#foreach (var level in Model.ReplayByHierarchyLevels.HierarchyLevels)
{
<tr>
<td>#level.Text</td>
<td>#Html.CheckBox(level.Text, level.Selected)</td>
<td>** #Html.CheckBoxFor(x => x.ReplayByHierarchyLevels.levelOne, Model.ReplayByHierarchyLevels.levelOne = level.Selected)</td>
</tr>
}
personally, I would just bind to the HierarchyLevels, so the checkbox view will be:
#for(int i =0; i < Model.ReplayByHierarchyLevels.HierarchyLevels.Count; i++)
{
<tr>
<td>#Model.ReplayByHierarchyLevels.HierarchyLevels[i].Text</td>
<td>
#Html.CheckBoxFor(m => m.ReplayByHierarchyLevels.HierarchyLevels[i].Selected)
#Html.HiddenFor(m => m.ReplayByHierarchyLevels.HierarchyLevels[i].Text)
#Html.HiddenFor(m => m.ReplayByHierarchyLevels.HierarchyLevels[i].Value)
</td>
</tr>
}
then if you want strong type of access, you could change the view model ReplayByHierarchyLevels to do:
public class ReplayByHierarchyLevels : ReplayViewModelBase
{
// be aware may be null
public bool levelOne { get{return HierarchyLevels.FirstOrDefault(x => x.Text == "levelOne").Selected;} }
// rest the same
}
Related
With the code below, i can select multiple radio buttons at the same time, that is a problem, a true radio button only works with ONE selected item. How do i re-arrange my code so that it acts like a real radio button and not like a checkbox like the code below?
for (int i = 0; i < Model.RadioButtonItems.Count; i++)
{
<div>
#Html.HiddenFor(m => m.RadioButtonItems[i].RBName)
#Html.LabelFor(l => l.RadioButtonItems[i].RBIsSelected, Model.RadioButtonItems[i].RBName)
#Html.RadioButtonFor(r => r.RadioButtonItems[i].RBIsSelected, true);
</div>
}
The rest of code:
Model:
public class ModelVariables
{
public List<Item> RadioButtonItems { get; set; }
}
public class Item
{
public string RBName { get; set; }
public bool RBIsSelected { get; set; }
}
public static class Repository
{
public static List<Item> RBFetchItems()
{
return new List<Item>()
{
new Item() {RBName = "Metal"},
new Item() {RBName = "Jazz"},
new Item() {RBName = "Trance"}
};
}
}
Controller:
var selectedRBItems = model.RadioButtonItems.Where(x => x.RBIsSelected).Select(x => x.RBName).ToList();
if (model.RadioButtonItems != null && selectedRBItems.Count > 0)
{
ViewBag.RBResults = "Successfully Logged Pressed RB's!";
}
else
{
ViewBag.RBResults = "You must select a radio button!";
}
Summary: this code let's you select multiple radiobuttons, i DONT want that, i want only one possible selection out of many options.
Each radio button has a different name attribute so they are not grouped. Your model needs a property to bind the selected value to, and a collection of items for the options
public class ModelVariables
{
[Required(ErrorMessage = "...")]
public string SelectedValue { get; set; }
public List<string> Options { get; set; }
}
and in the GET method
var model = new ModelVariables()
{
Options = new List<string>() { "Metal", "Jazz", "Trance" },
SelectedValue = ? // set this if you want one of the buttons initially selected
};
return View(model);
and in the view
foreach (var option in Model.Options)
{
<label>
#Html.RadionButtonFor(m => m.SelectedValue, option, new { id = "" })
<span>#option</span>
</label>
}
// add the following if you do not set an initial value in the GET method
#Html.ValidationMessageFor(m => m.SelectedValue)
I currently am pulling a list of url's from a view using Entity Framework 5 and MVC 5. I have the view populating all the links but I need each link to display their 'LinkState' names like in my model so it will output:
Alabama
Georgia
etc.
with the link attached to the LinkState. Instead of the view foreach loop saying State Link. I cant get my model/controlled to pull the correct information.
Repository:
public class LinkRepository
{
private readonly LinkLibrary _entities = new LinkLibrary ();
public LinkRepository()
{
_entities = new LinkLibrary ();
}
public List<LinkModels> RetrieveStateLink(string year)
{
return
_entities.vw_URLLibrary.Where(s => s.YEAR.Equals(year) && s.URL_TYPE.Equals("United States")).Select(m => new LinkModels()
{
UrlLink = m.LinkLocation
}).ToList();
}
}
Model
public class LinkModels
{
public string LinkYear { get; set; }
public string LinkState { get; set; }
public string UrlLink { get; set; }
public string LinkType { get; set; }
public List<string> ListOfUrls{ get; set; }
}
Controller
public ActionResult GetStateLinks()
{
var stateLink = new List<string>();
var model = rr.RetrieveStateLinks("2014").Select(m=> m.UrlLink).ToList();
foreach (var s in model)
{
stateLink.Add(s);
}
var rm = new LinkModels();
rm.ListOfUrls = stateLink;
return View(rm);
}
View
#foreach (var item in Model.StateLinkList)
{
<td>
State Link
</td>
}
Your issue is that you are returning a List of strings as opposed to a list of LinkModels. I updated the repository to return the url and link name
removed some unneccessary code in your controller and updated it to work with a list of LinkObjects. Then updated the view to display the info.
You will have to update your view #model List<LinkModels> instead of #model List<string>
public class LinkRepository
{
private readonly LinkLibrary _entities = new LinkLibrary ();
public LinkRepository()
{
_entities = new LinkLibrary ();
}
public List<LinkModels> RetrieveStateLink(string year)
{
return
_entities.vw_URLLibrary.Where(s => s.YEAR.Equals(year) && s.URL_TYPE.Equals("United States")).Select(m => new LinkModels()
{
LinkState = m.LinkState,
UrlLink = m.LinkLocation
}).ToList();
}
}
public ActionResult GetStateLinks()
{
var stateLink = new List<LinkModels>();
var model = rr.RetrieveStateLinks("2014");
return View(model);
}
#foreach (var item in Model)
{
<td>
#item.LinkState
</td>
}
Controller
public ActionResult GetStateLinks()
{
var model = rr.RetrieveStateLinks("2014");
return View(model);
}
View (change your view model to list of LinkModels)
#foreach (var item in Model)
{
<td>
#item.LinkState
</td>
}
So im trying to insert into my database the values from check boxes that the user checked.
In my ViewModel:
[Display(Name = "Title")]
public string Title { get; set; }
public IEnumerable<SelectListItem> UserTitlelist { get; set; }
public IEnumerable<SelectListItem> Titles { get; set; }
In my View:
#foreach (var item in Model.Titles)
{
<label class="managelabel" style="padding: 0 5px 0 5px;"><input name="Title" type="checkbox" value="#item.Value" #checkedcheckbox> #item.Text</label>
}
In my Controller:
var titleToInsert = new UserTitle
{
UserId = currentUserId,
TitleId = model.Title[];
};
UserManagerService.UpdateUserTitles(titleToInsert);
In UserManagerService:
public static int UpdateUserTitles(UserTitle userTitle)
{
using (ITransaction transaction = Context.BeginTransaction())
{
foreach (var x in userTitle)
{
Context.Save(userTitle);
}
transaction.Commit();
}
return 0;
}
You view model is incorrect and has no relationship at all to what you are editing. And SelectListItem is a class for use in #Html.DropDownListFor(), not for a collection of checkboxes.
You view models should be
public class TitleVM
{
public int ID { get; set; }
public string Name { get; set; }
public bool IsSelected { get; set; }
}
public class UserTitleVM
{
.... // other properties
public List<TitleVM> Titles { get; set; }
}
And in the view
#model UserTitleVM
#using (Html.BeginForm())
{
....
for(int i = 0; i < Model.Titles.Count; i++)
{
#Html.HiddenFor(m => m.Titles[i].ID)
#Html.CheckBoxFor(m =>m.Titles[i].IsSelected)
#Html.LabelFor(m => m.Titles[i].IsSelected, Model.Titles[i].Name)
}
and in the controller
public ActionResult Edit(UserTitleVM model)
{
// Get the ID's of the selected titles
List<int> selectedTitles = model.Titles.Where(t => t.IsSelected).Select(t => t.ID);
....
I found the answer is quite simple:
in the controller:
var myList = Request.Form["Title"];
foreach (var item in myList.Split(','))
{
var titleToInsert = new UserTitle
{
UserId = currentUserId,
TitleId = Convert.ToInt32(item)
};
UserManagerService.UpdateUserTitles(titleToInsert);
}
then in UserManagerService:
public static int UpdateUserTitles(UserTitle userTitle)
{
using (ITransaction transaction = Context.BeginTransaction())
{
Context.Save(userTitle);
transaction.Commit();
}
return 0;
}
This way each record gets saved individually
I am trying to populate an HTML table with data from a table in my database. The issue is simply that the HTML table is not getting populated with any data.
Here is the ViewModel:
public class TestViewModel
{
public string MatchedId { get; set; }
public string UnmatchedId { get; set; }
public string Auth { get; set; }
public DateTime CreditDate { get; set; }
public string CreditNumber { get; set; }
public decimal CreditAmount { get; set; }
public DateTime DeniedDate { get; set; }
public int DeniedReasonId { get; set; }
public string DeniedNotes { get; set; }
}
Controller Action:
[HttpPost]
public ActionResult UploadValidationTable(HttpPostedFileBase csvFile)
{
var inputFileDescription = new CsvFileDescription
{
SeparatorChar = ',',
FirstLineHasColumnNames = true
};
var cc = new CsvContext();
var filePath = uploadFile(csvFile.InputStream);
var model = cc.Read<Credit>(filePath, inputFileDescription);
try
{
var entity = new Entities();
//model here is the .csv, doesn't have anything to do with this issue
foreach (var item in model)
{
var tc = new TemporaryCsvUpload
{
Id = item.Id,
CreditAmount = item.CreditAmount,
CreditDate = item.CreditDate,
CreditNumber = item.CreditNumber,
DeniedDate = item.DeniedDate,
DeniedReasonId = item.DeniedReasonId,
DeniedNotes = item.DeniedNotes
};
entity.TemporaryCsvUploads.Add(tc);
}
entity.SaveChanges();
System.IO.File.Delete(filePath);
//This is where the database table is getting filled
entity.Database.ExecuteSqlCommand("Insert into CsvReport Select p.Id as MatchedId, case when p.Id is null then t.Id end as UnmatchedId, p.Auth,p.CreditDate, p.CreditNumber,p.CreditAmount, p.DeniedDate,p.DeniedReasonId, p.DeniedNotes from TemporaryCsvUpload t left join PermanentTable p on p.Id = t.Id;");
TempData["Success"] = "Updated Successfully";
}
catch (LINQtoCSVException)
{
TempData["Error"] = "Upload Error: Ensure you have the correct header fields and that the file is of .csv format.";
}
return View("Upload");
}
View:
#model IEnumerable<TestProject.TestViewModel>
#if (Model != null)
{
foreach (var item in Model.Where(x => x.IdMatched != null))
{
<tr>
<td>
#item.MatchedId
</td>
<td>
#item.Auth
</td>
<td>
#item.CreditDate
</td>
<td>
#item.CreditNumber
</td>
<td>
#item.CreditAmount
</td>
<td>
#item.DeniedDate
</td>
<td>
#item.DeniedReasonId
</td>
<td>
#item.DeniedNotes
</td>
</tr>
}
}
It's a little weird because I am populating the database with an SQL command. What am I missing here? Do I need to try and pass it through the controller action? Let me know if you need more information. Thanks!
Edit
I tried to pass the instance through, but I may still be doing it incorrectly:
var testModel = new TestViewModel();
return View("Upload", testModel);
Here is what its padding through:
public class TestViewModel
{
public IEnumerable<Test> Test { get; set; }
}
Made an answer so essentially the view doesn't know what to render you need to pass an actual filled model (in your case an IEnumerable to the view). This can be done using the method:
View("Upload", viewModelList);
Controller.View docs on MSDN
It looks like you are not adding any data to your view model.
If your view model is a collection of Test objects, you need to add some
Test objects to the collection.
var model = new TestViewModel()
{
Test = new List<Test>() { new Test(), new Test(), ... }
}
return View("Upload", model);
I have this problem where i want to make 7 dropdowns for each day of the week.
In each one of those dropdowns i wish to add the same data.
My ViewModel:
public class WeekDienstCreateViewModel
{
public WeekDienst weekDienst {get; set;}
public List<DienstPerWeekDienst> diensten { get; set; }
public WeekDienstCreateViewModel() { }
}
My Create Method in Controller:
As u can see I add everything allready except DienstId which is want to add with my dropdowns.
public ActionResult Create(int id)
{
WeekDienst wd = _service.FindWeekDienst(id);
WeekDienstCreateViewModel vm = new WeekDienstCreateViewModel();
vm.diensten = new List<DienstPerWeekDienst>();
vm.weekDienst = wd;
for (int i = 1; i <= 7; i++)
{
DienstPerWeekDienst dpwd = new DienstPerWeekDienst();
dpwd.volgnummer = i;
dpwd.WeekDienstId = wd.Id;
vm.diensten.Add(dpwd);
}
ViewBag.Diensten = _service.DienstenList(wd.AfdelingId);
return View(vm);
}
Classes:
public class DienstPerWeekDienst
{
[Key]
public int Id { get; set; }
[Required]
public int WeekDienstId { get; set; }
[Required]
public int DienstId { get; set; }
[Required]
[Range(1, 7)]
public int volgnummer { get; set; }
[ForeignKey("WeekDienstId")]
public virtual WeekDienst WeekDienst { get; set; }
[ForeignKey("DienstId")]
public virtual Dienst Dienst { get; set; }
public virtual ICollection<WeekDienst> WeekDiensten { get; set; }
}
public class WeekDienst
{
[Key]
public int Id { get; set; }
[Required]
public int AfdelingId { get; set; }
[Required]
[StringLength(5, ErrorMessage = "Value for {0} cannot exceed {1} characters.")]
[RegularExpression(#"^[a-zA-Z0-9]{5}$", ErrorMessage = "Verplicht 5 cijfers lang.")]
public string code { get; set; }
[DisplayName("Template")]
public bool template { get; set; }
[ForeignKey("AfdelingId")]
public virtual Afdeling Afdeling { get; set; }
}
And in my view i wish to create 7 dropdowns where i put in all my "Diensten" (class Dienst, fk in DienstPerWeekDienst). When I choose 1 i wish to add the "DienstId" into the "DienstPerWeekDienst" class.
So in my View i got this:
#foreach (var day in Model.diensten)
{
var currentDay=day;
#Html.DropDownListFor(currentDropDown=>currentDay, new SelectList(ViewBag.Diensten, "Value", "Text"))
}
I Wish to postback the chosen "Diensten" and create the "WeekDienst" but now i am just posting a null "DienstPerDienstWeekCreateViewModel". How am I able to fix this?
Thanks in Advance
FIX (Thanks to Siva Gopal)
I fixed this by doing:
#for (int i = 0; i < #Model.diensten.Count; i++)
{
#Html.HiddenFor(m => (m.diensten[i].volgnummer))
#Html.HiddenFor(m => (m.diensten[i].WeekDienstId))
#Html.DropDownListFor(m=> (m.diensten[i].DienstId), new SelectList(ViewBag.Diensten, "Value", "Text"))
}
You may try using
#foreach (var day in Model.diensten)
{
var currentDay=day;
#Html.DropDownListFor(currentDropDown=>currentDay, new SelectList(ViewBag.Diensten, "PropertyName_Holding_Value", "PropertyName_Holding_DisplayText"), new { })
} //This uses the Lambda Expression. Your dropdown Name/Id would be 1,2,3 etc. based on currentDay value.
OR
#foreach (var day in Model.diensten)
{
var currentDay=day;
var dropdownName=string.Format("diensten[{0}]",day-1); //If you want to model bind the selected dropdown value to input entity in POST request. The final dropdownName format should match the hierarchy of the property inside input entity/object. Even without this name formation, you can still POST the selected value back using Jquery/Javascript.
#Html.DropDownList(dropdownName, new SelectList(ViewBag.Diensten, "PropertyName_Holding_Value", "PropertyName_Holding_DisplayText"), new {})
} //
Note for Value Post back/model bind on full Page submit:
To be able to model bind/POST back values to the server, the html element names corresponding to the properties should be rendered as follows: Suppose if you display Employee.Department.Name, then name of textbox, displaying the Department Name in View should match Department_ReferenceName_Inside_Employee.Name for model binding.
Model:
public class Employee
{
public int Id { get; set; }
public string Name { get; set; }
public string City { get; set; }
public Department EmpDepartment { get; set; }
public List SubOrdinates { get; set; }
}
public class Department
{
public string Name { get; set; }
}
Controller:
public class HomeController : Controller
{
public ActionResult Index()
{
ViewBag.Message = "Welcome to ASP.NET MVC!";
//Prepare the model and send it to the view
Employee emp = new Employee { EmpDepartment = new Department { Name = "IT" } };
emp.SubOrdinates = new List<Employee> { new Employee { Name = "Emp1" }, new Employee { Name = "Emp2" } };
return View(emp);
}
[HttpPost]
public ActionResult Index(Employee emp)
{ //Put a break-point here and see how the modified values in view are flowing into emp..
return View(emp);
}
public ActionResult About()
{
return View();
}
}
View:
#model MvcApplication.Models.Employee
#using (Html.BeginForm())
{
#Html.TextBoxFor(m => m.EmpDepartment.Name)
#Html.LabelForModel("SubOrdinates :")
for (int i = 0; i < #Model.SubOrdinates.Count; i++)
{
#Html.TextBoxFor(m => (m.SubOrdinates[i].Name))
}
<input type="submit" name="name" value="Submit" /> }
ViewSource/PageSource:
The above text box syntax will be rendered as :
<input id="EmpDepartment_Name" name="EmpDepartment.Name" type="text" value="IT" /> <!--See above html : name=EmpDepartment.Name -->
<label for="">SubOrdinates :</label>
<input id="SubOrdinates_0__Name" name="SubOrdinates[0].Name" type="text" value="Emp1" />
<input id="SubOrdinates_1__Name" name="SubOrdinates[1].Name" type="text" value="Emp2" /> <!--See above html for how collection item Name(s) are being renderd by view engine-->
<input type="submit" name="name" value="Submit" />
#foreach (var day in Model.diensten)
{
var currentDay = day;
#Html.DropDownListFor(x => currentDay, new SelectList(ViewBag.Diensten, "Value", "Text"), new { #id = "DienstList" })
}
List<MvcApplication1.Models.Country> cntry = db.Countries.ToList();
SelectListItem sss = new SelectListItem();
List<SelectListItem> sltst = new List<SelectListItem>();
sss.Text = "Select";
sss.Value = "0";
sltst.Add(sss);
foreach (MvcApplication1.Models.Country s in cntry){
SelectListItem s1 = new SelectListItem();
s1.Text = s.Country1;
s1.Value = Convert.ToString(s.Id);
sltst.Add(s1);}
#Html.DropDownList("country", sltst, new { #id = "country" })