Solucionado (ver solução)
Solucionado
(ver solução)
6
respostas

Adicionar, editar e deletar elementos em uma table do html usando Model

Pessoal, estou com uma dúvida que não consegui encontrar em lugar nenhum dos cursos da Alura, e nem em nenhuma pesquisa.

Como posso estar adicionar, editando e deletando elementos de uma table do html usando o Model do Razor?

Um exemplo básico com AlunoViewModel:

public class AlunoView Model
{
    public Aluno Aluno {get; set;}
    public IList<Livro> Livros {get; set;}
}

E no html algo como:

@model Teste.ViewModels.AlunoViewModel
...
...
...
<h2>Dados do Aluno</h2>
@EditorFor(model => model.Aluno.Nome, new { @placeholder="Nome do aluno" } )
@EditorFor(model => model.Aluno.Idade, new { @placeholder="Idade do aluno" } )

<h2>Livros do aluno</h2>
<table>
    <thead>
        <th>Nome do Livro</th>
        <th>Autor</th>
        <th>Categoria</th>
        <th>ISBN</th>
        <th>Editar Livro</th>
        <th>ExcluirLivro</th>
    </thead>
    <tbody>
        <tr>
            <td>Livro x</td>
            <td>Autor y</td>
            <td>Categoria z</td>
            <td>9999999</td>
            <td><a href="modal de adição e edição">Editar</a></td>
            <td><button onclick="Remove(this)"></button></td>
        </tr>
    </tbody>
</table>
...
<button type="submit">Salvar</button>
...
...
...
<!--  modal de inserção de livros-->
<div class="modal inmodal" id="myModal" tabindex="-1" role="dialog" aria-hidden="true">
...
</div>

No caso usando um modal mesmo para adicionar ou editar livros.

Como posso estar implementando isso com Model do Razor? Já tentei fazer aqui de várias formas com javascript e não consegui.

6 respostas

Olá Lucas,

para fazer este trabalho na verdade vai envolver muito mais trabalho de js do que com o c#. O problema é que o Model e o Razor só funcionam do lado do servidor, quando a página chega no navegador do usuário tem apenas html, css e js. Então você não tem mais o objeto da Model.

No caso da operação de remove, o que você pode fazer fazer é uma requisição com AJAX para o servidor, parecido com o que tem no curso. Se der tudo certo, o seu código js se encarrega de apagar a linha da tabela.

Quanto ao adicionar e editar com o modal, dentro da div do modal você precisará deixar já o formulário com os campos necessários prontos. Na caso de clicar no botão de adicionar ele só mostrará o formulário. Já se clicar no link de edição, então será necessário que o seu js preencha os campos dependendo de quem foi clicado. Uma técnica que você pode usar para recuperar esta informação seriam os data atributes. Por exemplo, vamos supor que na sua tabela tenha uns 5 livros. Cada livro teria o seu link de edição, então um livro de id 1 ficaria assim:

<a href="#" class="editar" data-id="1" data-titulo="Harry Potter e a Pedra Filosofal" data-autor="JK" data-categoria="livro">Editar</a>

Marcando o campo deste jeito, você consegue via javascript recuperar a informação assim:

$(".editar").click(function(){
    var id = $(this).data('id');
    var titulo = $(this).data('titulo');
    var autor = $(this).data('autor');
    var categoria = $(this).data('categoria');
    //preenche os campos e chama o modal
})

Entendi Lucas, obrigado pela ajuda, o que você me indicaria fazer para o caso de excluir, tipo se remover algum elemento na posição 3 de um vetor de 10, precisaria fazer um algoritmo para trazer os outros para uma posição anterior a partir do 4 certo?

Eu estou tentando também sem o modal, onde o usuario clica em adicionar e na função do click no js eu faço tipo isso:

var tr = '<tr><td>@Html.EditorFor(model => model.Livros[0].Nome)</td></tr>';
$('#tbody').append(tr);

Só que se eu fizer um Html.DropDownListFor, ele quebra a linha e acaba quebrando o codigo js.

Não precisa fazer todo esse trabalho no caso da remoção. Você só precisa executar algum comando que apague a <tr> do livro que você deseja apagar. Você pode, por exemplo, dar atributos id para as <tr> que o jquery possui uma função chamada remove() que apaga o elemento da tela. Ficaria algo assim no js:

$("#livro_" + <id do livro>).remove();

E o id da tr pode ser algo do tipo:

<tr id="livro_<id do livro>">
...
</tr>

No caso do adicionar sem o modal, pelo código dá a entender que você quer que o campo que será preenchido esteja na tabela, é isso? E que a requisição será feita via ajax? Se for isso, este append da tr só será feito no caso de sucesso da requisição. E a tr terá que ser construída em cima da resposta que veio do servidor.

Agora sim Lucas, legal, mas o único detalhe que não falei é que eu irei armazenar os dados somente após o usuário der o submit no formulário, pois este formulário possui vários outros campos, dessa forma vou usar o método closest() do jquery para remover a tr. E essa parte dos livros estou fazendo em uma tabela mesmo.

Só não entendi porque não preciso implementar algo para voltar as outras posições, pode ficar null mesmo essa posição que eu excluir da lista de livros? O Razor entende?

solução!

Se o remove você fizer usando ajax, quando o usuário clicar no remove em teoria o livro já foi apagado.

Agr se você só quer que ele seja removido também no momento do submit, ai fica de fato um pouco mais chatinho. Neste caso, ai sim você terá que fazer um js que ajuste os names dos elementos que restaram para voltarem uma posição para a lista que o controller receber não ficar com valor nulo. Outra opção que eu acho mais simples do que ficar ajustando o name a cada vez que um elemento é removido, é na verdade os campos ficarem sem name a princípio e no momento do submit do formulário seja executado um js que atribui os names. Que aí é só passar Livros[0].Titulo para o titulo do livro na primeira linha, Livros[1].Titulo para a segunda e assim por diante.

E cuidado com o Razor, porque ele não estará presente nesse momento de ajustar a posição dos elementos da tela. Isso será feito via js na verdade. O Razor só opera do lado do servidor, quando está havendo a conversão do cshtml para html.

Muito bom Lucas, me ajudou bastante, vou trabalhar nisso agora!!! Parabéns e obrigado pela atenção!