Skip to content

Instantly share code, notes, and snippets.

@davecowart
Created February 3, 2011 18:48
Show Gist options
  • Save davecowart/809935 to your computer and use it in GitHub Desktop.
Save davecowart/809935 to your computer and use it in GitHub Desktop.
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<CHSweb.Models.ViewModels.PropertyDetailsViewModel>" %>
<%@ Import Namespace="CHSweb.Helpers" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
Details
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="HeadContent" runat="server">
<script src="/Scripts/jquery.form.js" type="text/javascript"></script>
<script src="/Scripts/PropertyEditor.js" type="text/javascript"></script>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<div>
<h1><%: Model.Property.Name %></h1>
<div>
<%: Html.Hidden("propertyId", Model.Property.Id) %>
<% Html.RenderPartial("OperatingStatementList", Model.OperatingStatements); %>
</div>
</asp:Content>
public static class HtmlPrefixScopeExtensions
{
private const string idsToReuseKey = "__htmlPrefixScopeExtensions_IdsToReuse_";
public static IDisposable BeginCollectionItem(this HtmlHelper html, string collectionName)
{
var idsToReuse = GetIdsToReuse(html.ViewContext.HttpContext, collectionName);
string itemIndex = idsToReuse.Count > 0 ? idsToReuse.Dequeue() : Guid.NewGuid().ToString();
// autocomplete="off" is needed to work around a very annoying Chrome behaviour whereby it reuses old values after the user clicks "Back", which causes the xyz.index and xyz[...] values to get out of sync.
html.ViewContext.Writer.WriteLine(string.Format("<input type=\"hidden\" name=\"{0}.index\" autocomplete=\"off\" value=\"{1}\" />", collectionName, html.Encode(itemIndex)));
return BeginHtmlFieldPrefixScope(html, string.Format("{0}[{1}]", collectionName, itemIndex));
}
public static IDisposable BeginHtmlFieldPrefixScope(this HtmlHelper html, string htmlFieldPrefix)
{
return new HtmlFieldPrefixScope(html.ViewData.TemplateInfo, htmlFieldPrefix);
}
private static Queue<string> GetIdsToReuse(HttpContextBase httpContext, string collectionName)
{
// We need to use the same sequence of IDs following a server-side validation failure,
// otherwise the framework won't render the validation error messages next to each item.
string key = idsToReuseKey + collectionName;
var queue = (Queue<string>)httpContext.Items[key];
if (queue == null) {
httpContext.Items[key] = queue = new Queue<string>();
var previouslyUsedIds = httpContext.Request[collectionName + ".index"];
if (!string.IsNullOrEmpty(previouslyUsedIds))
foreach (string previouslyUsedId in previouslyUsedIds.Split(','))
queue.Enqueue(previouslyUsedId);
}
return queue;
}
private class HtmlFieldPrefixScope : IDisposable
{
private readonly TemplateInfo templateInfo;
private readonly string previousHtmlFieldPrefix;
public HtmlFieldPrefixScope(TemplateInfo templateInfo, string htmlFieldPrefix)
{
this.templateInfo = templateInfo;
previousHtmlFieldPrefix = templateInfo.HtmlFieldPrefix;
templateInfo.HtmlFieldPrefix = htmlFieldPrefix;
}
public void Dispose()
{
templateInfo.HtmlFieldPrefix = previousHtmlFieldPrefix;
}
}
}
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<CHSweb.Data.Models.OperatingStatement>" %>
<%@ Import Namespace="CHSweb.Helpers" %>
<div id="operatingStatementFormContainer">
<% using (Html.BeginCollectionItem("operatingStatements")) { %>
<%: Html.ValidationSummary(true) %>
<fieldset>
<legend>Fields</legend>
<div class="editor-label">
<%: Html.LabelFor(model => model.Year) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.Year) %>
<%: Html.ValidationMessageFor(model => model.Year) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.RoomsAvailable) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.RoomsAvailable) %>
<%: Html.ValidationMessageFor(model => model.RoomsAvailable) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.RoomsOccupied) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.RoomsOccupied) %>
<%: Html.ValidationMessageFor(model => model.RoomsOccupied) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.Occupancy) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.Occupancy) %>
<%: Html.ValidationMessageFor(model => model.Occupancy) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.ADR) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.ADR) %>
<%: Html.ValidationMessageFor(model => model.ADR) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.RoomRevenue) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.RoomRevenue) %>
<%: Html.ValidationMessageFor(model => model.RoomRevenue) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.RBRevenue) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.RBRevenue) %>
<%: Html.ValidationMessageFor(model => model.RBRevenue) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.OtherOperatingDepartmentRevenue) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.OtherOperatingDepartmentRevenue) %>
<%: Html.ValidationMessageFor(model => model.OtherOperatingDepartmentRevenue) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.RentalsAndOtherIncome) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.RentalsAndOtherIncome) %>
<%: Html.ValidationMessageFor(model => model.RentalsAndOtherIncome) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.RoomsExpense) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.RoomsExpense) %>
<%: Html.ValidationMessageFor(model => model.RoomsExpense) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.FBExpense) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.FBExpense) %>
<%: Html.ValidationMessageFor(model => model.FBExpense) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.OtherOperatingDepartmentExpense) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.OtherOperatingDepartmentExpense) %>
<%: Html.ValidationMessageFor(model => model.OtherOperatingDepartmentExpense) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.AGExpense) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.AGExpense) %>
<%: Html.ValidationMessageFor(model => model.AGExpense) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.SalesMarketingExpense) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.SalesMarketingExpense) %>
<%: Html.ValidationMessageFor(model => model.SalesMarketingExpense) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.FranchiseFees) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.FranchiseFees) %>
<%: Html.ValidationMessageFor(model => model.FranchiseFees) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.POMExpense) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.POMExpense) %>
<%: Html.ValidationMessageFor(model => model.POMExpense) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.UtilityCost) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.UtilityCost) %>
<%: Html.ValidationMessageFor(model => model.UtilityCost) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.ManagementFee) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.ManagementFee) %>
<%: Html.ValidationMessageFor(model => model.ManagementFee) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.PropertyTax) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.PropertyTax) %>
<%: Html.ValidationMessageFor(model => model.PropertyTax) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.Insurance) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.Insurance) %>
<%: Html.ValidationMessageFor(model => model.Insurance) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.EquipmentLease) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.EquipmentLease) %>
<%: Html.ValidationMessageFor(model => model.EquipmentLease) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.GroundLease) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.GroundLease) %>
<%: Html.ValidationMessageFor(model => model.GroundLease) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.Other) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.Other) %>
<%: Html.ValidationMessageFor(model => model.Other) %>
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
<% } %>
</div>
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IEnumerable<CHSweb.Data.Models.OperatingStatement>>" %>
<div class="listSection">
<h4>Operating Statements</h4>
<% using (Html.BeginForm("AddOperatingStatement", "Property", FormMethod.Post, new { id = "operatingStatementForm" })) { %>
<table>
<thead>
<tr>
<th>Year</th>
<th>Occupancy</th>
<th>Room Revenue</th>
<th>Rooms Expense</th>
<th>AG Expense</th>
<th></th>
</tr>
</thead>
<tbody id="operatingStatementRows">
<% foreach (var operatingStatement in Model)
Html.RenderPartial("OperatingStatement", operatingStatement);
%>
</tbody>
</table>
<%= Html.ActionLink("New Operating Statement", "BlankOperatingStatementRow", null, new { id = "addOperatingStatement" })%>
<% } %>
</div>
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<CHSweb.Data.Models.OperatingStatement>" %>
<tr>
<td><%: Model.Year %></td>
<td><%: Model.Occupancy %></td>
<td><%: Model.RoomRevenue.GetValueOrDefault().ToString("C" )%></td>
<td><%: Model.RoomsExpense.GetValueOrDefault().ToString("C") %></td>
<td><%: Model.AGExpense.GetValueOrDefault().ToString("C") %></td>
<td><%: Html.ActionLink("Delete", "Delete", "OperatingStatement", new { id = Model.Id }, new { @class = "deleteLink" } )%></td>
</tr>
public class PropertyController : Controller {
CHSDataContext db = new CHSDataContext(ConfigurationManager.ConnectionStrings["chsdb"].ConnectionString);
[HttpPost]
public ActionResult AddOperatingStatement(int propertyId, IEnumerable<OperatingStatement> operatingStatements) {
try {
var operatingStatement = operatingStatements.First();
operatingStatement.PropertyId = propertyId;
db.OperatingStatements.InsertOnSubmit(operatingStatement);
db.SubmitChanges();
return View("OperatingStatement", operatingStatement);
} catch {
return Json("Error");
}
}
public ViewResult BlankOperatingStatementRow() {
return View("OperatingStatementEditorRow", new OperatingStatement());
}
}
function getPropertyId() {
return $("#propertyId").val();
}
$(document).ready(function () {
$("#addOperatingStatement").click(function () {
$.ajax({
url: this.href,
cache: false,
success: function (html) {
$("#operatingStatementRows").append(html);
$("#operatingStatementForm").ajaxForm({
target: '#operatingStatementFormContainer',
replaceTarget: true,
data: { propertyId: getPropertyId() }
});
}
});
return false;
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment