Salve sviluppatori! È passato diverso tempo dal mio ultimo blog in italiano, perciò eccovi un metodo assolutamente utile per chi di voi sviluppa applicazioni web con ASP.NET MVC. Il metodo, che oggi vi propongo, serve per mostrare una lista di caselle di controllo (="Checkboxes"). Ricapitolando nel "Controller" vengono preparati i dati che verranno incorporati in un oggetto (="Model"), che poi verranno passati ed elaborati da una "View". Il metodo, che oggi vi presento, verrà utilizzato nella "View" ed estende la classe "HtmlHelper".
public static MvcHtmlString CheckBoxListFor<TModel, TKey, TValue>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, IDictionary<TKey, TValue>>> expForAvailableItems, Expression<Func<TModel, IList<TKey>>> expForSelectedKey)
{
return CheckBoxListFor(htmlHelper, expForAvailableItems, expForSelectedKey, x => Convert.ToString(x), x => Convert.ToString(x), null, null);
}
public static MvcHtmlString CheckBoxListFor<TModel, TKey, TValue>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, IDictionary<TKey, TValue>>> expForAvailableItems, Expression<Func<TModel, IList<TKey>>> expForSelectedKey, Expression<Func<TValue, string>> expForValueToString, Expression<Func<TKey, string>> expForKeyToString, IDictionary<String, Object> htmlAttributesForListDiv = null, IDictionary<String, Object> htmlAttributesForItemDiv = null)
{
//the name for the checkbox
string name = ExpressionHelper.GetExpressionText(expForSelectedKey);
string HtmlName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);
if (String.IsNullOrEmpty(HtmlName))
{
throw new NullReferenceException("HtmlName is null");
}
//available items
IDictionary<TKey, TValue> availableItems = expForAvailableItems.Compile().Invoke(htmlHelper.ViewData.Model);
//selected items
IList<TKey> selectedItems = expForSelectedKey.Compile().Invoke(htmlHelper.ViewData.Model);
//convert value to string function
Func<TValue, string> funcValueToString = expForValueToString.Compile();
//convert key to string function
Func<TKey, string> funcKeyToString = expForKeyToString.Compile();
//Convert to checkboxlist
TagBuilder listDiv = new TagBuilder("div");
listDiv.MergeAttributes(htmlAttributesForListDiv, true);
StringBuilder listItemsBuilder = new StringBuilder();
// Define items
// Loop through items
Int32 index = 0;
foreach (var item in availableItems)
{
// Define div
TagBuilder inputdiv = new TagBuilder("div");
inputdiv.MergeAttributes(htmlAttributesForItemDiv, true);
// Define input
TagBuilder input = new TagBuilder("input");
if (selectedItems.Contains(item.Key))
input.MergeAttribute("checked", "checked");
input.MergeAttribute("id", String.Concat(name, index));
input.MergeAttribute("name", name);
input.MergeAttribute("type", "checkbox");
input.MergeAttribute("value", funcKeyToString(item.Key));
// Define label
TagBuilder label = new TagBuilder("label");
label.MergeAttribute("for", String.Concat(name, index));
label.SetInnerText(funcValueToString(item.Value));
// Add item
inputdiv.InnerHtml = String.Format("{0}{1}", input.ToString(TagRenderMode.SelfClosing), label.ToString(TagRenderMode.Normal));
listItemsBuilder.Append(inputdiv.ToString(TagRenderMode.Normal));
index++;
}
// Return list
listDiv.InnerHtml = listItemsBuilder.ToString();
return MvcHtmlString.Create(listDiv.ToString());
}
Nel "Controller" come già accennato prima vengono preparati i dati. Nel "Model" devono esistere un dizionario del tipo IDictionary<TKey, TValue> e una IList<TKey>. Il dizionario contiene tutti gli possibili elementi che verranno mostrati come caselle di controllo (="checkboxes"); la lista contiene le chiavi delle caselle di controllo selezionate.
[HttpGet]
[Authorize]
public ActionResult Edit()
{
DataModel model = new DataModel();
model.AvailableItems = DAO.GetAvailableItems().ToDictionary(x => x.ID, x => x.Desc);
model.SelectedItems = DAO.GetSelectedItems().ToList(x => x.ID);
return View(model);
}
Nella "View" per mostrare le caselle di controllo (="Checkboxes") basta chiamare la funzione ("CheckBoxListFor") e passare ad essa il dizionario e la lista che si trovano nel "Model". Non dimenticatevi di importare il "Namespace"!
<%@ Import Namespace="CuMvcApi.Helpers.HTML" %>
<%: Html.CheckBoxListFor(x=>x.AvailableItems, y=>y.SelectedItems) %>
Spero, che vi sia piaciuto questo articolo e che vi sia utile per il vostro lavoro!