I got the following code from the internet for CheckboxListFor html helper extension. At the moment, in the SelectedValues it is returning a List<string> of selected values from the checkboxlist. I want to get a comma-separated string in SelectedValues.
Can anyone tell me how I can achieve it?
Here is the code:
HTMLHelper extension:
/// <summary>
/// Returns a checkbox for each of the provided <paramref name="items"/>.
/// </summary>
public static MvcHtmlString CheckBoxList(this HtmlHelper htmlHelper, string listName, IEnumerable<SelectListItem> items, object htmlAttributes = null)
{
var container = new TagBuilder("div");
foreach (var item in items)
{
var label = new TagBuilder("label");
label.MergeAttributes(new RouteValueDictionary(htmlAttributes), true);
var cb = new TagBuilder("input");
cb.MergeAttribute("type", "checkbox");
cb.MergeAttribute("name", listName);
cb.MergeAttribute("value", item.Value ?? item.Text);
if (item.Selected)
cb.MergeAttribute("checked", "checked");
label.InnerHtml = cb.ToString(TagRenderMode.SelfClosing) + item.Text;
container.InnerHtml += label.ToString();
}
return new MvcHtmlString(container.ToString());
}
private static IEnumerable<SelectListItem> GetCheckboxListWithDefaultValues(object defaultValues, IEnumerable<SelectListItem> selectList)
{
var defaultValuesList = defaultValues as IEnumerable;
if (defaultValuesList == null)
return selectList;
IEnumerable<string> values = from object value in defaultValuesList
select Convert.ToString(value, CultureInfo.CurrentCulture);
var selectedValues = new HashSet<string>(values, StringComparer.OrdinalIgnoreCase);
var newSelectList = new List<SelectListItem>();
selectList.ForEach(item =>
{
item.Selected = (item.Value != null) ? selectedValues.Contains(item.Value) : selectedValues.Contains(item.Text);
newSelectList.Add(item);
});
return newSelectList;
}
/// <summary>
/// Returns a checkbox for each of the provided <paramref name="items"/>.
/// </summary>
public static MvcHtmlString CheckBoxListFor<TModel, TValue>(this HtmlHelper<TModel> htmlHelper,
Expression<Func<TModel, TValue>> expression,
IEnumerable<SelectListItem> items, object htmlAttributes = null)
{
var listName = ExpressionHelper.GetExpressionText(expression);
var metaData = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
items = GetCheckboxListWithDefaultValues(metaData.Model, items);
return htmlHelper.CheckBoxList(listName, items, htmlAttributes);
}
In the view:
@Html.CheckBoxListFor(model => model.SelectedValues, Model.MySelectList)
Model:
public class MyViewModel
{
public SelectList MySelectList{ get; set; }
public List<string> SelectedValues{ get; set; }
//public string SelectedValues{ get; set; } Can I get comma separated string here
}
Note that I need comma separated string returned from the helper not after I got back list on the controller action.
Why I am trying to do this?:
//Here in my model, I am getting `SelectedValues` which is a List<String>.
public ActionResult Index(MyViewModel model)
{
//My code....
}
In View
//But I cannot save this list into RouteValueDictionary like:
var searchCriteria = new RouteValueDictionary();
searchCriteria["model.SelectedValues"] = Model.SelectedValues; // List<string> cannot be save here. That's why I needed comma separated string.
var viewDataDictionary = new ViewDataDictionary();
viewDataDictionary["searchCriteria"] = searchCriteria;
@Html.Partial("_MyPagingView", Model.MyList, viewDataDictionary)
There is a whole mechanism inside the _MyPagingView which calls Index Action whenever next page is clicked. And to preserve the state of the search we need to keep our searched data inside RouteValueDictionary.
string.Joinin the controller action