terça-feira, 12 de novembro de 2013

Último elemento de lista JSTL

Se você está em um loop c:forEach e, quer exibir ou carregar alguma coisa quando o loop estiver no último elemento, você pode usar o método getLast() do contador (varStatus) do loop.

Contador de loop c:forEach ??

Sim, a tag c:forEach nos permite criar um contador, que é nada mais que uma variável de escopo de página. Essa variável é criada a partir da especificação do atributo varStatus da tag c:forEach. Abaixo, segue um exemplo.

Exemplo 1.
<c:forEach items="${suaLista}" var="elemento" varStatus="contador">
          ${elemento.id} - ${elemento.nome} - ${elemento.email}
</c:forEach>


Para quem não entendeu o exemplo acima, mostro abaixo o trecho de código correspondente em java.

Exemplo 2
for(int i=0; i<suaLista.size(); i++){
          Object o = suaLista.get(i);
          System.out.println(o.getId() + " - " + o.getNome() + " - " + o.getEmail());
}

Se você não entendeu o exemplo acima, fico triste em te dizer que seu problema é lógica de programação. Porém, se você entendeu, vamos a uma explicação mais profunda. Na tag c:forEach o controle do loop, a criação do objeto do laço e a incrementação são automáticos. Logo, você não tem que se preocupar com isso, você só tem que se preocupar com a lógica do seu negócio.

Mas, aonde entra o contador / varStatus ????

Calma, já vamos chegar lá. Usando o exemplo 1, vamos supor que, além dos dados da lista você também quer exibir a posição da lista aonde estão aqueles dados.

Exemplo 3.
<c:forEach items="${suaLista}" var="elemento" varStatus="contador">
          ${contador.count}: ${elemento.id} - ${elemento.nome} - ${elemento.email}
</c:forEach>

O resultado desse exemplo será:

0: 1 - João - jp@gmail.com
1: 2 - Maria - maria@gmail.com
2: 3 - José - ze@gmail.com

Que count é esse ???

Esse count é um método da interface LoopTagStatus, que é acessado via reflection, logo você não precisa usar getCount() e, sim count. Esse método retorna o valor atual do contador. Dessa forma, podemos atingir o resultado acima.

Hummm, entendi o count. Mas, como uso o last ?

Você pode usar o método last da forma que quiser. Ele funciona via reflection, como o count. Segundo a documentação, ele funciona da seguinte forma:

Returns information about whether the current round of the iteration is the last one. As with isFirst(), subsetting is taken into account. isLast() doesn't necessarily refer to the status of the underlying Iterator; it refers to whether or not the current round will be the final round of iteration for the tag associated with this LoopTagStatus.

Ele retorna um booleano informando se aquela iteração é última ou não. Se for a última é porque corresponde ao último elemento do loop, senão, é porque não corresponde.

Agora que já sabemos como o last funciona, podemos ver um exemplo dele. Vamos supor que listagem de objetos do exemplo 3, no último objeto queremos uma label com a seguinte descrição "Sou o último". Segue exemplo.

Exemplo 4.
<c:forEach items="${suaLista}" var="elemento" varStatus="contador">
          ${contador.count}: ${elemento.id} - ${elemento.nome} - ${elemento.email}
          <c:if test="contador.last">
                 Sou o último.
          </c:if>
</c:forEach>

O resultado será.

0: 1 - João - jp@gmail.com
1: 2 - Maria - maria@gmail.com
2: 3 - José - ze@gmail.com Sou o último.

Galera, espero que tenham gostado de mais esse post. Se escrevi algo errado, comentem, para que eu possa consertar.

Referências:
http://stackoverflow.com/questions/3099234/jstl-foreach-omit-an-element-in-last-record
http://docs.oracle.com/javaee/5/api/javax/servlet/jsp/jstl/core/LoopTagStatus.html#isLast%28%29



Leia Mais ››

segunda-feira, 4 de novembro de 2013

Como retirar tags html de uma string - retirar html string java

Olá amigos !!

Um dia estava precisando fazer um programa que retirava tags html de uma string que vinha do banco de dados. Pensei como iria fazer aquilo. Então, comecei a pesquisar por soluções e vi algumas pessoas criando longas classes Java e scripts em Javascript para algo simples.

Cheguei a ver uma classe aonde foram registradas várias tags de html conhecidas e, depois ela checava palavra por palavra da string com as tags registradas e, retirava se achasse. Não achei aquilo muito correto pois, amanhã se fosse inventado uma nova tag, o programa não poderia ser mais aplicado.

