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

Como colocar um atributo placeholder="" em uma <form:input/> tag do spring ?

Utilizando o autocomplete do Eclipse o atributo placeholder não consta entre as opções da tag .

Pesquisando encontrei essa resposta aqui http://stackoverflow.com/questions/18046557/how-to-use-placeholder-html-with-spring-forminput-tag-on-jsp-page que diz na realidade para utilizar uma EL dentro do valor do campo do placeholder.

Eu não compreendi muito bem. E pra piorar estou utilizando internacionalização no formulário, logo teria que ser mais ou menos algo assim ?

<form:input path="nome" cssClass="form-control" placeholder=<fmt:message key="form.nome"/>/>

ou

<form:input path="nome" cssClass="form-control" placeholder=${<fmt:message key="form.nome"/>}/>

No primeiro caso, da pau dizendo quote symbol expected e no segundo da erro também no processamento da EL.

Alguém sabe como fazer isso ? O objetivo final é apenas um texto dentor do campo para auxiliar o usuário a preencher o formulário!

7 respostas

Fala aí, Davi! Tudo certo, cara? =)

Vamos com calma... Rs.

O quote symbol expected já lhe diz a resposta! Observe que sempre que você coloca um atributo, você coloca seu valor entre aspas... Por exemplo, path="nome", ou cssClass="form-control", sacou? No caso do placeholder, é a mesma coisa:

<form:input path="nome" cssClass="form-control" placeholder="<fmt:message key='form.nome' />">

E aí, conseguiu entender? =)

Cuidado com essa bizarrice de colocar uma tag dentro do atributo de outra! Rs. Ela funciona e não está errado, mas é um pouco confuso, tem que tomar cuidado para não se confundir. Por isso use as aspas simples dentro das duplas, beleza? =)

Espero ter ajudado, mas qualquer dúvida não deixe de postar por aqui, no fórum, para que possamos ajudá-lo! =)

Abração e bons estudos,

Fábio

Olá Fábio, muito obrigado pela sua atenção até aqui!

Realmente no primeiro trecho de código inserido aqui eu esqueci de colocar as aspas duplas no valor do atributo placeholder!

Mas, colocando-as agora, passo a ter um problema que até me é mais difícil de entender.

Ao usar o formulário desta forma, com a tag html padrão:

    <form:form action="${s:mvcUrl('PC#gravar').build() }" method="POST" modelAttribute="pessoa">
                        <div class="form-group">
                            <label>Nome</label>
                            <input type="text" name="nome" class="form-control"/>
                        </div>
                        <div class="form-group messages-alert">
                            <form:errors path="nome"></form:errors>
                        </div>
                        <div class="form-group">
                            <label><fmt:message key="form.telefoneResidencialLabel"/></label>

                            <input type="text" name="telefoneResidencial" class="form-control" placeholder="<fmt:message key="form.telefoneResidencialPlaceholder"/>"/> 
                        </div>
                        <div class="form-group messages-alert">
                            <form:errors path="telefoneResidencial"></form:errors>
                        </div>
</form:form>

Tudo funciona bem.

Mas ao usar o form com a tag do spring, recebo um "Neither BindingResult nor plain target object for bean name 'pessoa' available as request attribute". Seria a tradução deste texto, nem o resultado do binding nem um objeto alvo claro para o objeto gerenciado pelo spring "pessoa" está disponível como um atributo na requisição ?

Eu tentei ler um pouco a respeito desse atributo modelAttribute no formulário e tive que coloca-lo no meu formulário pois justamente o spring estava esperando receber um objeto chamado "command" no formulário (como não dado nenhum nome ele utiliza este name como padrão). Logo quando eu coloquei o mesmo com o valor de "pessoa" ele bate com minha classe Pessoa do meu modelo e estava conseguindo enviar o formulário normalmente.

Mas eu estou com dificuldades neste tópico, e como o @ModelAttribute não foi algo abordado no curso, eu fiquei com essa lacuna aí. Eu vi algumas coisas a respeito do @ModelAttribute mas nada que eu tenha compreendido bem, por isso não vou citar aqui!

Mas a pergunta é, porque que quando utilizando a

input type="text" name=".."

do html não ocorre esse erro de binding e quando utilizando a form:input path do spring o mesmo passa a ocorrer ?

Não sei se eu fui muito claro, ou se é muita coisa, mas se alguém pudesse me dar uma luz sobre essas questões seria de grande ajuda!

Quase esqueço de colocar o controlador aqui e vou colocar a classe do modelo também ok...

@Controller
public class PessoaController {

    @Autowired
    PessoaDAO pessoaDAO;

    @InitBinder
    public void InitBinder(WebDataBinder binder) {
        binder.addValidators(new PessoaValidacao());
        new PessoaValidacao();
    }

    @RequestMapping(value = "/formPF", method = RequestMethod.GET)
    public ModelAndView formPF() {
        System.out.println("Entrando no formulário");

        ModelAndView modelAndView = new ModelAndView("pessoa/formPF");

        return modelAndView;
    }

    @RequestMapping(value = "/gravar", method = RequestMethod.POST)
    public ModelAndView gravar(@Valid Pessoa pessoaFisica, BindingResult result, RedirectAttributes redirectAttributes) {

        if (result.hasErrors()) {
            return formPF();
        }

        pessoaDAO.gravar(pessoaFisica);

        redirectAttributes.addFlashAttribute("msgSucesso", "Locatário cadastrado com sucesso");

        return new ModelAndView("redirect:listaLocatarios");
    }

