Question:
I recently asked a question about my problem, but it got a little difficult to understand, here I will try to summarize my problem.
I am using ASP.NET MVC.
I have 2 tables: Autores
and Livros
, where 1 Autor
has many Livros
.
When I create the Autor
and want to add another Livro
, I have a button that creates my fields via jQuery
, but when I save, my Controller
only takes the 1st name, the other names I added by jQuery
are not added correctly .
So let's go to the screen to register author (example):
<div class="col-xs-12 col-md-4">
@Html.LabelFor(model => model.Nome)
@Html.EditorFor(model => model.Nome)
</div>
<div class="col-xs-12 col-md-4">
@Html.LabelFor(model => model.NomeLivro)
@Html.EditorFor(model => model.NomeLivro)
</div>
//DIV PARA RECEBER OS NOVOS CAMPOS
<div id="divAddLivro"></div>
There I have my button for the jQuery call:
<button id="btnAddLivro">Adicionar Livro</button>
my jQuery
:
$("#btnAddLivro").click(function () {
$("#divAddLivro").append(''+
'<div class="col-xs-12 col-md-4">'+
' @Html.LabelFor(model => model.Nome)'+
' @Html.EditorFor(model => model.Nome)'+
'</div>'+
'<div class="col-xs-12 col-md-4">'+
' @Html.LabelFor(model => model.NomeLivro)'+
' @Html.EditorFor(model => model.NomeLivro)'+
'</div>' +
'</div>');
});
AUTHOR MODEL
public class Autor
{
[Key]
public int IdAutor { get; set; }
public string Nome { get; set; }
public ICollection<Livro> Livros{ get; set; }
}
BOOK TEMPLATE
public class Livro
{
[Key]
public int IdLivro { get; set; }
public string Nome { get; set; }
public int IdAutor { get; set; }
public ICollection<Autor> Autores { get; set; }
}
Answer:
This way what you are doing will not work anyway. You are only handling html
, but the server does not understand that you are passing a book list to the controller
.
For that, the most recommended is to use the package BeginCollectionItem .
To use it, install it from NuGet with this command:
Install-Package BeginCollectionItem
Once that's done, let's make changes to your project.
You haven't posted your Models, so I'll assume you already have the Authors list for each book.
In your controller
we need to create an Action
to return a new author. To do this, add this Action
in your Authors controller.
public ActionResult GetNewAutor()
{
var autor = new Autor()
return PartialView("_Autor", autor );
}
In this Action
we are creating a new author and returning a PartialView
with it. Your PartialView
will be the same as the code you used in append
in your question. It will look like this:
@model Projeto.Autor//Altere isso
@using (Html.BeginCollectionItem("Livros"))//O nome da sua lista
{
<div class="col-xs-12 col-md-4">
@Html.LabelFor(model => model.Nome)
@Html.EditorFor(model => model.Nome)
</div>
<div class="col-xs-12 col-md-4">
@Html.LabelFor(model => model.NomeLivro)
@Html.EditorFor(model => model.NomeLivro)
</div>
}
The name Authors of this part @using (Html.BeginCollectionItem("Livros"))
must be the same name as the virtual public virtual ICollection<Livros> Livros{get;set;}
in your Model Authors.
In your view
, we'll change the way to "duplicate" the field, using an ajax
request to the controller
.
<script>
$('#btnAddLivro').click(function () {
$.ajax({
url: '@Url.Action("GetNewAutor", "Autores")',
type: 'POST',
success: function (data) {
$('#new-autor').append(data);
}
});
});
</script>
In this request we are adding another author to your code (performing the request in the controller
).
Note that in this part $('#new-autor').append(data);
we are doing append()
from PartialView()
to the div
with id="new-autor"
. So just create an empty div
with this id wherever the inputs are added, like this:
<div id="new-autor"></div>
By doing this, when you send a save, you will have a list of authors in your Model
.