Em um blog, vi que um leitor deu uma sugestão de uma regex para tal tarefa. Então, fui em cima disso e, consegui construir as seguintes soluções:

Regex em Java: <.*>

Regex em Javascript: <*>

Porém, existem prós e contras dessas soluções.

Prós:
- Consegue identificar qualquer tag html, visto que qualquer uma começa com < e termina com >.
- Não precisarei mais alterar esse programa.

Contra:
- Se na minha string houver algo que não seja html mas, que comece com < e termine >, o programa irá identificar isso como html e, irá retirar.

Explicação:

Se vocês notarem, em js não existe o ponto (.) e, em java existe. Essa diferença existe pelo fato de, em javascript o caractere asterisco (*) significa qualquer caractere (número ou letra) em uma quantidade de 0 a infinito. Em Java, o * significa somente que algo vai se repetir em um quantidade de 0 a infinito. Para dizermos que queremos que a regex encontre 0 ou infinitos caracteres, precisamos usar o ponto (.), onde, o mesmo significa  um caractere qualquer.
Leia Mais ››

sexta-feira, 6 de setembro de 2013

Roteiro de estudo para o livro EJB 3 Profisional - Java Persistence API

Olá mais uma vez. Há um tempo comprei o livro

e resolvi estudá-lo. Terminado meu estudo, achei interessante disponibilizar um guia para pessoas que tem esse livro ou, querem comprá-lo mas, não sabem o que ler dele, caso queriam aprender JPA.

Estudei os seguinte capítulos e tópicos:

Capítulo 1 - todo
Capítulo 2 - todo
Capítulo 4 - todo
Capítulo 6 - só estudei o tópico "Definindo Queries Nomeadas", página 197
Capítulo 8 - todo
Capítulo 9 - só estudei por completo os tópicos "Lock" e "Geração de esquema" respectivamente, página 330 e 342.

Mais uma vez, espero ter ajudado a todos.
Leia Mais ››

quinta-feira, 1 de agosto de 2013

Regex para aceitar acentos

Um dia estava precisando realizar uma validação de entrada de dados em um campo de texto. Nesse campo de texto só seria permitido entrar valores nos seguintes padrões:

aaaaa
AAAA
aaa111
AAA111
AAaa111
áááÁÁÁÁ
a-a-a
_i-i-i-i

onde:

a: representa letra qualquer que pode ir de a - z
A: representa letra qualquer que pode ir de A - Z
1: número qualquer que pode ir de 0 - 9
á: representa letra acentuada qualquer que pode ir de à-ú
Á: representa letra acentuada  qualquer que pode ir de À-Ú
_ e -: representam os caracteres _ e -

Não queria usar nenhum plugin jquery. Queria usar uma regex pois, queria algo performático. Realizando pesquisas atrás da regex, achei a solução no endereço (para quem estiver lendo esse post, recomendo olhar esse link).

http://aurelio.net/regex/guia/acentuacao.html#5_5

Analisando o conteúdo do link, montei minha regex, segue abaixo:

/^([a-zA-Zà-úÀ-Ú0-9]|-|_|\s)+$/

onde:

^ = Demarca início da linha.
[a-zA-Zà-úÀ-Ú0-9] = Representa uma letra qualquer que pode estar no intervalo de a-z ou, de A-Z, ou de à-ú, ou de À-Ú, ou um número que pode estar entre 0 ou 9.
| = Representa a operação lógica "or".
- e _ = Representam os caracteres - (hífen) e _ (underline), respectivamente.
\s = Encontra um caracter de espaço (whitespace).
+ = Representa 1 ou mais ocorrências de alguma coisa.
$ = Demarca fim de linha.

Importante: Para entender uma regex é necessário avaliar as partes em alguns momentos mas, em outros é necessário entender o todo.

Se, esta é sua primeira vez aqui no blog ou, é seu primeiro contato com regex, recomendo você dar uma olhadinha em outros posts:

http://precisoestudarsempre.blogspot.com.br/2013/03/mascara-para-valores-decimais-negativos.html
http://precisoestudarsempre.blogspot.com.br/2013/05/regex-para-datas-mascara-para-datas.html
http://precisoestudarsempre.blogspot.com.br/2013/06/regex-para-horas-mascara-para-horas.html

Recomendo também você dar uma olhadinha nesse link:

http://www.w3schools.com/jsref/jsref_obj_regexp.asp
Leia Mais ››

sexta-feira, 14 de junho de 2013

Regex para horas - Máscara para horas

Para não usarmos máscaras prontas (maskedinput, entre outros) para formatar horários em um campo de texto, podemos aplicar uma regex. Porém, existem algumas considerações a serem analisadas.

Existem dois formatos para horas. O primeiro formato é o formato AM/PM, que vai de 00 até 12, simbolizando meia noite e meio dia.

Exemplo:
10:00 pm
02:00 am
05:00 am
07:00 am
11:00 pm
11:00 am
5:00 pm

O segundo formato é o formato tradicional que vai de 00 até 00 do outro dia. Exemplo:

20:35
17:00
19:00
21:00
04:30
02:55

Já que existem dois formatos diferentes, vamos construir uma regex para cada formato. A primeira regex é para o formato AM/PM.

 (0[0-9]|1[0-2])\:[0-5][0-9]

A segunda regex é para o formato tradicional.
 
 ([0-1][0-9]|2[0-4])\:[0-5][0-9] 



Ambas regex são para o formato hh:mm.
Leia Mais ››

terça-feira, 21 de maio de 2013

Método para query dinâmica

A construção de métodos que montam queries dinâmicas requerem certos artifícios para conseguir construir um bom resultado. Um desses artifícios é o método abaixo que construí uma vez, ele recebe a query como parâmetro e avalia se nela já consta a palavra "WHERE". Se não constar, o método retorna a palavra "WHERE" mas, se constar, significa que a query já possui a cláusula WHERE, logo ele retorna "AND" visando complementar a instrução SQL.

Abaixo, descrevo o método e um exemplo de uso.

Método

public String addConditionalConnector(String query){
        if(query.indexOf("WHERE") == -1){
            return " WHERE ";
        } else {
            return " AND ";
        }
    }

Exemplo de uso:

public List listar(Objeto objeto){
StringBuilder query = new StringBuilder();
query.append("SELECT * FROM TABELA");
/*faço mais coisas*/
query.append(addConditionalConnector(query.toString()));
/*faço mais coisas*/
query.append(addConditionalConnector(query.toString()));
/*faço mais coisas e executo a query*/
}

Com esse método auxiliar, eu não preciso mais me preocupar com a sintaxe da query em relação a minha cláusula WHERE com AND, porque o método já avalia o que é necessário.

Para quem não entende SQL, seguem links:

http://www.w3schools.com/sql/default.asp
http://www.w3schools.com/sql/sql_select.asp
http://www.w3schools.com/sql/sql_where.asp
http://www.w3schools.com/sql/sql_and_or.asp
Leia Mais ››

terça-feira, 14 de maio de 2013

Regex para datas - Máscara para datas

Para validar datas é possível criar diversas soluções, como:
  • Validação server-side;
  • Utilização de plugins prontos;
  • Quebrar a string fazendo um split na barra e validando caracter por caracter via Javascript.
Existe uma outra forma, embora não tão simples mas, muito refinada e com poucas linhas de código. Essa forma é utilizar uma Regex. Em Javascript é possível criar regexs e utilizá-las para validação. Quando criamos uma regex em Javascript, um objeto do tipo RegExp é gerado e com eles métodos são disponibilizados. Abaixo, apresento-lhes uma regex que criei para realizar essa validação.

/([0-2][0-9]|3[0-1])\/(0[0-9]|1[0-2])\/[0-9]{4}/

Essa regex valida datas do formato dd/mm/yyyy. Com dias indo de 01 até 31, meses indo de 01 até 12 e anos variados.
Leia Mais ››

quarta-feira, 10 de abril de 2013

Bug $.post

Na construção de funções que utilizam os métodos para ajax do jquery, notei que existem diferenças na passagem de parâmetros.

Que diferenças são essas ?

De acordo com a documentação do jquery você realizar uma requisição ajax através dos métodos:

jQuery.ajax()
jQuery.get()
jQuery.post()

O método jQuery.ajax() ou $.ajax() realizam uma requisição ajax podendo ser GET ou POST. O método jQuery.get() realiza uma requisição GET para carregar dados do servidor, é uma "abreviação" do método $.ajax, ou seja, é equivalente à:

$.ajax({
  url: url,
  data: data,
  success: success,
  dataType: dataType
});

Finalmente o método jQuery.post() realiza uma requisição POST para carregar dados do servidor, é uma "abreviação" do método $.ajax, ou seja, é equivalente à:


$.ajax({
  type: "POST",
  url: url,
  data: data,
  success: success,
  dataType: dataType
});


Vamos analisar aqui o método $.post(). Nesse método podemos passar parâmetros de duas formas, a primeira forma é via uma string, exemplo:

function foo(){
       var valor1 = 1;
       var valor2 = 'Joao Paulo';
       $.post("sua_url", "parametro1=" + valor1 + '&parametro2=' + valor2,
                 function(retornoAjax){},
       "html");
}

Nesse exemplo, realizamos uma requisição ajax ao servidor passando dois parâmetros. Quando esses dados chegarem no servidor, o parametro1 vai chegar com o valor "1" e o parametro2 vai chegar com o valor "Joao Paulo". A integridade dos dados vai ser mantida mas, se mudarmos só um pouco o exemplo teremos um problema.


function foo(){
       var valor1 = 1;
       var valor2 = 'João Paulo';
       $.post("sua_url", "parametro1=" + valor1 + '&parametro2=' + valor2,
                 function(retornoAjax){},
       "html");
}

Quando esses dados chegarem no servidor, o parametro1 vai continuar com o valor 1 mas, o parametro2 vai vir com caracteres estranhos, "quebrados", quadradinhos e afins. Para solucionar esse problema, temos que passar os parâmetros de uma outra forma, via JSON. Passando os parâmetros via JSON, conseguimos manter a integridade dos dados quando eles chegam no servidor. Para passar parâmetros via JSON, teremos de modificar um pouco nossa função.


function foo(){
       var valor1 = 1;
       var valor2 = 'João Paulo';
       $.post("sua_url", {parametro1: valor1, parametro2: valor2},
                 function(retornoAjax){},
       "html");
}

Caso você tenha dúvidas de como trabalhar com JSON, recomendo dar uma lida em outro post aqui do blog. Desse jeito podemos manter a integridade dos nossos dados e, o valor do parametro2 chegar no servidor como "João Paulo". Podemos também alterar um pouco mais nossa função caso queiramos passar mais parâmetros.


function foo(){
       var valor1 = 1;
       var valor2 = 'João Paulo';
       var parametros = {

      'parametro1' : valor1,
              'parametro2' : valor2
       };
       $.post("sua_url", parametros,

                 function(retornoAjax){},
       "html");
}


Leia Mais ››

segunda-feira, 1 de abril de 2013

Passar parâmetros no forward da action

Existem várias formas de passar paramêtros em uma querystring. Para quem não sabe o que é uma querystring, querystring é tudo que se localiza após o ? em uma url, exemplo:

www.meusite.com.br/blablabla?minhaquerystring

A função da querystring é passar parâmetros para suas classes de servidor. Quando se constrói um sistema usando struts, às vezes é necessário passar parâmetros pelo forward no seu struts-config. Agora, você pensa, "isso é fácil" e, realmente é, segue exemplo:

<action path="/minhaAction" name="meuForm" type="caminhodaminhaaction.MinhaAction" scope="request" validate="false">
            <forward name="fwd-sucesso" path="/minhaActionForward.do?parametro1=valor" redirect="false"></forward>
</action>

Nesse exemplo, passamos só um parâmetro pelo forward da action mas, e se quisessemos passar mais ? Então você pensa, "isso também é fácil, é só por o & depois do valor do parâmetro1". Só que você está


ENGANADO

Se você fizer isso, sua aplicação vai gerar um erro dizendo que não consegue reconhecer o sinal de &. Procurando por uma solução, achei o link abaixo, que descreve a solução.

http://www.guj.com.br/java/45037-struts-parametros-via-url-no-forward-de-um-action-

A solução é simples, ao invés de por o &, ponha &amp; e construa sua querystring normalmente, segue exemplo:

<action path="/minhaAction" name="meuForm" type="caminhodaminhaaction.MinhaAction" scope="request" validate="false">
               <forward name="fwd-sucesso" path="/minhaActionForward.do?parametro1=valor&amp;parametro2=valor&amp;parametro3=valor" redirect="false"></forward>
</action>
Leia Mais ››

quarta-feira, 13 de março de 2013

Máscara para valores decimais negativos

Máscaras para valores decimais negativos é sempre algo bem chato e complicado de achar, nas minhas pesquisas na net não achei nada que me ajudasse, o plugin maskedinput não pode me ajudar nessa situação pois, ele se encaixa muito bem para valores fixos tipo, datas, horários, cpf/cnpj, rg e por ai vai.

Outro plugin que achei que talvez fosse me ajudar era o maskedmoney(ou alguma coisa assim) mas, também não era o que eu queria. Então pensei:

"Porque não faço a minha própria máscara ?"

Mãos à obra.

Já sabia que iria ter d fazer uma regex em javascript se queria uma solução limpa e eficaz, só que ai surgia um outro grande problema, como fazer a tal Regex ? Depois de quebrar muito a cabeça e ter ajuda de um guru do javascript, Leonardo Dutra, conseguimos construir uma regex que pudesse validar campos decimais negativos e positivos.

