Pass two templates to a sign-up view

Asked

Viewed 1,372 times

9

I have a login registration screen. I have to fill it with values registered in the database.

Follows the codes:

Models:

public partial class Aba
{
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public Aba()
    {
        this.Tela = new HashSet<Tela>();
    }

    public int idAba { get; set; }
    public string idEmpresa { get; set; }
    public string Nome { get; set; }
    public string idAbaSistema { get; set; }

    public virtual Empresa Empresa { get; set; }
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<Tela> Tela { get; set; }
}

public partial class Tela
{
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public Tela()
    {
        this.TelaFuncao = new HashSet<TelaFuncao>();
    }

    public int idTela { get; set; }
    public int idAba { get; set; }
    public string Nome { get; set; }
    public string idTelaSistema { get; set; }

    public virtual Aba Aba { get; set; }
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<TelaFuncao> TelaFuncao { get; set; }
}

public partial class TelaFuncao
{
    public int idTelaFuncao { get; set; }
    public int idTela { get; set; }
    public string Nome { get; set; }
    public string idFuncaoSistema { get; set; }

    public virtual Tela Tela { get; set; }
}

Controller:

var abas = _abaApp.SelectForeignKey("s8f50f03-c064-4afa-ba5e-397236cd2b03");
return View(abas);

Repository:

var abaQuery = _sigconEntities.Aba
                .Where(a => a.idEmpresa == idEmpresa);
return abaQuery.ToList();

View:

@model Sigcon.Model.Acesso

@{
    ViewBag.Title = "Cadastrar";
}

The problem is sending the model of these values for the view, she already this "typed", I do not know how to send the two values.

Thanks in advance!

Show 1 more comment

1 answer

10


Following the previous hook, if you have the relationship of Aba for Tela, the selection made here already contemplates the lazy load of Tela and of TelaFuncao:

var abaQuery = _sigconEntities.Aba
                .Where(a => a.idEmpresa == idEmpresa);
return abaQuery.ToList();

@model of his View, so it needs to be:

@model IEnumerable<Sigcon.Model.Aba>

@{
    ViewBag.Title = "Cadastrar";
}

And the completion:

@foreach (var aba in Model)
{
    <h1>Aba: @aba.Nome</h1>

    foreach (var tela in aba.Telas) 
    {
        <h2>Tela: @tela.Nome</h1>

        foreach (var permissao in tela.TelaFuncoes)
        {
            <p>Permissão: @permissao.Nome</p>
        }
    }
}

But as you want a creation and editing form, the solution will necessarily become more complex. I will try to make a succinct answer covering all the points.

First of all, we are dealing with a screen of multiple cardinalities. My suggestion is that first you make a screen whose Model be it Tela, and for him you can handle N Models of the kind TelaFuncao. Start with Aba will make the solution too complex for you who are starting out.

So I’ve taken some liberties and I’ll reimplement your system with a few adjustments, starting with Models:

public class TelaFuncao
{
    [Key]
    public Guid TelaFuncaoId { get; set; }
    public Guid TelaId { get; set; }

    [Required]
    public string Nome { get; set; }

    public virtual Tela Tela { get; set; }
}

public class Tela
{
    [Key]
    public Guid TelaId { get; set; }
    public Guid AbaId { get; set; }

    [Required]
    public string Nome { get; set; }

    public virtual Aba Aba { get; set; }
    public virtual ICollection<TelaFuncao> TelaFuncoes { get; set; }
}

public class Aba
{
    [Key]
    public Guid AbaId { get; set; }
    public Guid EmpresaId { get; set; }

    [Required]
    public string Nome { get; set; }

    public virtual Empresa Empresa { get; set; }
    public virtual ICollection<Tela> Telas { get; set; }
}

public class Empresa
{
    [Key]
    public Guid EmpresaId { get; set; }

    [Required]
    public string Nome { get; set; }

    public virtual ICollection<Aba> Abas { get; set; }
}

Notice also that I’m using Guid on purpose, to the detriment of int, in key definition. There are some advantages to using that can be found here.

I did this because I want to use the Entity Framework naming conventions and automatically generate everything using Scaffolding. Once done, we can generate Controllers and Views through the IDE.

For this, after you have set the 4 Models, right click on the directory Controllers and choose the option Add > Controller...:

Add Controller

On the next screen, choose MVC 5 Controller with Views, using Entity Framework:

MVC 5 Controller with Views, using Entity Framework

Right after, set the Model class, the data context class and the name of the Controller. Here I made to Empresa. Stayed like this:

EmpresasController

