Search code examples
c#asp.net-mvcasp.net-mvc-4dynamicmvc-editor-templates

A dynamic input for each record of a table in the database


I have a property called UserFunctions where I have several functions and must assign a User for each function. I have a EditorTemplate to return a list of users. I have to create a field dynamically for each function registered in the database and each field will use the EditorTemplate to list users. (like the image below). I created a EditorTemplate (UserFunctions.cshtml) strongly typed (model ICollection ) which generates the fields, like the image below, but I do not know what to do so that the values are returned to the Model. I thought of using a hidden multiselect, but is very complicated.

enter image description here

My class

public class FunctionUser //Não mapeado
{
    public int IdFuncao { get; set; } //functin id
    public string Usuario { get; set; } //User
    public string DscFuncao { get; set; } //Function Description
}

My Field in the View (property UserFunctions)

@Html.EditorFor(i => i.UserFunctions, "UserFunctions")

My EditorTemplate -> UserFunctions.cshtml

@model ICollection<FunctionUser>
@{
    var modelMetaData = this.ViewData.ModelMetadata;
    var propertyName = modelMetaData.PropertyName;    
}




@foreach (FunctionUser item in this.Model)
{
    var id = "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(ModeloResources.ProductDevelopment, 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 (FunctionUser item in this.Model)
{   
<option value="@item.IdFuncao">teste</option>
}
</select>

Solution

  • Someone answered my question in "pt.stackoverflow.com". The solution was to use the BeginCollectionItem package.

    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);
    }
    

    Main View:

     @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")    
    }
    

    Following link: Solution using BeginCollectionItem