· 8 years ago · Aug 06, 2018, 09:50 AM
1Generating Checkbox Lists with MVC3 using a complex viewmodel and a cross table with Linq to SQL
2[MetadataType(typeof(SystemFailureProblemMetadata))]
3 public partial class SystemFailureProblem
4 {
5 private class SystemFailureProblemMetadata
6 {
7 public int ID { get; set; }
8
9 [Required]
10 [StringLength(200)]
11 [DisplayName("Problem Description")]
12 public String Description { get; set; }
13
14 public IList<xSystemFailureProblemToType> FailureTypeCategories { get; set; }
15
16 }
17
18}
19
20
21
22[MetadataType(typeof(SystemFailureTypeMetaData))]
23 public partial class SystemFailureType
24 {
25 private class SystemFailureTypeMetaData
26 {
27 public int ID { get; set; }
28
29 [Required]
30 [StringLength(200)]
31 public String Description { get; set; }
32 }
33 }
34
35@for(int i=0;i < Model.problem.FailureTypeCategories.Count(); i++)
36 {
37 @Html.CheckBox("FailureTypeCategories["+i+"].ID", false)
38
39 }
40
41public SystemFailureProblem problem { get; set; }
42
43 public SystemFailureProblemViewModel() { }
44
45 public SystemFailureProblemViewModel(SystemFailureProblem problem)
46 {
47 this.problem = problem;
48 }
49
50public ActionResult Edit(int id)
51 {
52 try
53 {
54 return PartialView("Form", context.SystemFailureProblems.Single(p => p.ID == id));
55 }
56 catch (Exception ex)
57 {
58 ModelState.AddModelError("", ex.Message);
59 return PartialView("Form", null);
60 }
61 }
62
63public class SystemFailureProblemTypeViewModel
64{
65 public int TypeID { get; set; }
66 public string TypeDescription { get; set; }
67 public bool Assigned { get; set; }
68}
69
70public ActionResult Edit(int id)
71 {
72 SystemFailureProblem problem = (from p in context.SystemFailureProblems
73 where p.ID == id
74 select p).Single();
75
76 PopulateSystemFailureProblemData(problem);
77
78 return View(problem);
79 }
80
81 public void PopulateSystemFailureProblemData(SystemFailureProblem problem)
82 {
83 // get all failure types
84 var allTypes = from t in context.SystemFailureTypes select t;
85
86 // get al types joined with this problem using cross table
87 var problemTypes = from x in context.xSystemFailureProblemToTypes
88 join t in context.SystemFailureTypes on x.SystemFailureTypeID equals t.ID
89 where x.SystemFailureProblemID == problem.ID
90 select t;
91
92 // construct view model collection
93 List<SystemFailureProblemTypeViewModel> viewModel = new List<SystemFailureProblemTypeViewModel>();
94 foreach (var type in allTypes)
95 {
96 viewModel.Add(new SystemFailureProblemTypeViewModel
97 {
98 TypeID = type.ID,
99 TypeDescription = type.Description,
100 Assigned = problemTypes.Contains(type)
101 });
102 }
103
104 ViewBag.Types = viewModel;
105 }
106
107[HttpPost]
108 public ActionResult Edit(int id, FormCollection collection, string[] selectedTypes)
109 {
110 SystemFailureProblem problem = (from p in context.SystemFailureProblems
111 where p.ID == id
112 select p).Single();
113
114 // get all types joined with this problem using cross table
115 var problemTypes = from x in context.xSystemFailureProblemToTypes
116 join t in context.SystemFailureTypes on x.SystemFailureTypeID equals t.ID
117 where x.SystemFailureProblemID == problem.ID
118 select t;
119
120 problem.FailureTypes = problemTypes.ToList<SystemFailureType>();
121
122 if (TryUpdateModel(problem, "", null, new string[] { "Types" }))
123 {
124 try
125 {
126 // loop through all types in the system
127 foreach (var failureType in context.SystemFailureTypes)
128 {
129 // determine if checkbox for current type was checked
130 if (selectedTypes.Contains(failureType.ID.ToString()))
131 {
132 // if no joining record exists (type not previously selected), create a joining record
133 if (!problemTypes.Contains(failureType))
134 {
135 context.xSystemFailureProblemToTypes.InsertOnSubmit(
136 new xSystemFailureProblemToType
137 {
138 SystemFailureProblemID = problem.ID,
139 SystemFailureTypeID = failureType.ID
140 });
141 }
142 }
143 else
144 {
145 // if type was unchecked but joining record exists, delete it
146 if (problemTypes.Contains(failureType))
147 {
148 xSystemFailureProblemToType toDelete = (from x in context.xSystemFailureProblemToTypes
149 where x.SystemFailureProblemID == problem.ID &&
150 x.SystemFailureTypeID == failureType.ID
151 select x).SingleOrDefault();
152 context.xSystemFailureProblemToTypes.DeleteOnSubmit(toDelete);
153
154 }
155 }
156 }
157 context.SubmitChanges();
158 return RedirectToAction("Index");
159 }
160 catch
161 {
162 return View();
163 }
164 }
165
166 PopulateSystemFailureProblemData(problem);
167 return View(problem);
168 }
169
170<div class="editor-field">
171 <table>
172 <tr>
173 @{
174 int cnt = 0;
175 List<SystemFailures.Data.SystemFailureProblemTypeViewModel> types = ViewBag.Types;
176
177 foreach (var type in types) {
178 if (cnt++ % 3 == 0) {
179 @: </tr> <tr>
180 }
181 @: <td>
182 <input type="checkbox"
183 name="selectedTypes"
184 value="@type.TypeID"
185 @(Html.Raw(type.Assigned ? "checked="checked"" : "")) />
186 @type.TypeDescription
187 @:</td>
188 }
189 @: </tr>
190 }
191 </table>
192 </div>