2
respostas

Form com List

Boa tarde minha duvida é a seguinte tenho um objeto que é passado pelo controller para o view (JSP), nele um dos atributos é uma List é possivel adicionar alguns objetos a list antes de dar o submit no form? e como fazer isso sendo que um

dentro de outro não é recomendado?
2 respostas

Fala Lucas, tudo bem ?

Pelo que entendi, você passa um objeto que contem uma lista pra view, onde você tem um formulário, e deseja adicionar elementos nessa lista antes de reenviar os dados do form.

Imagine o seguinte exemplo:

public class Tarefa {

    private String titulo;
    private List<Comentario> comentarios = new ArrayList<>();

    //getters and setters
    //addComentario
    //toString
}

public class Comentario {

    private String texto;
    private Calendar horario = Calendar.getInstance();

    //getters e setters 
    //toString
}

E um controller pra testar a ideia:

@Controller
public class TarefaController {

    @GetMapping("/tarefa")
    public ModelAndView exibe() {

        Comentario comentario = new Comentario();
        comentario.setTexto("Fazer lista de itens");

        Tarefa tarefa = new Tarefa();
        tarefa.setTitulo("Fazer compra do mês");
        tarefa.addComentario(comentario);

        ModelAndView view = new ModelAndView("tarefa/form");
        view.addObject("tarefa", tarefa);
        return view;
    }

    @PostMapping("/tarefa")
    public String salva(Tarefa tarefa) {

        System.out.println(tarefa);
        // salva
        return "redirect:/tarefa";
    }    
}

E a página com form já com as informações do server:

<body>
    <h1>Tarefa</h1>
    <form id="form" action="/tarefa" method="post">

        <div>
            <label>Titulo:</label>    
            <input type="text" name="titulo" value="${tarefa.titulo}"/>
        </div>

        <div id="comentarios">
            <c:forEach var="comentario" items="${tarefa.comentarios }" varStatus="status">
                <div>
                    <label>Comentario ${status.index + 1}:</label>    
                    <input type="text" name="comentarios[${status.index}].texto" value="${comentario.texto}"/>
                </div>
            </c:forEach>
        </div>
        <button onclick="adicionaComentario(event)">Adicionar Comentário</button>

        <input type="submit" value="Enviar"/>
    </form>
</body>

Basta você usar a sintaxe de lista no name do input e o Spring vai montar a listinha de acordo com os dados - name="comentarios[0].texto"

Aí você pode ter alguma coisa no seu front que possibilite criar mais campos pra você montar sua listinha e reenviar os dados:

<script type="text/javascript">
    var size = ${tarefa.comentarios.size()};

    function adicionaComentario(event) {
        event.preventDefault();

        var novoComentario = document.createElement('div');

        var label = document.createElement('label');
        label.textContent = 'Comentário ' + (size + 1) + ': ';

        var input = document.createElement('input');
        input.setAttribute('type', 'text');
        input.setAttribute('name', 'comentarios['+ size +'].texto');

        novoComentario.appendChild(label);
        novoComentario.appendChild(input);

        document.querySelector('#comentarios').appendChild(novoComentario);
        size++;
    }
</script>

A cada momento que você clica em Adicionar Comentario um novo campo será adicionado na página pra ser preenchido com os indices incrementando:

<div id="comentarios">
    <div>
        <label>Comentario 1:</label>    
        <input type="text" name="comentarios[0].texto" value="Fazer lista de itens">
    </div>
    <!-- itens adicionados dinamicamente -->        
    <div>
        <label>Comentário 2: </label>
        <input type="text" name="comentarios[1].text">
    </div>
    <div>
        <label>Comentário 3: </label>
        <input type="text" name="comentarios[2].texto">
    </div>
</div>

Aí é só fazer o submit..

Saída do método que atende o post:

Tarefa [titulo=Fazer compra do mês, comentarios=[Comentario [texto=Fazer lista de itens, horario=20:11 18/08/2017], Comentario [texto=Teste mais um, horario=20:11 18/08/2017], Comentario [texto=Mais um, horario=20:11 18/08/2017]]]

Espero ter ajudado com o exemplo.

Abraço!

Deu certo, obrigado ajudou muito!