I have a property called ProductDevelopment where I have several functions and must assign a user to each function. I have an EditorTemplate to return a list of users. I have to dynamically create a field for each function registered in the database and each field will use the EditorTemplate to list users. (as in the image below). I created a strongly typed EditorTemplate (FuncoesUsuarios.cshtml) ( @model ICollection<FuncaoUsuario>
), which generates the fields, as in the image below, but I do not know what to do so that the values are returned to the Model. I thought about using a hidden multiselect, but I'm finding it very complicated.
Myclass
publicclassFuncaoUsuario//Nãomapeado{publicintIdFuncao{get;set;}publicstringUsuario{get;set;}publicstringDscFuncao{get;set;}}
MyfieldintheView(ProductDevelopmentproperty)
publicICollection<FuncaoUsuario>ProductDevelopment{get;set;}
MyEditorTemplate->FunctionsUsers.cshtml
@modelICollection<FuncaoUsuario>@{varmodelMetaData=this.ViewData.ModelMetadata;varpropertyName=modelMetaData.PropertyName;}@foreach(FuncaoUsuarioiteminthis.Model){varid="id" + Guid.NewGuid().ToString().Substring(0, 5);
List<SelectListItem> listValues = new List<SelectListItem>();
if (!string.IsNullOrEmpty(item.Usuario))
{
listValues.Add(new SelectListItem { Selected = true, Text = item.Usuario, Value = item.Usuario });
}
<div id="@id" class="field-middle">
<h3>@String.Format(Html.LabelFor(model => model).ToString(), item.DscFuncao) :</h3>
@Html.DropDownList("", listValues, new { id = "PD" + item.IdFuncao.ToString() })
</div>
<script language="javascript" type="text/javascript">
$("#@id select")
.turnAutoComplete("@Url.Action("UsersListJson", "Security")");
</script>
}
<select name="@propertyName" multiple="multiple" size=30 style='height: 100%;' >
@foreach (FuncaoUsuario item in this.Model)
{
<option value="@item.IdFuncao">teste</option>
}
</select>
[EDITED]
I made the changes as below using BeginCollectionItem
Models:
public partial class Modelo
{
public ICollection<FuncaoUsuario> ProductDevelopment { get; set; }
//Continua...
}
public class FuncaoUsuario
{
public int IdFuncao { get; set; }
public string Usuario { get; set; }
public string DscFuncao { get; set; }
}
Controller:
public ViewResultBase Editar(int id)
{
Modelo model = this.Service.GetForEdit(this.IdEmpresa, id);
return base.SwitchView(model);
}
View Main:
@model Modelo
<div class="box-fields">
@using (Ajax.BeginForm(
this.DefaultActionEdit,
"Modelo",
new DefaultAjaxOptions()
))
{
@Html.EditorFor(i => i.ProductDevelopment) //precisa desta propriedade na view principal, pra nao dar o erro mencionado abaixo. E tem que remover o template Collection.cshtml.
foreach (FuncaoUsuario userFunction in this.Model.ProductDevelopment)
{
Html.RenderPartial("_UsuarioFuncao", userFunction);
}
//Mais coisas....
}
Partial View:
@model FuncaoUsuario
@using (Html.BeginCollectionItem("ProductDevelopment"))
{
List<SelectListItem> listValues = new List<SelectListItem>();
if (!string.IsNullOrEmpty(this.Model.Usuario))
{
listValues.Add(new SelectListItem { Selected = true, Text = this.Model.Usuario, Value = this.Model.Usuario });
}
@Html.HiddenFor(x => x.IdFuncao)
@Html.EditorFor(x => x.Usuario, "Usuario")
}
Error encountered:
Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
Source Error:
Line 1: @model FuncaoUsuario
Line 2:
Line 3: @using (Html.BeginCollectionItem("ProductDevelopment")) <- erro nesta linha.
Line 4: {