-The main view model has a property List<EmergencyContactViewModel>.
-EmergencyContactViewModel contained props for name, relationship, home phone, work phone.
-When displaying this in edit mode, there would always be at least one emergency contact.
Given that, you know that you had 4 more contacts to add to the form. I thought, no problem, just add all the fields and then hide them. To my surprise, that did not work. That is the center of this posting.
Here is the abbreviated view:
<div> <ul> <li><a href="#tabs-1">My Information</a></li> <li><a href="#tabs-2">Emergency Contact</a></li> <li><a href="#tabs-3">Federal Tax</a></li> <li><a href="#tabs-4">State Tax</a></li> <li><a href="#tabs-5">Change Request</a></li> </ul> <div id="tabs-1"> </div> <div id="tabs-2"> </div> <div id="tabs-3"> </div> <div id="tabs-4"> </div> <div id="tabs-5"> @using (Html.BeginForm()) { <table id="changeRequest"> <tr> <td>Emploee ID</td> <td>@Html.TextBoxFor(x => x.MyInfo.EmployeeId)</td> <td>Address</td> <td>@Html.TextBoxFor(x => x.MyInfo.Address</td> <td></td> <td></td> </tr> <tr> <td>Last Name</td> <td>@Html.TextBoxFor(x => x.MyInfo.LastName)</td> <td></td> <td><input type="text"></td> <td></td> <td></td> </tr> <tr> <td>First</td> <td>@Html.TextBoxFor(x => x.MyInfo.FirstName)</td> <td></td> <td><input type="text"></td> <td></td> <td></td> </tr> <tr> <td>Middle</td> <td>@Html.TextBoxFor(x => x.MyInfo.MiddleName)</td> <td>City</td> <td>@Html.TextBoxFor(x => x.MyInfo.City)</td> <td></td> <td></td> </tr> <tr> <td>Email</td> <td>@Html.TextBoxFor(x => x.MyInfo.Email)</td> <td>State</td> <td>@Html.TextBoxFor(x => x.MyInfo.State)</td> <td></td> <td></td> </tr> <tr> <td></td> <td></td> <td>Zip Code</td> <td>@Html.TextBoxFor(x => x.MyInfo.ZipCode)</td> <td></td> <td></td> </tr> <tr> <td></td> <td></td> <td>Phone 1</td> <td>@Html.TextBoxFor(x => x.MyInfo.Phone1)</td> <td></td> <td></td> </tr> <tr> <td></td> <td></td> <td>Phone 2</td> <td>@Html.TextBoxFor(x => x.MyInfo.Phone2)</td> <td></td> <td></td> </tr> <tr> <td><input type="button" id="addContact" value="Add Contact" /></td> </tr> <tr> <td>Contact</td> <td>Relationship</td> <td>Home Phone</td> <td>Work Phone</td> </tr> @for (var i = 0; i < Model.EmergencyContacts.Count; i++) { <tr> <td>@Html.TextBoxFor(x => x.EmergencyContacts[i].ContactName)</td> <td>@Html.TextBoxFor(x => x.EmergencyContacts[i].Relationship)</td> <td>@Html.TextBoxFor(x => x.EmergencyContacts[i].HomePhone)</td> <td>@Html.TextBoxFor(x => x.EmergencyContacts[i].WorkPhone)</td> </tr> } </table> <input type="submit" value="Submit" /> } </div> </div>
A few things to point out...
Yes the for loop should be removed and be replaced with an Editor Template. However, this was the standard and how they did things so just keeping in line.
The easiest solution would be that since an employee can have up to five emergency contacts, just render all the fields right out of the gate. Afterall, this is in Edit mode, however, in this post we are going to be doing it dynamically.
Let's take a look at the form...
To do this dynamically, we will need to test for the existence of other rows since an employee can have up to five emergency contacts. If the row exists, of course, don't add. If the row doesn't exist, add a new row:
if ($('#EmergencyContacts_1__ContactName').length < 1) { $('#changeRequest > tbody:last').append('<tr id="contact1">' + <td><input name="EmergencyContacts[1].ContactName" id="EmergencyContacts_1__ContactName" + type="text" /><td> + <td>< input name="EmergencyContacts[1].Relationship" id="EmergencyContacts_1__Relationship" + type="text" /><td> + <td>< input name="EmergencyContacts[1].HomePhone" = id="EmergencyContacts_1__HomePhone" + type="text" /><td> + <td>< input name="EmergencyContacts[1].WorkPhone" = id="EmergencyContacts_1__WorkPhone" + type="text" /><td> ); } if ($('#EmergencyContacts_2__ContactName').length < 1) { $('#changeRequest > tbody:last').append('<tr id="contact2">' + <td><input name="EmergencyContacts[2].ContactName" id="EmergencyContacts_2__ContactName" + type="text" /><td> + <td>< input name="EmergencyContacts[2].Relationship" id="EmergencyContacts_2__Relationship" + type="text" /><td> + <td>< input name="EmergencyContacts[2].HomePhone" = id="EmergencyContacts_2__HomePhone" + type="text" /><td> + <td>< input name="EmergencyContacts[2].WorkPhone" = id="EmergencyContacts_2__WorkPhone" + type="text" /><td> ); } if ($('#EmergencyContacts_3__ContactName').length < 1) { $('#changeRequest > tbody:last').append('<tr id="contact3">' + <td><input name="EmergencyContacts[3].ContactName" id="EmergencyContacts_3__ContactName" + type="text" /><td> + <td>< input name="EmergencyContacts[3].Relationship" id="EmergencyContacts_3__Relationship" + type="text" /><td> + <td>< input name="EmergencyContacts[3].HomePhone" = id="EmergencyContacts_3__HomePhone" + type="text" /><td> + <td>< input name="EmergencyContacts[3].WorkPhone" = id="EmergencyContacts_3__WorkPhone" + type="text" /><td> ); } if ($('#EmergencyContacts_4__ContactName').length < 1) { $('#changeRequest > tbody:last').append('<tr id="contact4"> + <td><input name="EmergencyContacts[4].ContactName" id="EmergencyContacts_4__ContactName" + type="text" /><td> + <td>< input name="EmergencyContacts[4].Relationship" id="EmergencyContacts_4__Relationship" + type="text" /><td> + <td>< input name="EmergencyContacts[4].HomePhone" = id="EmergencyContacts_4__HomePhone" + type="text" /><td> + <td>< input name="EmergencyContacts[4].WorkPhone" = id="EmergencyContacts_4__WorkPhone" + type="text" /><td> '); }
Now it seems the next thing to do would be to add code to hide those table rows and handle the button click event as such:
$('#contact1').hide(); $('#contact2').hide(); $('#contact3').hide(); $('#contact4').hide(); $('#addContact').click(function() { $('#contact1').show(); $('#contact2').show(); $('#contact3').show(); $('#contact4').show(); });
Let's go take a look at the result...
The rows are not hidden. The solution is rather simple. All that is needed is to add the visibility attribute with a value of hidden to each table row. For example:
$('#changeRequest > tbody:last').append('<tr id="contact1" style="visibility: hidden;">'
The next step is to handle the click event for the Add Contact button. For each row, change the visibility attribute value to visible, then hide it, then fade in. It may seem odd to show the table row and then hide it again. This is done so we can apply the fade in effect. If you omit hiding the second time, all the fields will just pop in immediately. Of course that is fine, we just want to show a smooth transition:
$('#addContact').click(function () { $('#contact1').css('visibility', 'visible').hide().fadeIn('slow'); $('#contact2').css('visibility', 'visible').hide().fadeIn('slow'); $('#contact3').css('visibility', 'visible').hide().fadeIn('slow'); $('#contact4').css('visibility', 'visible').hide().fadeIn('slow'); });
When the page loads, the fields should be hidden...
Then when Add Contact is clicked, the fields should fade in nicely...