views:

101

answers:

2

On index.gsp I have this to redirect it to list.gsp so I'm imagining is should be something like this:

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

My filter is just one textField and two datePickers with drop down boxes (DD-MMM-YYYY) and they should be by default filtered from today's date to infinity. So it should show me only the events that have not happened yet, but the old ones should still be in the database.

Here are the links to my last 3 questions for background information

http://stackoverflow.com/questions/3096572/i-have-a-bunch-of-data-and-i-need-a-data-filter-using-grails

http://stackoverflow.com/questions/3105021/grails-filter-data-in-a-grails-table-dynamically

http://stackoverflow.com/questions/3119559/grails-edit-and-delete-links-not-working

I think the second one is the one with most of my code.

Any help would be greatly appreciated and well rated. Thanks! :) And a again special thanks to proflux for all the help!

UPDATE

Here is the in the 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>

UPDATE

Here is the searchResults code,

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]) 
}

And since I am already using results and is a list, what should I do, give it another name and at the end put it to model after results?? like:

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

Or should I just define it inside results??

UPDATE

<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>

For some reason when I apply the filters then it shows me everything on the list (it does not filter) and the textFields in the filter do not save the date from when the filter was applied.

Any ideas on how I can fix this?

A: 

Hi Fernando,

Instead of doing the redirect on the GSP, it would probably be better to update your index controller method to do something like:

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

This way your controller logic is all in the controller and not in both the GSP and controller.

Your second requirement is a little trickier, but not too bad. Basically, you need up update your criteria logic. I'll assume that you only care about two cases:

  1. you have both fechaCambioD and fechaCambioH
  2. you have fechaCambioD and no fechaCambioH (your default - from today until the end of time)

And you don't care about finding all the entries from the beginning of time up until fechaCambioH

If that's the case, change your controller logic to:

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}%")
        }            
    }

So we essentially:

  1. If you didn't get a fechaCambioD parameter, we're going to default fechaCambioD to the current time.
  2. If we don't have both fechaCambioD and fechaCambioH we're going to find all entries that have a fechaCambio greater than the current time.

I believe that should work, but if not let me know...

UPDATE:

Okay, my mistake, there is no gte comaparator, it's just ge for greater than or equal and gt for greater than. Since your search criteria is simpler for list, you can probably just change the method to:

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])
}

If this doesn't work let me know...

proflux
I had def index = { redirect(action: "list", params: params) }in the controller, but that did not work. But is fine the only line I have in index.gsp is that one
fgualda87
It seems like I do need that line in the gsp file
fgualda87
One more thing, those changes will show when searchResults is called.I need this to be done when list is called, so shouldn't it be under def list?
fgualda87
I tried it in searchResults and I got this error message: Executing action [searchResults] of controller [eval.EntryController] caused exception: call to [get] not supported here
fgualda87
did you mistype gte("fechaCambio"..." as get("fechaCambio"... ?
proflux
yes, you'll need your logic in the list controller method if you want it to execute from there. I would recommend factoring this logic out into a service method though and using the same logic from both your list and search methods, but the quick an dirty solution is to copy the criteria into def list.
proflux
yes, that would be the quick and dirty way, lol, but still it doesn't work, and yes i noticed it was get not gte.
fgualda87
but still i don't how to make it work :/ like even if it puts in the value I shouldn't click the filter button, it should do it automatically when the page loads...
fgualda87
you shouldn't have to click the filter button. There is probably a mismatch between the <g:each> tag on your list.gsp and the variable you're sending to that page on the controller... Can you post your current list controller method and the <g:each...> tag in your list.gsp that is building the html table? Probably it is looking for a variable called entryInstanceList and your controller is passing in a variable called searchResults or something similar...
proflux
Ok sorry, I was having lunch and it took forever. I will post it in a second.
fgualda87
Ok done. It's giving me an error though, saying I cannot use get there with the first piece of code... It says is not supported.
fgualda87
see updated answer... let me know if it doesn't work. You may encounter some issues with what we've done up to this point if you're using the paginate buttons.
proflux
YES! Is working!! The only thing is that it should be today's date -1 or 00:00 because I think is filtering seconds and everything I put with today's date doesn't show, unless I use the filter.
fgualda87
should I change it to new Date() - 1?Because new Date() creates the time with seconds... maybe give format to that new Date()?
fgualda87
If you use new Date() -1 it will give you 24 hours before right now. If you want from midnight of today, then use the updated code posted above. Let me know if that works...
proflux
No, is not working, for some weird reason though. Don't we need to initialize it as a new Date() somewhere? So it gets today's date.
fgualda87
Calendar.getInstance() is the Calendar equivalent of new Date(). today.getTime() returns the Date representation of the Calendar object. We're getting a Calendar set to the current time, then setting the hour, minute, second, ms to zero, then using its date representation. Can you describe what it's doing now?
proflux
If I create an event with today's date and then go to the list, it doesn't show it. If I create the event with tomorrow's date then it does show it.
fgualda87
what about after defining today, write today.setTime(new Date()) in the next line?
fgualda87
I tried that and nothing happened, same as before, no change at all.
fgualda87
change today.set(Calendar.HOUR,0) to today.set(Calendar.HOUR_OF_DAY, 0)
proflux
PERFECT! Thank you so much!!
fgualda87
I found an error, the opposite thing is happening with lastUpdatedH, is not counting today. If I apply the filter for lastUpdated, I'm assuming I need to do the same thing but HOUR_OF_DAY, 24?
fgualda87
HOUR_OF_DAY=23, MINUTE=59, SECOND=59, MILLISECOND=999 should do it, or roll the day forward by one then set all fields to zero. Depends on if you want the last moment of fechaCambioH or the first moment of fechaCambioH+1, but they are pretty much equivalent.
proflux
Where should I put it though, since I already have def results defined.I will update post with def searchReasults code.
fgualda87
I tried putting everywhere in the code, I did the HOUR_OF_DAY=23 because it makes more sense, but it didn't work.
fgualda87
for the fechaCambioH calendar, try creating it with today=Calendar.getInstance() then call today.setTime(fechaCambioH) before you start setting HOUR_OF_DAY, etc..
proflux
but do I write it inside the def results list ??
fgualda87
and I imagine I have to change Entry.findAllByFechaCambioGREATERThanEquals(today.getTime()) for LESSok so I wrote def otherResults = Entry.findAllByFechaCambioLessThanEquals(today.getTime()) how do I render it?? I put 'results':otherResults next to the other results: resultS??
fgualda87
I got an error saying: Error 500: Executing action [searchResults] of controller [eval.EntryController] caused exception: No such property: lastUpdatedH for class: eval.EntryController
fgualda87
fgualda87
Well, if you're doing it in the criteria we can't use the dynamic LessThanEquals finder, but you're right about changing the greater than to less than.
proflux
If I can't use LessThanEquals then what can I use?
fgualda87
how do I render it?
fgualda87
Will post an update a little later, basically a combination of the between criteria as posted above and the calender logic on fechaCambioH.
proflux
Ok, thanks, I'll let you know as soon as I apply the changes.
fgualda87
for some reason i can't vote on the answer :S it says you need to edit it :S
fgualda87
@proflux - I have a question regarding this same thing, is there any way I can contact you? Like nay kind of instant messaging?
fgualda87
I'm not on any IM services, but you can post a question here and if I get a chance I'll take a look at it.
proflux
+1  A: 

For the fechaCambio in the criteria, what you can do is something like this:

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]) 
}

