Solução para bind com date no grails, no uso de Jquery ui.
Autor: Bosco Moreira | Publicado: 2011-10-14T20:31:00-07:00


Como pode ser visto na documentação da tag datepicker do grails, ele gera os campos (day, month, year), hour e minute, para realizar diretamente o bind em um domain que possui um java.util.Date como propriedade. Ao usar a tag datepicker isso acontece muito bem, ocorre que não é visualmente agradável essa propriedade.

&nbsp;


Visualmente o datepicker do jquery ui é uma maravilha, mas nem tudo é perfeito. O problema é que para usá-lo é necessário fazer pequenas adaptações (POG :D). Visto que ele gera uma string para o controller e assim fica complicado de trabalhar.













Concluindo, o ideal era que o datepicker do jquery ui fizesse o que a tag datepicker do grails faz. Então vamos gerar nossa própria tag que junte a beleza com a funcionalidade do bind automático. Para isso, crie uma tagLib no seu projeto e adicione o código uiDatePicker. Lembre que para que a tag funcione corretamente é necessário possuir o jquery e jquery ui instalados corretamente no projeto. Note que adicionei o mask também, mas se não o quiser pode remover o trecho do código que gera a mascara de data. O padrão regional do jquery ui datepicker pode ser encontrato aqui. Para usá-lo você deve baixar o pacote desejado, importar no projeto e passar no atributo regional da tagLib que criou. Verá que criei minha tagLib com o namespace iTag, isso não é uma obrigação, pode criar como quiser o deixar sem namespace definido. Por padrão do datepicker do jquery ui, deixar sem definição de regional, faz com que a linguagem escolhida seja inglês. Veja como definir para português do Brasil.











O resultado abaixo foi conseguido utilizando o regional pt-BR. Em seguida o resultado do código no firebug. Boa sorte !! xD




com pt-BR




resultado no firebug



Lembrando que essa não é a única solução. Se preferir é possível 
customizar uma classe que implemente a interface PropertyEditorRegistrar, responsável por realizar 
binds nas propriedades.&nbsp; Acesso o blog Felipenasc, lá poderá ver detalhes dessa outra solução.







... 

def uiDatePicker = { attrs ->
  def name = attrs.name
  def id = attrs.id ?: onlyField(name)
  def clazz = attrs.class ?: ''
  def format = attrs.formatDate ?: 'dd/mm/yy'
        def formatJava = attrs.formatDateJava ?: 'dd/MM/yyyy'
        def regional = attrs.regional ?: ''
  def showButtonPanel = attrs.showButtonPanel
  def changeMonth = attrs.changeMonth
  def changeYear = attrs.changeYear
  def showWeek =  attrs.showWeek
  def firstDay = attrs.firstDay ?: 1
  def numberOfMonths = attrs.numberOfMonths ?: 3
  def maskFormat = attrs.maskFormat
  def minDate = attrs.minDate
        def value = attrs?.value

        def title = attrs.title ?: ''
        def onkeypress = attrs.onkeypress

  // field
  out << ""
  // date
  out << ""
  out << ""
  out << ""
  // time
  try{
            out << ""
            out << ""
        }catch (IllegalArgumentException e){
            out << ""
            out << ""
        }


        // script
  out << ""
  out << "\$(document).ready(function(){"
  if(maskFormat){
   out << "     \$('#${id}').mask('${maskFormat}');"
  }

  out << "    \$('#${id}').datepicker({"
  out << "        dateFormat: '${format}'"
  if(showButtonPanel){
   out << "    ,showButtonPanel: ${showButtonPanel}"
   out << "    ,numberOfMonths: ${numberOfMonths}"
  }
  if (minDate) {
   out << "    ,minDate: ${minDate}"
  }
  if(changeMonth){
   out << "    ,changeMonth: ${changeMonth}"
  }
  if(changeYear){
   out << "    ,changeYear: ${changeYear}"
  }
  if(showWeek){
   out << "    ,showWeek: ${showWeek}"
   out << "    ,firstDay: ${firstDay}"
  }
  out << "       ,onClose: function(dateText,inst) {"
        out << "        var date = \$('#${id}').datepicker( 'getDate' );"
        out << "            \$('#${id}_day').val(date.getDate());"
  out << "            \$('#${id}_month').val(date.getMonth() + 1);"
  out << "            \$('#${id}_year').val(date.getFullYear());"
  out << "            \$('#${id}_hour').val(date.getHours());"
  out << "            \$('#${id}_minute').val(date.getMinutes());"
  out << "       }"
  out << "    });"
  out << "});"
   if(regional != null){
   out << "\$('#${id}').focus(function(){"
   out << "    \$('#${id}').datepicker(\$.datepicker.setDefaults(\$.datepicker.regional['${regional}']));"
   out << "});"
  }
  out << ""



 }
...