Grails: как заставить мою страницу загружать фильтр при загрузке страницы?

На index.gsp у меня есть это, чтобы перенаправить его на list.gsp, поэтому я представляю, что это должно быть примерно так:

${response.sendRedirect("entry/list")}

Мой фильтр состоит только из одного textField и двух datePickers с раскрывающимися списками (DD-MMM-YYYY), и они должны быть по умолчанию отфильтрованы от сегодняшней даты до бесконечности. Так что он должен показывать мне только те события, которые еще не произошли, а старые все еще должны быть в базе данных.

Вот ссылки на мои последние 3 вопроса для получения справочной информации.

У меня есть куча данных, и мне нужен фильтр данных с помощью Grails

Grails: динамически фильтровать данные в таблице Grails

Grails: не работают ссылки для редактирования и удаления

Я думаю, что второй - это тот, у которого большая часть моего кода.

Любая помощь будет принята с благодарностью и хорошо оценена. Спасибо! :) И еще раз отдельное спасибо proflux за помощь!

ОБНОВЛЕНИЕ

Вот в list.gsp

<g:each in="${entryInstanceList}" status="i" var="entryInstance">
                    <tr class="${(i % 2) == 0 ? 'odd' : 'even'}">
                        <td><g:formatDate format="dd-MMMM-yyyy" date="${entryInstance.fechaCambio}" /></td>
                        <td><b>${fieldValue(bean: entryInstance, field: 'proyectoRuta')}</b></td>
                        <td>${fieldValue(bean: entryInstance, field: 'summary')}</td>
                        <td><g:formatDate format="dd-MMM-yyyy HH:mm z" date="${entryInstance.lastUpdated}" /></td>
                        <td>
                        <g:form>
                            <g:hiddenField name="id" value="${entryInstance?.id}" />
                            <span class="simple"><g:actionSubmit class="editar" action="edit" value="${message(code: 'default.button.editar.label', default: '&nbsp;&nbsp;&nbsp;')}" /></span>
                            <span class="simple"><g:actionSubmit class="eliminar" action="delete" value="${message(code: 'default.button.eliminar.label', default: '&nbsp;&nbsp;&nbsp;')}" onclick="return confirm('${message(code: 'default.button.delete.confirm.message', default: 'Esta seguro que desea Eliminar?')}');" /></span>
                        </g:form>
                        </td>
                    </tr>
</g:each>

ОБНОВЛЕНИЕ

Вот код searchResults,

def searchResults = { 
    def entryCriteria = Entry.createCriteria()

    def results = entryCriteria.list {
        and{if(params?.fechaCambioD && params?.fechaCambioH) { 
            between("fechaCambio", params.fechaCambioD, params.fechaCambioH) 
            } 

        if(params?.lastUpdatedD && params?.lastUpdatedH) { 
            between("lastUpdated", params.lastUpdatedD, params.lastUpdatedH) 
            }

        if(params?.proyectoRutaN) { 
            ilike("proyectoRuta","%${params.proyectoRutaN}%")
            }            
        }
        }
        render(view:'searchResults', model:['results':results, 'proyectoRutaN':params?.proyectoRutaN, 'fechaCambioD':params?.fechaCambioD, 'fechaCambioH':params?.fechaCambioH, 'lastUpdatedD':'', 'lastUpdatedH':params?.lastUpdatedH]) 
}

И так как я уже использую результаты и это список, что мне делать, дать ему другое имя и в конце положить его в модель после результатов?? как:

render(view:'searchResults', model:['results':results, 'otherResults':otherResults, 'proyectoRutaN':params?.proyectoRutaN, 'fechaCambioD':params?.fechaCambioD, 'fechaCambioH':params?.fechaCambioH, 'lastUpdatedD':'', 'lastUpdatedH':params?.lastUpdatedH])

Или я должен просто определить это внутри результатов??

ОБНОВЛЕНИЕ

<table><tbody class="yui-skin-sam">
<tr class="prop">
    <td valign="top" class="name"><b>Proyecto/Ruta: </b> &nbsp;&nbsp;&nbsp;<g:textField name="proyectoRutaN" value="${proyectoRutaN}" /></td>
    <td></td>
    <td valign="top" class="name"><b>Fecha de Implementación: </b></td>
    <td></td>
    <td valign="top" class="name"><b>Fecha de Última Modificación: </b></td>
</tr>
<tr class="prop">
    <td></td>
    <td valign="top">Desde:</td>
    <td valign="top"><gui:datePicker name="fechaCambioD" value="${params?.fechaCambioD}"  formatString="dd/MMM/yyyy"/></td>
    <td valign="top">Desde:</td>
    <td valign="top"><gui:datePicker name="lastUpdatedD" value="${params?.lastUpdatedD}" default="none"/></td>