Again, this is the quick and dirty approach; not very elegant but if I understand your problem it should do what you want.

proflux
Is throwing me an error. Don't you need like def fromCal = something first?
fgualda87
is not compiling
fgualda87
oops, I forgot a { nvm
fgualda87
I got this error: Error 500: Executing action [searchResults] of controller [eval.EntryController] caused exception: groovy.lang.MissingMethodException: No signature of method: eval.EntryController.getTime() is applicable for argument types: () values: [] Possible solutions: getTmpl(), getList(), getSave(), getTmpl(java.lang.Object), getG(), getFilter()
fgualda87
Ok, I got it, it worked!!! Thank you very much!!
fgualda87
no problem, glad you got it working.
proflux
Thank you very much! Thanks for all your help!
fgualda87
Hey proflux, I have a question, what if for the filter I want to make the datePicker a textField? I would need to separate it in different textFields, right? like one for day one for month and one for year? thnks
fgualda87
Either separate fields or one field that you parse up and validate yourself; then you also have to handle binding the text fields to your date which can be a little tricky if you haven't done it before. You may want to take a look at some of the rich UI widgets that are available. For instance, the JQuery-UI and Grails-UI both have a nice date picker calendar widget. http://grails.org/plugin/grails-ui , http://www.grails.org/plugin/jquery-ui
proflux
grails-ui looks neat and straight to the point, i'll check it out. thank you!
fgualda87
Ok, I got it to show me the calendar and everything, but again the filter is not working :(
fgualda87
For some reason the filter is not filtering, is showing me everything on the list no matter what the date on the filter are. I will post my code, can you help me?
fgualda87
When I get a chance I'll take a look, but won't have much time to look into it until later on today.
proflux
No problem. Thanks! ;)
fgualda87
do you know where i can find the properties of gui:datePicker?
fgualda87
I think there's usually passthrough properties that correspond to the ones for the YUI component. Look at the YUI library documentation and I think you can usually just set the same parameters on the gui component.
proflux
how do I make the filters read the datePickers from Grails UI? I thought I was doing it right but it does not work
fgualda87
Not 100% sure, I only had a minute to look but try setting the id attribute on gui:datePicker as well as the name: <gui:datePicker id="fechaCambioH" name="fechaCambioH" .../>
proflux
posted a new question since this one has evolved.http://stackoverflow.com/questions/3204688/grails-how-to-make-filter-recognize-values-from-datepicker-using-grails-ui
fgualda87
I got this error: Executing action [searchResults] of controller [eval.EntryController] caused exception: java.lang.String cannot be cast to java.util.Date
fgualda87
I think that has to do with the format of the gui:datePicker
fgualda87
No is not working :S
fgualda87