    @RequestMapping(value = "/listaLocatarios", method = RequestMethod.GET)
    public ModelAndView listaLocatarios() {
        List<Pessoa> lista = pessoaDAO.getLista();
        ModelAndView modelAndView = new ModelAndView("pessoa/lista");
        modelAndView.addObject("lista", lista);
        return modelAndView;
    }


}
@Entity
public class Pessoa {

    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @Basic(optional = false)
    private String nome;

    @OneToOne(cascade = CascadeType.ALL)
    @Basic(optional = false)
    private Endereco endereco;

    @Basic(optional = false)
    private String telefoneResidencial;

    @Basic(optional = false)
    private String telefoneComercial1;

    @Basic(optional = true)
    private String telefoneComercial2;

    @Basic(optional = false)
    private String rg;

    @Basic(optional = false)
    private String documento;

    @Basic(optional = true)
    private Long tipo;

// getters and setters

}

Já percebi aqui, que não estava recebendo @ModelAttribute no controlador do método correto! O método formPF no controlador, conforme código abaixo:

@RequestMapping(value = "/formPF", method = RequestMethod.GET)
    public ModelAndView formPF(@ModelAttribute("pessoa") Pessoa pessoa) {
        System.out.println("Entrando no formulário");

        ModelAndView modelAndView = new ModelAndView("pessoa/formPF");

        return modelAndView;
    }

Com isso já foi possível pelo menos carregar o formulário novamente utilizando a form:input path tag do spring...

O valor do atributo placeholder está saindo em plain text lá no formulário.

E um melhor entendimento sobre o funcionamento do modelattribute ainda é desejado por mim!

Davi,

Muito bom! Mandou bem em achar o erro... =)

Sobre o @ModelAttribute... Você deve ter reparado que o valor que você passou entre parênteses na anotação é o mesmo do atributo modelAttribute da tag <form:form>, certo? Rs... =)

Em ambos os casos, passamos o valor pessoa!

Agora... Para que será que serve isso?!

Se pararmos para pensar, no método do Controller do Spring, estamos pedindo @ModelAttribute("pessoa") Pessoa pessoa, reparou? Essa annotation é responsável por disponibilizar o objeto para a View, fazendo um binding entre as duas camadas! Sacou? =)

Espero ter ajudado! Mas qualquer dúvida continue postando aqui até sanarmos todas elas! =)

Abraço e bons estudos,

Fábio

Fábio, conceitualmente falando, esquecendo um pouco esse meu código de exemplificação que eu postei aí, a partir de que momento se torna necessário a utilização do attributo modelAttribute no formulário e também a anotação @ModelAttribute no método do controlador ?

Pergunto isso, pois removi a anotação do método do cotrolador e o formulário continua a ser gerado com sucesso. Talvez eu não tenha dado um Clean ou um Clean Tomcat Work Directory e ainda tinha alguma "sujeira" no código e fui levado a pensar que a falta dessa anotação estava impedindo o carregamento do formulário..

E também, pelo menos utilizando as tags html padrão, o spring consegue realizar o binding naturalmente do modelo com a view sem a necessidade desse mapeamento adicional correto ?

Sobre esse código

<form:input path="telefoneResidencial" cssClass="form-control" placeholder="<fmt:message key='form.telefoneResidencialPlaceholder'/>"/>

é possível se fazer isso ou tem alguma coisa aí errada ? A view gerada ta saindo com o código em plain text na tela e o html gerado é esse aqui:

<div class="form-group">
                            <label>Telefone residencial</label>
                            <input id="telefoneResidencial" name="telefoneResidencial" class="form-control" placeholder="&lt;fmt:message key=&#39;form.telefoneResidencialPlaceholder&#39;/&gt;" type="text" value=""/>

                        </div>
solução!

Davi,

Correto! O Spring consegue fazer o binding automaticamente, sem essa anotação. Dei uma olhada na documentação para conferir e me parece que ela é utilizada quando queremos mudar o nome do objeto que estamos enviando para a View. Se não me engano, o Spring utiliza, por padrão, o nome da classe, mas com a primeira letra em minúscula... Então, acredito que ela seja desnecessária, sim. =)

Sobre a tag... Eu já vi o uso de <fmt:formatDate> dentro de outra tag e funcionou corretamente... Estranho isso. =|

De qualquer forma, você se importa em fazer um teste?

Algumas tags possuem o atributo var, que é utilizado quando queremos armazenar algum valor numa variável. Assim, você pode tentar fazer o seguinte:

<fmt:message key='form.telefoneResidencialPlaceholder' var="message" />
<form:input path="telefoneResidencial" cssClass="form-control" placeholder="${message}" />

Essa é uma forma um pouco mais organizada (na minha opinião) de se fazer as coisas... Eu não gosto muito de colocar uma tag dentro do atributo de outra.

Após o teste, coloca seu feedback aqui, por favor... Tanto se deu para entender sobre a annotation, quanto o funcionamento das tags. =)

Fábio

Fábio, muito obrigado pelas suas respostas, deu para compreender o uso sim, e eu adorei essa saída para a questão da tag aí!

Grato! Espero que esse tópico possa ajudar mais alguém com essas mesmas dúvidas...

Abraço

Davi

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software