</tr>
<tr class="prop">
    <td></td>
    <td valign="top">Hasta:</td>
    <td valign="top"><gui:datePicker name="fechaCambioH" value="${params?.fechaCambioH}"  formatString="dd/MMM/yyyy"/></td>
    <td valign="top">Hasta:</td>
    <td valign="top"><gui:datePicker name="lastUpdatedH" value="${params?.lastUpdatedH}" default="none"/></td>
</tr>

По какой-то причине, когда я применяю фильтры, он показывает мне все в списке (он не фильтрует), а текстовые поля в фильтре не сохраняют дату применения фильтра.

Любые идеи о том, как я могу это исправить?


person randomizertech    schedule 30.06.2010    source источник


Ответы (2)


Вместо того, чтобы выполнять перенаправление в GSP, вероятно, было бы лучше обновить метод контроллера индекса, чтобы он делал что-то вроде:

def index {
  redirect(action:'list')
}

Таким образом, вся логика вашего контроллера находится в контроллере, а не как в GSP, так и в контроллере.

Ваше второе требование немного сложнее, но не так уж плохо. По сути, вам нужно обновить логику критериев. Я предполагаю, что вас интересуют только два случая:

  1. у вас есть и fechaCambioD, и fechaCambioH
  2. у вас есть fechaCambioD и нет fechaCambioH (по умолчанию - с сегодняшнего дня и до конца времен)

И вам не нужно искать все записи с начала времен до fechaCambioH.

Если это так, измените логику вашего контроллера на:

def fechaCambioD = params?.fechaCambioD ?: new Date()

def results = entryCriteria.list {
    if(params?.fechaCambioD && params?.fechaCambioH) { 
        between("fechaCambio", params.fechaCambioD, params.fechaCambioH) 
    } 
    else {
      gte("fechaCambio", fechaComabioD)
    }

    if(params?.lastUpdatedD && params?.lastUpdatedH) { 
        between("lastUpdated", params.lastUpdatedD, params.lastUpdatedH) 
        }

    if(params?.proyectoRutaN) { 
        ilike("proyectoRuta","%${params.proyectoRutaN}%")
        }            
    }

Итак, мы по существу:

  1. Если вы не получили параметр fechaCambioD, мы установим fechaCambioD по умолчанию на текущее время.
  2. Если у нас нет ни fechaCambioD, ни fechaCambioH, мы найдем все записи, у которых fechaCambio больше текущего времени.

Я считаю, что это должно сработать, но если нет, дайте мне знать...

ОБНОВЛЕНИЕ:

Хорошо, моя ошибка, компаратора gte нет, просто ge означает больше или равно и gt больше. Поскольку ваши критерии поиска проще для списка, вы, вероятно, можете просто изменить метод на:

def list = {
   def today = Calendar.getInstance()
   today.set(Calendar.HOUR, 0)
   today.set(Calendar.MINUTE, 0)
   today.set(Calendar.SECOND, 0)
   today.set(Calendar.MILLISECOND, 0)
   def results = Entry.findAllByFechaCambioGreaterThanEquals(today.getTime()) 
   render(view:'list', model:['entryInstanceList':results])
}

Если это не сработает, дайте мне знать...

person proflux    schedule 30.06.2010
comment
У меня было def index = {redirect(action: list, params: params)} в контроллере, но это не сработало. Но в порядке, единственная строка, которая у меня есть в index.gsp, - это та - person randomizertech; 30.06.2010
comment
Кажется, мне нужна эта строка в файле gsp - person randomizertech; 30.06.2010
comment
Еще одна вещь, эти изменения будут отображаться при вызове searchResults. Мне нужно, чтобы это было сделано при вызове списка, так что не должно ли это быть в списке определения? - person randomizertech; 30.06.2010
comment
Я попробовал это в searchResults и получил это сообщение об ошибке: Выполнение действия [searchResults] контроллера [eval.EntryController] вызвало исключение: вызов [get] здесь не поддерживается - person randomizertech; 30.06.2010
comment
вы опечатались gte(fechaCambio... как get(fechaCambio... ? - person proflux; 30.06.2010
comment
да, вам понадобится ваша логика в методе контроллера списка, если вы хотите, чтобы он выполнялся оттуда. Я бы порекомендовал выделить эту логику в сервисный метод и использовать ту же логику как из вашего списка, так и из методов поиска, но быстрое и грязное решение - скопировать критерии в список определения. - person proflux; 30.06.2010
comment
да, это был бы быстрый и грязный способ, лол, но все же он не работает, и да, я заметил, что это было не gte. - person randomizertech; 30.06.2010
comment
но все же я не знаю, как заставить его работать: / например, даже если он вводит значение, я не должен нажимать кнопку фильтра, он должен делать это автоматически при загрузке страницы... - person randomizertech; 30.06.2010
comment
вам не нужно нажимать кнопку фильтра. Вероятно, существует несоответствие между тегом ‹g:each› в вашем list.gsp и переменной, которую вы отправляете на эту страницу в контроллере... Можете ли вы опубликовать свой текущий метод контроллера списка и ‹g:each.. .› тег в вашем list.gsp, который строит html-таблицу? Вероятно, он ищет переменную с именем entryInstanceList, а ваш контроллер передает переменную с именем searchResults или что-то подобное... - person proflux; 30.06.2010
comment
Готово. Однако это дает мне ошибку, говоря, что я не могу использовать добраться туда с первым фрагментом кода... Он говорит, что не поддерживается. - person randomizertech; 01.07.2010
comment
см. обновленный ответ ... дайте мне знать, если это не сработает. Вы можете столкнуться с некоторыми проблемами с тем, что мы сделали до этого момента, если вы используете кнопки разбиения на страницы. - person proflux; 01.07.2010
comment
ДА! Работает!! Единственное, это должна быть сегодняшняя дата -1 или 00:00, потому что я думаю, что это фильтрация секунд, и все, что я поставил с сегодняшней датой, не отображается, если я не использую фильтр. - person randomizertech; 01.07.2010
comment
я должен изменить его на новую дату () - 1? Поскольку новая дата () создает время с секундами... может быть, придать формат этой новой дате ()? - person randomizertech; 01.07.2010
comment
Если вы используете new Date() -1, это даст вам 24 часа до этого момента. Если вы хотите с полуночи сегодняшнего дня, то используйте обновленный код, размещенный выше. Дай мне знать, если это работает... - person proflux; 01.07.2010
comment
Нет, не работает, по какой-то странной причине. Разве нам не нужно где-то инициализировать его как новый Date()? Таким образом, он получает сегодняшнюю дату. - person randomizertech; 01.07.2010
comment
Calendar.getInstance() — это Календарь, эквивалентный new Date(). today.getTime() возвращает представление даты объекта календаря. Мы получаем Календарь, установленный на текущее время, затем устанавливаем часы, минуты, секунды, мс на ноль, а затем используем его представление даты. Можете ли вы описать, что он делает сейчас? - person proflux; 01.07.2010
comment
Если я создаю событие с сегодняшней датой, а затем перехожу к списку, оно не отображается. Если я создам событие с завтрашней датой, оно его покажет. - person randomizertech; 01.07.2010
comment
как насчет того, чтобы после определения сегодняшнего дня написать today.setTime(new Date()) в следующей строке? - person randomizertech; 01.07.2010
comment
Я попробовал это, и ничего не произошло, как и раньше, никаких изменений. - person randomizertech; 01.07.2010
comment
измените today.set(Calendar.HOUR,0) на today.set(Calendar.HOUR_OF_DAY, 0) - person proflux; 01.07.2010
comment
Нашел ошибку, с lastUpdatedH происходит обратное, сегодня не в счет. Если я применяю фильтр для lastUpdated, я предполагаю, что мне нужно сделать то же самое, но HOUR_OF_DAY, 24? - person randomizertech; 01.07.2010
comment
HOUR_OF_DAY=23, MINUTE=59, SECOND=59, MILLISECOND=999 должны сделать это, или переместить день вперед на один, а затем установить все поля в ноль. Зависит от того, хотите ли вы последний момент fechaCambioH или первый момент fechaCambioH+1, но они в значительной степени эквивалентны. - person proflux; 01.07.2010
comment
Но куда мне его поместить, поскольку у меня уже есть определенные результаты определения. Я обновлю сообщение с кодом def searchReasults. - person randomizertech; 01.07.2010
comment
Я пытался вставить все в код, я сделал HOUR_OF_DAY=23, потому что это имеет больше смысла, но это не сработало. - person randomizertech; 01.07.2010
comment
для календаря fechaCambioH попробуйте создать его с помощью today=Calendar.getInstance(), затем вызовите today.setTime(fechaCambioH), прежде чем вы начнете устанавливать HOUR_OF_DAY и т. д.. - person proflux; 01.07.2010
comment
но я пишу это в списке результатов определения ?? - person randomizertech; 01.07.2010
comment
и я предполагаю, что мне нужно изменить Entry.findAllByFechaCambioGREATERThanEquals(today.getTime()) на LESS, хорошо, поэтому я написал def otherResults = Entry.findAllByFechaCambioLessThanEquals(today.getTime()), как мне это отобразить?? Я помещаю «результаты»: другие результаты рядом с другими результатами: результаты?? - person randomizertech; 01.07.2010
comment
Я получил сообщение об ошибке: Ошибка 500: выполнение действия [searchResults] контроллера [eval.EntryController] вызвало исключение: нет такого свойства: lastUpdatedH для класса: eval.EntryController - person randomizertech; 01.07.2010
comment
Ну, если вы делаете это в критериях, мы не можем использовать динамический поиск LessThanEquals, но вы правы, меняя больше на меньше. - person proflux; 01.07.2010
comment
Если я не могу использовать LessThanEquals, то что я могу использовать? - person randomizertech; 01.07.2010
comment
Чуть позже опубликую обновление, в основном сочетание промежуточных критериев, как указано выше, и логики календаря на fechaCambioH. - person proflux; 01.07.2010

Для fechaCambio в критериях вы можете сделать что-то вроде этого:

def searchResults = { 
    def fromCal
    if(params?.fechaCambioD) {
      fromCal = Calendar.getInstance()
      fromCal.setTime(param?.fechaCambioD)
      fromCal.set(Calendar.HOUR_OF_DAY,0)
      fromCal.set(Calendar.MINUTE,0)
      fromCal.set(Calendar.SECOND,0)
      fromCal.set(Calendar.MILLISECOND,0)
    }
    def toCal
    if(params?.fechaCambioH) {

      toCal = Calendar.getInstance()
      toCal.setTime(param?.fechaCambioH)
      toCal.set(Calendar.HOUR_OF_DAY,23)
      toCal.set(Calendar.MINUTE,59)
      toCal.set(Calendar.SECOND,59)
      toCal.set(Calendar.MILLISECOND,999)
    }
    def entryCriteria = Entry.createCriteria()

    def results = entryCriteria.list {
        and{if(params?.fechaCambioD && params?.fechaCambioH) { 
            between("fechaCambio", fromCal.getTime(), toCal.getTime()) 
            } 

        if(params?.lastUpdatedD && params?.lastUpdatedH) { 
            between("lastUpdated", params.lastUpdatedD, params.lastUpdatedH) 
            }

        if(params?.proyectoRutaN) { 
            ilike("proyectoRuta","%${params.proyectoRutaN}%")
            }            
        }
        }
        render(view:'searchResults', model:['results':results, 'proyectoRutaN':params?.proyectoRutaN, 'fechaCambioD':params?.fechaCambioD, 'fechaCambioH':params?.fechaCambioH, 'lastUpdatedD':'', 'lastUpdatedH':params?.lastUpdatedH]) 
}

Опять же, это быстрый и грязный подход; не очень элегантный, но если я понимаю вашу проблему, он должен делать то, что вы хотите.

person proflux    schedule 01.07.2010
comment
Привет, профлюкс, у меня вопрос, а что если для фильтра я хочу сделать datePicker текстовым полем? Мне нужно было бы разделить его на разные текстовые поля, верно? например, один для дня, один для месяца и один для года? спасибо - person randomizertech; 07.07.2010
comment
Либо отдельные поля, либо одно поле, которое вы анализируете и проверяете самостоятельно; тогда вам также придется обрабатывать привязку текстовых полей к вашей дате, что может быть немного сложно, если вы этого не сделали раньше. Возможно, вы захотите взглянуть на некоторые из доступных виджетов богатого пользовательского интерфейса. Например, JQuery-UI и Grails-UI имеют хороший виджет календаря выбора даты. grails.org/plugin/grails-ui , grails.org/plugin/jquery-ui - person proflux; 07.07.2010
comment
grails-ui выглядит аккуратно и прямолинейно, я проверю. Спасибо! - person randomizertech; 07.07.2010
comment
Хорошо, я получил это, чтобы показать мне календарь и все, но фильтр снова не работает :( - person randomizertech; 07.07.2010
comment
По какой-то причине фильтр не фильтрует, показывает мне все в списке, независимо от того, какая дата в фильтре. Я опубликую свой код, вы можете мне помочь? - person randomizertech; 07.07.2010
comment
Когда у меня будет возможность, я посмотрю, но у меня будет не так много времени, чтобы изучить это до более позднего дня. - person proflux; 07.07.2010
comment
Вы знаете, где я могу найти свойства gui:datePicker? - person randomizertech; 08.07.2010
comment
Я думаю, что обычно есть сквозные свойства, соответствующие свойствам компонента YUI. Посмотрите на документацию библиотеки YUI, и я думаю, что обычно вы можете просто установить те же параметры для компонента графического интерфейса. - person proflux; 08.07.2010
comment
как заставить фильтры читать datePickers из пользовательского интерфейса Grails? Я думал, что делаю это правильно, но это не работает - person randomizertech; 08.07.2010
comment
Не уверен на 100%, у меня была всего минута, чтобы посмотреть, но попробуйте установить атрибут id в gui:datePicker, а также имя: ‹gui:datePicker id=fechaCambioH name=fechaCambioH .../› - person proflux; 08.07.2010