Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    Filter ListGrid Locally (No DataSource Backing)

    Is it possible to filter a ListGrid locally when no data source is used?

    I have a ListGrid that is populated using SetData(ListGridRecord[] records). All of the records are placed and displayed. There isn't really a data source being used for this grid, and we set the data manually using the setData() method.

    I would like to filter using Criteria, but I haven't figured out how to get it to work yet.

    I read in an old post to try setting fetchMode to local, but I'm not sure how to do that or where - again, there is no data source being used...just ListGridRecord[] records being passed to setData().

    #2
    Use a clientOnly DataSource. It doesn't really require much more code, just move your field definitions from the grid to the DataSource.

    Comment


      #3
      I originally tried using a data source, but for some reason the data never showed up in the grid.

      Code:
      public class WeeklyReportLocalDS extends DataSource {
      	
      	public WeeklyReportLocalDS() {
      		
      		DataSourceIntegerField wr_id = new DataSourceIntegerField("wr_id", "Report ID");
      		addField(wr_id);
      		wr_id.setPrimaryKey(true);
      		
      		DataSourceTextField student_name = new DataSourceTextField("student_name", "Student Name");
      		addField(student_name);
      		
      		DataSourceDateField week_of = new DataSourceDateField("week_of","Week Of");
      		addField(week_of);
      		
      		setClientOnly(true);
      		
      		
      		
      	}
      }
      Then, passing the same ListGridRecord[] records array to datasource.setTestData(records) that I use with ListGrid.setData(records), nothing happens.

      The grid continues to state there are no items to view. When I use ListGrid.setData(records), the items show up.

      Here is the code where the grid is defined.

      Code:
      wr_grid = new ListGrid();
      		data_source = new WeeklyReportLocalDS();
      
      		data_source.setTestData(getWRGridRecords(weekly_reports));
      		wr_grid.setID("wr_grid");
      		wr_grid.setWidth(500);
      		wr_grid.setAlternateRecordStyles(true);
      		wr_grid.setAutoFitData(Autofit.BOTH);
      		wr_grid.setDataSource(data_source);
      		wr_grid.setAutoFetchData(true);
      		wr_grid.setCanEdit(false);
      		
      		wr_id_field = new ListGridField("wr_id", "Report ID");
      		wr_id_field.addRecordClickHandler(new RecordClickHandler() {
      
      			public void onRecordClick(RecordClickEvent event) {
      				WeeklyReportRecord record = (WeeklyReportRecord) event.getRecord();
      				int wr_id = record.getWRID();
      				new WeeklyReportEdit(wr_id);
      				
      			}
      			
      		});
      		student_name_field = new ListGridField("student_name", "Student Name");
      		student_name_field.setName("student_name");
      		week_of_field = new ListGridField("week_of", "Week Of");
      		wr_grid.setFields(wr_id_field, student_name_field, week_of_field);
      I'm not sure why the data doesn't show up in the grid. But if I comment out data_source.setTestData() and use wr_grid.setData(getWRGridRecords(weekly_reports)) then everything works ok - but it isn't using the data source.

      Comment


        #4
        Not sure why the data is showing, most likely incorrect ordering of setTestData() and fetchData(), but your approach is fine too. Even with setData(), the DataSource is still being used as a definition of the fields and how they are filtered.

        Comment


          #5
          Thanks for the response. I played around with it a little more and notice some really strange behavior when filtering.

          In the section of code that initializes the datasource / grid, I have

          Code:
          data_source.setTestData(getWRGridRecords(weekly_reports));
          wr_grid.setData(getWRGridRecords(weekly_reports));
          And when a filter button is clicked, I have

          Code:
          Criteria crit = new Criteria();
          crit.addCriteria("student_name", search_panel.getStudentField());
          wr_grid.fetchData(crit);
          Using this format, it works. The data initially shows all fields, and then when the filter button is hit it displays only the student who was selected in the form.

          Now comes the strange part.

          If we comment out data_source.setTestData(), it no longer works. Initially, all data is displayed, but when we hit the filter button, it then says 'No items to view' as if there were no results that matched the criteria (even when there are). So it filters and all data disappears from the grid.

          If we *uncomment* data_source.setTestData(), and *comment* wr_grid.setData(), then the data initially doesn't appear, and searching doesn't display results either. It's as if no data exists.

          I find this very strange. Both data_source.setTestData() and wr_grid.setData() have to be used for it to work. Filtering always displays zero results unless the data_source.setTestData() is called, but no data appears in the grid (initially or filtering) if wr_grid.setData() is not called.

          Any idea what would cause this? I thought that if we called wr_grid.setDataSource(data_source), used autofetch or fetched sometime after that call, then the data would appear in the grid. But it doesn't. Data is only applied to the grid using the setData() method, ignoring what is in the data_source, UNLESS we filter, in which case it retrieves the items from the data_source.setTestData() that match the given criteria.

          And if you look at the previous post, you will see where wr_grid is initialized with the data_source and autoFetchData(). Even if I assume autoFetchData() is not fetching, and I add wr_grid.fetchData() at the VERY end of the code, it still will not display data using only the data_source. wr_grid.setData() is still required.
          Last edited by superman859; 12 Mar 2009, 08:04.

          Comment


            #6
            After further playing around with Criteria, I am also unable to get it to search an array of dates. Ultimately, I want it to return all results between two dates.

            After looking at documentation for Criteria, it seems that it takes a single Date value, or an array of Date values where it can be any of the listed dates.

            So I tried

            Code:
            Date from_date = search_panel.getFromDate();
            Date to_date = search_panel.getToDate();
            Date cur_date = from_date;
            ArrayList<Date> crit_date = new ArrayList<Date>();
            while (cur_date.compareTo(to_date) <= 0) { // loop through all dates and add to crit_date array
            	crit_date.add(cur_date);
            	cur_date = CalendarUtils.addDays(cur_date, 1);
            }
            Date[] date_array = new Date[crit_date.size()];
            for (int i = 0; i < date_array.length; i++) { //copy ArrayList<Date> to Date[] object (got Javascript errors using (Date) crit_date.toArray())
            	date_array[i] = crit_date.get(i);
            }
            crit.addCriteria("week_of", date_array);
            where the "week_of" column holds dates. If I use crit.addCriteria("week_of", from_date), it returns all results that match from_date. However, when I try passing in an array of dates, (even as a simple as a two element array holding from_date, to_date), then it always returns zero results, even when there should be matches. I'm not sure why passing a single date element works, but passing an array always results in nothing being returned. I must have a misunderstanding of the Criteria field.

            Comment


              #7
              To specify a date range you'll need to use AdvancedCriteria. Direct creation of AdvancedCriteria is currently only possible via JSNI. Take a look at this post.

              Comment


                #8
                Thanks. I looked and tried it, but I may not be doing it correctly. I added this method:

                Code:
                public static native JavaScriptObject getDateRangeJSObject(String field, Date from, Date to) /*-{
                		var advancedCriteria = {
                			_constructor:"AdvancedCriteria",
                			operator:"and",
                			criteria:[
                			{ fieldName: field, operator:"greaterOrEqual", value: from },
                			{operator: "and", criteria:[
                				{ fieldName: field, operator:"lessOrEqual", value: to }
                				]
                			}
                			]
                		}
                		
                		return advancedCriteria;
                	}-*/;
                which takes the field name to search (from the list grid) and two date objects.

                I then use

                Code:
                AdvancedCriteria ac = new AdvancedCriteria(SearchWidget.getDateRangeJSObject("week_of", from_date, to_date));
                wr_grid.fetchData(ac);
                To create a new AdvancedCriteria. Am I doing it wrong? When I do the search, the grid shows 'No items to view' and the hosted mode shell displays some 'Malformed JSNI reference 'constructor' expect subsequent failures" notices (although I already had some to start with - more are created).

                Comment


                  #9
                  Hi superman,

                  That looks generally right, but the problem could be in the value of "field" or in the from/to values. Try hardcoding those directly as a first step just to verify that's not where the problem is.

                  Another good approach is to set up a FilterBuilder and use that interface to enter the criteria you want, apply those to the grid and see that you get the expected result, then use the Developer Console to call filterBuilder.getCriteria() and inspect the (working) criteria being put together by the FilterBuilder.

                  Comment


                    #10
                    Originally posted by Isomorphic
                    Hi superman,

                    That looks generally right, but the problem could be in the value of "field" or in the from/to values. Try hardcoding those directly as a first step just to verify that's not where the problem is.

                    Another good approach is to set up a FilterBuilder and use that interface to enter the criteria you want, apply those to the grid and see that you get the expected result, then use the Developer Console to call filterBuilder.getCriteria() and inspect the (working) criteria being put together by the FilterBuilder.
                    Thanks for the tip about using FilterBuilder. I added it to the page and was able to search the fields easily with it by dates. However, I'm not quite sure how to look at the contents of filterBuilder.getCriteria() to inspect them.

                    I tried using developer console and typed 'filterBuilder.getCriteria()' into the JS Eval section at the bottom of the first tab, but then I saw filterBuilder undefined in the top portion appear. If this is the correct way to see the contents, then I'm not sure why it was undefined. The variable filterBuilder was defined, and the program was running (and I had done a search using it successfully as well).

                    Is this the proper way to use the developers console to see the details? I haven't used the console too much, other than for layout purposes using the 'watch' tab to see what had been drawn and where, along with occassionally watching for errors appear in the first tab logging section. But I'm not sure about how to retrieve the values for a method like getCriteria().

                    Comment


                      #11
                      filterBuilder is probably a Java, not JavaScript, variable. The ID of the FilterBuilder is show in the Watch tab, and also in the middle section of the of the ResultSets tab if you click on the FilterBuilder. You can also use setID() in Java to give it a predictable global ID.

                      Comment


                        #12
                        Originally posted by Isomorphic
                        filterBuilder is probably a Java, not JavaScript, variable. The ID of the FilterBuilder is show in the Watch tab, and also in the middle section of the of the ResultSets tab if you click on the FilterBuilder. You can also use setID() in Java to give it a predictable global ID.
                        Thanks. I was able to get some of the information back from getCriteria(). However, for the criteria field, it simply says Array[1]. Is it possible to get it to list out the full criteria so I can analyze what is actually stored in the array?

                        Evaluator: result of 'filterBuilder.getCriteria();' (0ms):
                        {_constructor: "AdvancedCriteria",
                        operator: "and",
                        criteria: Array[1]}

                        I've managed to get it somewhat working, although it seems to be a day off. For example, if I have from date of 03/02/2009, I want it to include 03/02/2009 in the filtered set. However, it does not. You must search with a fromd ate of 03/01/2009 in order to get 03/02/2009 in the result set. Thus, it seems to be treating it as a greaterThan search, rather than greaterOrEqual. However, I have the code as

                        Code:
                        public static native JavaScriptObject getDateRangeJSObject(String field, Date from, Date to) /*-{
                        	
                        	var date1 = new Date();
                        	date1.setFullYear(from.@java.util.Date::getYear()() + 1900,from.@java.util.Date::getMonth()(),from.@java.util.Date::getDate()());
                        	var date2 = new Date();
                        	date2.setFullYear(to.@java.util.Date::getYear()() + 1900,to.@java.util.Date::getMonth()(),to.@java.util.Date::getDate()());
                        	
                        	
                        		var advancedCriteria = {
                        			_constructor:"AdvancedCriteria",
                        			operator:"and",
                        			criteria:[
                        				{ fieldName: field, operator:"greaterOrEqual", value: date1 },
                        			 	{ fieldName: field, operator:"lessOrEqual", value: date2 }
                        			]
                        		}
                        			
                        		
                        		
                        		return advancedCriteria;
                        	}-*/;
                        So it should be greaterOrEqual, or lessOrEqual. However, both of these do NOT include the specified date in the filtered set.
                        I have tested that date1 and date2 are indeed correct simply by stating alert(date1) or alert(date2). The result is the correct date.

                        EDIT: Found the problem. It seems to be related to the time the dates were created. I use the SmartGWT date picker to select the dates in the UI. This generates the date with minutes, hours, seconds, milliseconds etc all set to 0. When converting to a Javascript Date (because for some reason it wouldn't work using the dates as they stand without creating new ones for some reason), it was setting date1 correctly, although it had defaulted to the current hour / minutes / etc. Because of this, the values were never returned because the grid had dates all at 0 hour, minutes, milliseconds, etc. I fixed it by calling

                        date1.setHours(0):
                        date1.setMinutes(0);
                        date1.setSeconds(0);
                        date1.setMilliseconds(0);

                        which zeroed out everything.

                        The code would be a lot cleaner if the Date object arguments would work as they stand, but they will not for some reason. This is strange, because you can easily call date(from) and it displays the same thing as date(date1) after date1 has been initialized to the same values as from.
                        Last edited by superman859; 22 Mar 2009, 08:40.

                        Comment


                          #13
                          new Date() in JavaScript does give you a date that initially has the current timestamp, as in Java. However there are multiple constructors for JavaScript Date that take either String representations or numbers for year, month, day, and in this case the Date doesn't pick up the current timestamp.

                          Does that explain why your Java dates weren't working or is there still some kind of possible conversion issue?

                          Comment


                            #14
                            Im having a similiar problem.

                            I am generating a Tree from DataObjects and setting the Tree as Data for my TreeGrid.
                            Then I have a SelectionChangedListener for the TreeGrid that is creating ListGridRecords to show additional Details in a seperate ListGrid.


                            For the TreeGrid I can't filter the TreeField , on Enter it just closes all Nodes always.
                            Last edited by nils2k; 25 Mar 2009, 07:25.

                            Comment

                            Working...
                            X