A dynamic field for each database record

3

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:  {  
    
asked by anonymous 18.08.2015 / 17:40

1 answer

3

This is a classic case of using the NuGet BeginCollectionItem package. It is not native to ASP.NET MVC or Razor. It needs to be installed.

I have already answered several questions about . If necessary, please edit your question so that I can make the appropriate complements in the answer.

EDIT

Having this error:

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

This is because the BeginCollectionItem inserts a EditorTemplate named Collection.cshtml which can give some problems. It is recommended that you delete it to set your Partial .

The exact location of this Template is Views\Shared\EditorTemplates\Collection.cshtml .

    
18.08.2015 / 18:11