Skip to content

Instantly share code, notes, and snippets.

@nickalbrecht
Last active July 3, 2020 00:31
Show Gist options
  • Save nickalbrecht/dfa024cd8797075abe98da82f3181b64 to your computer and use it in GitHub Desktop.
Save nickalbrecht/dfa024cd8797075abe98da82f3181b64 to your computer and use it in GitHub Desktop.
Updated implementation of `BeginCollectionItem` to support nesting, not ignore the original `HtmlFieldPrefix`, and also provide overloads to let me decide the ID to use. Refactored to be a bit cleaner
public static class CollectionEditingHtmlExtensions
{
/// <summary>
/// Begins a collection item by inserting a hidden field for the index value
/// </summary>
/// <param name="collectionName">The name of the collection property that owns this item</param>
/// <param name="indexValue">The value of the index for the current item</param>
public static IDisposable BeginCollectionItem<TModel>(this IHtmlHelper<TModel> html, string collectionName, Guid indexValue)
{
return BeginCollectionItem(html, collectionName, indexValue == Guid.Empty ? null : indexValue.ToString(), html.ViewContext.Writer);
}
public static IDisposable BeginCollectionItem<TModel>(this IHtmlHelper<TModel> html, string collectionName, string indexKey)
{
return BeginCollectionItem(html, collectionName, string.IsNullOrEmpty(indexKey) ? null : indexKey, html.ViewContext.Writer);
}
public static IDisposable BeginCollectionItem<TModel>(this IHtmlHelper<TModel> html, string collectionName, string indexValue, TextWriter writer)
{
if (collectionName == null)
throw new ArgumentNullException(nameof(collectionName), "collectionName is null or empty.");
if (string.IsNullOrEmpty(indexValue))
throw new ArgumentException("indexValue is null or empty.", nameof(indexValue));
//a hidden <input> element to hold the current index value passed in
var indexField = new TagBuilder("input");
indexField.MergeAttributes(new Dictionary<string, string>() {
{ "name", html.ViewData.TemplateInfo.GetFullHtmlFieldName(collectionName != string.Empty ? $"{collectionName}.Index" : "Index") },
{ "value", indexValue },
{ "type", "hidden" },
{ "autocomplete", "off" }
});
//Write the hidden <input> element
indexField.WriteTo(writer, HtmlEncoder.Default);
return new CollectionItemNamePrefixScope(html.ViewData.TemplateInfo, html.ViewData.TemplateInfo.GetFullHtmlFieldName($"{collectionName}[{indexValue}]"));
}
private class CollectionItemNamePrefixScope : IDisposable
{
private readonly TemplateInfo _templateInfo;
private readonly string _previousPrefix;
public CollectionItemNamePrefixScope(TemplateInfo templateInfo, string collectionItemName)
{
_templateInfo = templateInfo;
_previousPrefix = templateInfo.HtmlFieldPrefix;
templateInfo.HtmlFieldPrefix = collectionItemName;
}
public void Dispose()
{
_templateInfo.HtmlFieldPrefix = _previousPrefix;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment