I have a 1: N relationship between Person and Contact. In my view, I can list all the contacts of a client when it is opened.
Ineedtoimplementthe"New Contact" button so that when clicked, dynamically add the fields (Type of Contact, Contact, Main Contact, Details and Delete Button) ... I tried to do with Java Script and I managed, but I have had problems with validations that did not work and the "combobox ContactType" that does not populate ... This is because I could not use the asp.net core asp- "validation-for" and "asp-items" tags in the block JavaScript ...
I made a FOR to receive the database data and the validations and combobox work correctly. The problem is in the JS block that does not work. How do I make it work in JavaScript?
@model Retaguarda.Application.ViewModels.Pessoa.PessoaViewModel
@{
ViewData["Title"] = "_PessoaContato";
}
<div class="form-horizontal">
<div class="form-group row">
<div class="col-md-12">
<div class="col-md-12" id="div-contatos">
@if (Model.PessoasContatosViewModel != null)
{
@for (int i = 0; i < Model.PessoasContatosViewModel.Count; i++)
{
<div class="row align-items-center">
<div class="col-md-2">
@Html.HiddenFor(model => model.PessoasContatosViewModel[i].Id, new { @class = "hid-id" })
<label asp-for="PessoasContatosViewModel[i].ContatoTipoId" class="control-label sel-contatoTipo">Tipo de Contato</label>
<select asp-for="PessoasContatosViewModel[i].ContatoTipoId" asp-items="Model.ContatosTipos" data-plugin="selectpicker" title="Selecione uma opção" class="form-control show-tick show-menu-arrow sel-contatoTipo"></select>
<span asp-validation-for="PessoasContatosViewModel[i].ContatoTipoId" class="text-danger"></span>
</div>
<div class="col-md-4">
<label asp-for="PessoasContatosViewModel[i].Contato" class="control-label txt-contato">Contato</label>
<input type="text" asp-for="PessoasContatosViewModel[i].Contato" class="form-control txt-contato" />
<span asp-validation-for="PessoasContatosViewModel[i].Contato" class="text-danger"></span>
</div>
<div class="col-md-2">
<label class="control-label"> </label>
<div class="checkbox-custom checkbox-default">
<input type="checkbox" asp-for="PessoasContatosViewModel[i].ContatoPrincipal" class="ckb-contatoPrincipal" checked autocomplete="off" />
<label asp-for="PessoasContatosViewModel[i].ContatoPrincipal" class=" ckb-contatoPrincipal">Contato Principal</label>
</div>
</div>
<div class="col-md-3">
<label asp-for="PessoasContatosViewModel[i].Detalhes" class="control-label txt-detalhes">Detalhes</label>
<textarea asp-for="PessoasContatosViewModel[i].Detalhes" class="form-control txt-detalhes"></textarea>
<span asp-validation-for="PessoasContatosViewModel[i].Detalhes" class="text-danger"></span>
</div>
<div class="col-md-1">
<button type="button" class="btn btn-icon btn-default btn-outline btn-remover-contato" data-id="@Model.PessoasContatosViewModel[i].Id." style="margin-top: 30px;"><i class="icon wb-trash" aria-hidden="true"></i></button>
</div>
</div>
}
}
</div>
</div>
</div>
<div class="form-group row">
<div class="col-md-12">
<div class="col-md-2">
<button id="btn-add-contato" type="button" class="btn btn-icon btn-default btn-outline"><i class="icon wb-plus" aria-hidden="true"></i> Novo Contato</button>
</div>
</div>
</div>
</div>
<script>
$(function () {
var qtdContatos = 0;
$("#btn-add-contato").click(function (e) {
e.preventDefault();
var blocoContato = '<div class="row align-items-center">' +
' <div class="col-md-2" >' +
' <label name="PessoaContatoViewModel[' + qtdContatos + '].ContatoTipoId" class="control-label sel-contatoTipo">Tipo de Contato</label>' +
' <select name="PessoaContatoViewModel[' + qtdContatos + '].ContatoTipoId" data-plugin="selectpicker" title="Selecione uma opção" class="form-control show-tick show-menu-arrow sel-contatoTipo"></select>' +
' </div >' +
'<div class="col-md-4">' +
' <label name="PessoaContatoViewModel[' + qtdContatos + '].Contato" class="control-label txt-contato">Contato</label>' +
' <input type="text" name="PessoaContatoViewModel[' + qtdContatos + '].Contato" class="form-control txt-contato" />' +
' </div>' +
' <div class="col-md-2">' +
' <label class="control-label"> </label>' +
' <div class="checkbox-custom checkbox-default">' +
' <input type="checkbox" name="PessoaContatoViewModel[' + qtdContatos + '].ContatoPrincipal" class="ckb-contatoPrincipal" checked autocomplete="off" />' +
'<label for="PessoaContatoViewModel[' + qtdContatos + '].ContatoPrincipal class="ckb-contatoPrincipal">Contato Principal</label>' +
'</div>' +
' </div>' +
' <div class="col-md-3">' +
'<label name="PessoaContatoViewModel[' + qtdContatos + '].Detalhes" class="control-label txt-detalhes">Detalhes</label>' +
'<textarea name="PessoaContatoViewModel[' + qtdContatos + '].Detalhes" class="form-control txt-detalhes"></textarea>' +
'</div>' +
'<div class="col-md-1">' +
'<button type="button" class="btn btn-icon btn-default btn-outline btn-remover-contato" style="margin-top: 30px;"><i class="icon wb-trash" aria-hidden="true"></i></button>' +
' </div>' +
' </div>';
$("#div-contatos").append(blocoContato);
qtdContatos++;
});
$("#div-contatos").on("click", ".btn-remover-contato", function (e) {
e.preventDefault();
$(this).parent().parent().remove();
qtdContatos--;
$("#div-contatos .row").each(function (indice, elemento) {
$(elemento).find(".sel-contatoTipo").attr("name", "PessoaContatoViewModel[" + indice + "].ContatoTipoId");
$(elemento).find(".txt-contato").attr("name", "PessoaContatoViewModel[" + indice + "].Contato");
$(elemento).find(".ckb-contatoPrincipal").attr("name", "PessoaContatoViewModel[" + indice + "].ContatoPrincipal");
$(elemento).find(".txt-detalhes").attr("name", "PessoaContatoViewModel[" + indice + "].Detalhes");
});
});
});
</script>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
Controller:
[HttpGet]
[Authorize(Policy = "CanWritePessoaData")]
[Route("pessoa-gerenciar/editar-pessoa/{id:int}")]
public IActionResult Edit(int? id)
{
if (id == null)
{
return NotFound();
}
var pessoaViewModel = _pessoaAppService.GetJoinById(id.Value);
if (pessoaViewModel == null)
{
return NotFound();
}
pessoaViewModel.PessoaGenericoViewModel.Filiais = PreencherFiliais();
pessoaViewModel.ContatosTipos = PreencherContatodosTipos();
return View(pessoaViewModel);
}
ViewModels:
public class PessoaViewModel
{
[Key]
public int Id { get; set; }
[DisplayName("Natureza")]
[Required(ErrorMessage = "Escolha uma Natureza")]
public PessoaNatureza PessoaNatureza { get; set; }
[DisplayName("Natureza")]
public string PessoaNaturezaDescricao { get; set; }
[DisplayName("Naturezas")]
public IEnumerable<SelectListItem> PessoasNaturezas { get; set; }
public PessoaGenericoViewModel PessoaGenericoViewModel { get; set; }
public IEnumerable<PessoaGenericoViewModel> PessoasGenericosViewModel { get; set; }
public IEnumerable<SelectListItem> ContatosTipos { get; set; }
public List<PessoaContatoViewModel> PessoasContatosViewModel { get; set; }
public PessoaFisicaViewModel PessoaFisicaViewModel { get; set; }
public PessoaJuridicaViewModel PessoaJuridicaViewModel { get; set; }
public PessoaViewModel()
{
PessoasNaturezas = ExtensaoDeEnumerador.EnumParaSelectListGenerico<PessoaNatureza>("U", PessoaNatureza.ToString()).OrderBy(x => x.Text);
PessoaFisicaViewModel = null;
PessoaJuridicaViewModel = null;
}
}
public class PessoaContatoViewModel
{
[Key]
public int Id { get; set; }
public int PessoaId { get; set; }
[DisplayName("Tipo de Contato")]
[Required(ErrorMessage = "Escolha um Tipo de Contato")]
public int ContatoTipoId { get; set; }
[DisplayName("Tipo de Contato")]
public string ContatoTipoDescricao { get; set; }
[DisplayName("Tipos de Contato")]
public IEnumerable<SelectListItem> ContatosTipos { get; set; }
[DisplayName("Contato")]
[Required(ErrorMessage = "O campo Contato é obrigatório")]
[MaxLength(100, ErrorMessage = "O campo {0} deve ter no máximo {1} caracteres")]
public string Contato { get; set; }
[DisplayName("Detalhes")]
[MaxLength(150, ErrorMessage = "O campo {0} deve ter no máximo {1} caracteres")]
public string Detalhes { get; set; }
[DisplayName("Contato Principal")]
public bool ContatoPrincipal { get; set; }
}