Announcement

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

    ListGrid.fetchData and DSCallback

    Hi,

    I'm trying to pass a DSCallback to ListGrid.fetchData(Criteria criteria, DSCallback dsCallBack) because I need to run some custom code based on the server response (specifically, the data I'm passing as search criteria can fail special server-side validation logic and I need to flag errors in the search form accordingly).

    Anyway, long story short: the validation is working, and so is the actual fetch and the DSCallback(). But the problem is that I don't know how to communicate to the ListGrid the total size of the result set on the server side (the ListGrid is using paging). My server side data object is correctly returning the data the listGrid needs (i.e. startRow, endRow, totalRows, etc) and it works fine when I don't pass the DSCallback to the fetchData() method. However, the code for my DSCallback is as follows:

    Code:
    private class DIDSearchCallback implements DSCallback
    	{
    
    		@Override
    		public void execute(DSResponse response, Object rawData,
    				DSRequest request) 
    		{
    			
    			if(response.getStatus() == DSResponse.STATUS_VALIDATION_ERROR)
    			{
    				if(response.getErrors().size()!=0)
    				{
    					vm.setErrors(response.getErrors(), true);
    				}
    			}
    			else
    			{
    				
    				results.setData(response.getDataAsRecordList());
    			}
    			
    		}
    		
    	}
    If the resultset on the serverside is greater than 75, I end up having problems. Let's say for instance there are 400 results. The ListGrid asks for result 0-75. My server-side DAO correctly retrieves result 0-75 and sets totaRows to 400. However, because in the callback I'm simply passing the data as a recordList, the ListGrid just sees a list with 75 items and renders that - it doesn't try to page any further (because it doesn't know there are actually 400 total results).

    So I'm not sure what to put in the DSCallback to tell the ListGrid what the real resultset size is. I've tried playing around with com.smartgwt.client.data.ResultSet, specifically changing the DSCallback to:

    Code:
    private class DIDSearchCallback implements DSCallback
    	{
    
    		@Override
    		public void execute(DSResponse response, Object rawData,
    				DSRequest request) 
    		{
    			
    			if(response.getStatus() == DSResponse.STATUS_VALIDATION_ERROR)
    			{
    				if(response.getErrors().size()!=0)
    				{
    					vm.setErrors(response.getErrors(), true);
    				}
    			}
    			else
    			{
    				ResultSet resultSetProperties = new ResultSet();
    				resultSetProperties.setLength(response.getTotalRows());
    				
    				results.setDataProperties(resultSetProperties);
    				results.setData(response.getDataAsRecordList());
    			}
    			
    		}
    		
    	}
    On the one hand, this works because the ListGrid now correctly realizes that there are 400 total results and starts paging. But on the other hand, it appears some really crucial information is now missing from the ResulSet object and the ListGrid starts throwing some really nasty javascript errors in the process.

    Anyway, that's probably not the right approach, but I'm not sure what is.

    Thanks.
    Last edited by SiccoNaets; 14 Jul 2010, 21:00.

    #2
    Also, ideally, I'd rather not do the callback at all. However, there doesn't seem to be any other way to do a fetch() and retrieve the errorReport from the server to correctly show validation errors on the form; so...
    Last edited by SiccoNaets; 14 Jul 2010, 20:59.

    Comment


      #3
      You don't need to do any of this. Look at the documentation for fetchData(), a ResultSet is set up automatically. What sent you down this path, validation errors? Why is fetch returning validation errors?

      Comment


        #4
        Users can perform a variety of searches against the underlying data. One field allows them to enter phone-numbers as free-text, and in fact, they can enter phone numbers in a variety of different formats - 555-123-4567, 5551234567, +1(555)123-4567 are all valid formats for the same number, for instance.

        We have a piece of (existing) code on the server which can parse the free-text field and derive real phone-numbers from that data. However, not every possible string is of course a phone number. "Blahblah" isn't a phone-number and neither is just "123". In that case, the server code throws a parse exception. I'm handling the exception, but if that happens, I want to be able to display a validation error next to the free-entry field that indicates one of the numbers they provided isn't really a valid number.

        The DSCallback() allows me to do exactly that but, like I said, what's giving me some trouble is providing the listGrid with the meta-data about the resultSet which would allow paging to work properly.

        Comment


          #5
          The ListGrid is not expecting validation errors because it wouldn't know what to do with them - you actually want them shown in a related form that the grid doesn't know about. So, take this approach instead:

          1. call DataSource.fetchData() with criteria derived from the form

          2. in the callback from this method, handle validation errors via your ValuesManager as you are now

          3. if there were no errors, take the data supplied in the DSCallback and form a ResultSet with that data and the criteria and totalRows values, then supply this to the grid via setData().

          Comment


            #6
            Thanks Isomorphic.

            Ok, I tried changing the DSCallback to:

            Code:
            private class DIDSearchCallback implements DSCallback
            	{
            		protected Criteria criteria;
            		
            		public DIDSearchCallback(Criteria criteria)
            		{
            			this.criteria= criteria;
            		}
            
            		@Override
            		public void execute(DSResponse response, Object rawData,
            				DSRequest request) 
            		{
            			
            			if(response.getStatus() == DSResponse.STATUS_VALIDATION_ERROR)
            			{
            				if(response.getErrors().size()!=0)
            				{
            					vm.setErrors(response.getErrors(), true);
            				}
            			}
            			else
            			{
            				ResultSet resultSet = new ResultSet();
            				resultSet.setInitialData(response.getData());
            				resultSet.setInitialLength(response.getData().length);
            				resultSet.setCriteria(criteria);
            				resultSet.setLength(response.getTotalRows());
            				
            				results.setData(resultSet);
            			}
            			
            		}
            		
            	}
            I assume I also need to remove the dataSource from the ListGrid, since I'm invoking the dataSource directly, correct?

            Finally, I invoke the fetch like this:

            Code:
            Criteria criteria= new Criteria();
            this.didDS.fetchData(criteria, new DIDSearchCallback(criteria));
            However, this causes the dataSource to try and return all results from the server (which makes sense, because without a properly formatted dsRequest telling the server to limit the resultset, that's what it's designed to do).

            So, i think instead, I need:

            Code:
            Criteria criteria= new Criteria();
            DSRequest dsRequest = new DSRequest();
            dsRequest.setStartRow(?);
            dsRequest.setEndRow(?);
            this.didDS.fetchData(criteria, new DIDSearchCallback(criteria), dsRequest);
            and somehow figure out the current start and endrow from the ListGrid so that it properly pages, but I'm not sure how to obtain that...

            Comment


              #7
              dsRequest.setStartRow(), dsRequest.setEndRow() give you paging via fetchData()'s requestProperties argument. Use whatever page size you want, it's settable.

              Do not remove the DataSource from the ListGrid.

              Comment

              Working...
              X