/^-?[0-9]{1,3}(?:\.[0-9]{2})?$/

Ai está a obra prima mas, agora precisamos entender o que isso faz para que possamos construir outras no futuro. Em javascript, a barra / no início e no fim é obrigatório, isso é próprio da linguagem pois, quando você constrói uma regex um objeto RegExp é gerado, logo você deverá sempre por.

O símbolo ^ denota início de sentença, logo estamos construindo uma regex que vai validar inícios de sentença.

Os símbolos -? significam que eu posso ter 1 ou nenhuma ocorrência do sinal negativo(-), o ? dá esse significado de 1 ou 0 ocorrências.

[0-9] significa que eu posso ter um número de 0 à 9. {1,3} significa que você pode ter de 1 à três ocorrências mas, de que ? Note que o [0-9] e o {1,3} estão juntos, logo eu posso ter de 1 à 3 ocorrências de números que vão de 0 à 9.

O segredo de entender uma regex é saber avaliar as partes mas, também saber avaliar o todo.

Os parênteses () significam agrupamento e, o ?: significa que realizo um agrupamento sem guardar dados em um vetor interno mas, hein ? Quando você monta uma regex agrupada os valores capturados por ela são guardados em um vetor para utilização futura.

A contra barra \ significa caracter de escape, por que usei isso ?A máscara deve aceitar ponto como separador decimal mas, o caracter . têm significado próprio no contexto da regex, logo uso a contra barra para dizer ao javascript que o caracter ponto não deve ser levado em conta como sendo uma regex. Logo, após o ponto encontramos outro [0-9], já sabemos o que significa.

O {2} significa que só posso ter duas ocorrências de ?:\.[0-9], ou seja, eu só posso ter duas casas depois da vírgula. Logo, após o fecha parênteses ) encontramos um ?. Isso significa que 1 ou nenhuma ocorrência de (?:\.[0-9]{2}), ou seja, que eu posso ter duas casas depois da vírgula ou não para que tais valores sejam aceitos:

-7
-85
-856
85
99
2
856.55
-856.55

O sinal de $ denota fim de sentença, logo estamos validando também o fim da sentença também. Podemos notar que construimos uma regex fechada. Para por em prática essa regex podemos usar métodos especiais para isso, como o test() que valida se um valor passado como parâmetro está de acordo com a regex ou não, retornando true ou false.

Qualquer dúvida é só comentar.

Leia Mais ››

quinta-feira, 21 de fevereiro de 2013

Gifs para loading

Um dia estava precisando de um gif para loading e achei vários site que disponibilizavam download mas, o que mais me interessou foi o site:

http://www.ajaxload.info/

Nesse site é possível você escolher um tipo de gif e personalizá-lo, mudar sua cor e por ai vai. Depois de escolher as características de seu gif é só gerá-lo e fazer o download. Ferramenta muito útil e ótimo quebra galho.
Leia Mais ››

segunda-feira, 18 de fevereiro de 2013

Chamdas de funções nos browsers

Esse tópico é algo muito curioso e particular do IE6. Em javascript é possível tem uma função recebendo x parâmetros, onde x é um número maior que 0 e é possível chamá-la não passando todos os parâmetros, segue exemplo:

function foo(param1, param2, param3){
/*código*/
}

function foo2(){
      foo("a", "b");

}

Note que só passei dois paramêtros na chamada de foo em foo2, quando todo esse código for executado o que virá como valor no param3?

É aí que entra a grande questão. Nos browsers ie7( e versões superiores), firefox, chrome, opera e safari o parâmetro que falta vai com o valor de "undefined" para a função foo(), porém no ie6 ele usa o último valor da pilha de chamada de função.

COMO ASSIM ?

O ie6 usa o último valor de parâmetro passado quando ele nota que numa função que recebe x parâmetros são passados menos que x. Um exemplo deve esclarecer as coisas.

Vamos continuar utilizando a função foo() definida lá em cima.

function foo3(){
    foo('a', 'b', 'c');
   /*codigo*/
   foo('a', 'b');
}

Na segunda chamada de foo, o valor de param3 virá como 'c' mesmo eu não tendo passado nada para ele na segunda chamada, logo ele utiliza o último valor da pilha de chamadas de funções. Isso pode causar problemas em seus scripts quando você quer construir um sistema que rode em todos os browsers. Uma das soluções para esse problema é sempre passar todos os parâmetros ou forçar a passada de "undefined" para a função.
Leia Mais ››