By clicking on Add, the result should be:

Controller gerado

Note that not only the logic of selection, detailing, inclusion, editing and deletion were generated, but also the Views correspondents of each transaction.

Repeat the process, for Tabs, Screens and Screen Functions.

Once done, you will need to install a package called Begincollectionitem. I’ve told you a lot about him here, then I’ll skip some parts.

Open the Package Manager Console (View > Other Windows > Package Manager Console) and install it.

BeginCollectionItem

Abra TelasController (I’m guessing you’ve already begotten him) and Views/Telas/Create.cshtml. Let’s start with View. Mine is like this:

@model MeuProjeto.Models.Tela

@{
    ViewBag.Title = "Create";
}

<h2>Create</h2>


@using (Html.BeginForm()) 
{
    @Html.AntiForgeryToken()

    <div class="form-horizontal">
        <h4>Tela</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        <div class="form-group">
            @Html.LabelFor(model => model.AbaId, "AbaId", htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.DropDownList("AbaId", null, htmlAttributes: new { @class = "form-control" })
                @Html.ValidationMessageFor(model => model.AbaId, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Nome, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Nome, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Nome, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
    </div>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

Between the "Create" button and the last field, Nome, place a call statement from Partial, thus:

    <div class="form-group">
        @Html.LabelFor(model => model.Nome, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Nome, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Nome, "", new { @class = "text-danger" })
        </div>
    </div>

    @Html.Partial("_Permissoes", Model.TelaFuncoes)

    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" value="Create" class="btn btn-default" />
        </div>
    </div>

That is, we are sending to another View (in the case, a View partial) only TelaFuncoes. There we’ll discover our permissions list.

Create a Partial called "_Permissions":

Partials (1)

Partials (2)

Put in it the following:

@model IEnumerable<MeuProjeto.Models.TelaFuncao>

<div class="actions">
    <a class="btn btn-default btn-sm" id="adicionar-nova-permissao">
        Adicionar Nova Permissão
    </a>
    <script type="text/javascript">
                $("#adicionar-nova-permissao").click(function () {
                    $.get('/Telas/NovaLinhaPermissao', function (template) {
                        $("#area-permissoes").append(template);
                    });
                });
    </script>
</div>

<div id="area-permissoes">
    @if (Model != null)
    {
        foreach (var permissao in Model)
        {
            @Html.Partial("_LinhaPermissao", permissao);
        }
    }
</div>

Well, if you read the code, you’ll notice we’re gonna need one more Partial calling for _LinhaPermissao. Create this Partial and put in it the following:

@model MeuProjeto.Models.TelaFuncao

@using (Html.BeginCollectionItem("TelaFuncoes"))
{
    <div class="form-group">
        @Html.HiddenFor(model => model.TelaFuncaoId)
        @Html.HiddenFor(model => model.TelaId)

        <label class="col-md-1 control-label">Nome</label>
        <div class="col-md-5">
            @Html.TextBoxFor(model => model.Nome, new { @class = "form-control", placeholder = "Nome" })
            @Html.ValidationMessageFor(model => model.Nome, "", new { @class = "text-danger" })
        </div>
        <div class="col-md-2">
            <a class="btn red" onclick="$(this).parent().parent().remove();">Excluir</a>
        </div>
    </div>
}

If you did everything right, the screen should appear like this:

Tela Criar

If you’ve noticed, in our TelasController, we need to add a method called NovaLinhaPermissao. He’s like that:

    public ActionResult NovaLinhaPermissao()
    {
        return PartialView("_LinhaPermissao", new TelaFuncao { TelaFuncaoId = Guid.NewGuid() });
    }

And now we can add and delete permissions.

BeginCollectionItem em ação

And when we add 3 permissions and send to Create of TelasController, we have the 3 permissions there.

Fim!

As an exercise, make the edit now. If you need help, open another question (this is already too big).

PS: Remove a repository from your architecture. Entity Framework is already a repository.

  • Gypsy, the access screen is one of registration, as I would recover the access values?

  • I will remove the repository, vlw by tip.

  • Ah, you want like an editing form?

  • That’s right, I have the access values and below I have the permissions of the whole system, then register everything.

  • This is a third question. I recommend you link the next question with this one.

  • But what do I write next time? It’s not the same question?

  • I can answer this one. It’s going to be huge. Okay?

  • Yes, I think the second question would be the same.

  • I told you it was gonna be huge.

  • 2

    That’s right Gypsy, but I was having trouble listing and editing kkk But you have improved my codes too much, now I can do the rest, if I need to open another question. Thank you!

Show 5 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.