Announcement

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

    ColumnTree with multiple datasources?

    My data consists of employers that have employees that have paychecks. I would like to represent this tree data in a ColumnTree, ideally along with a DynamicForm that allows me to edit the selected item in the ColumnTree, similar to the "Pattern Reuse" example in the Showcase.

    The employers, employees, and paychecks have different fields, so it seems I can't lump them into one datasource (or can I?). I would like to use RestDataSources to fetch, update, add, and delete the items via XML webservice.

    I looked at the "Miller Columns" example in the Showcase, but the datasource has items all of the same type.

    Is there a way to get the results I am looking for?

    #2
    Look into DataSourceField.setForeignKey that allows one datasource to have a foreign key relationship to another DataSource. The ItemSupplyLocalDS class in showcase uses this feature.

    Sanjiv

    Comment


      #3
      So, if call
      Code:
      setID("employerDS")
      in my EmployerDS class, I then should call
      Code:
      setForeignKey("employerDS.EmployerID")
      from my EmployeeDS class, assuming that EmployerID is the field name of the Employer pk. Am I correct so far?

      This leaves me with three data sources: EmployerDS, EmployeeDS, and PaycheckDS.

      My question now is how do I assign the datasources to the ColumnTree so that when an employer is selected in the 1st column, the employees for that employer show in the 2nd column? And then when one of those employees is selected, the paychecks for that employee show in the 3rd column?

      Comment


        #4
        Hi icabot,

        At the moment, the only documented way to do this is to create a DataSource that is basically a facade over the two types of objects (ie, the fields it declares have only properties in common). There is a feature partly implemented that allows creating a ResultTree that automatically traverses DataSource relationships based on foreignKeys - see ResultTree.js from SmartClient if interested. You can always sponsor final development of this feature to have it completed in time for you to use it.

        Comment


          #5
          Thanks, I'll keep an eye on ResultTree. This project is my personal exploration of implementing an existing project in GWT, so unfortunately, I highly doubt my supervisor would sponsor.

          For future thread readers:
          If anyone has an example of using a ColumnTree with multiple datasources in combination with a DynamicForm, please share your solution!

          Comment


            #6
            Another way to use the ColumnTree is to have your multiple data sources converted into a Tree and then use the setData(Tree tree) method of ColumnTree.
            Last edited by dfreire; 16 Mar 2009, 08:39.

            Comment


              #7
              Has This Been Added As a New Feature ?

              I'm currently trying to do was icaBot was asking about, but instead with a TreeGrid. Has support for this functionality been added ?

              If not, how would I go about converting my multiple DataSource objects to Tree objects ? I'm assuming I would instantiate a Tree and call setData(TreeNode[] nodes) on it. However, is there a quick way to convert each DataSource element to a TreeNode ? I don't see anything immediately obvious, but I'm still looking. Any suggestions on achieving this would be greatly appreciated.

              Comment


                #8
                So again:

                .. create a DataSource that is basically a facade over the two types of objects (ie, the fields it declares have only properties in common)
                When fetches occur on that DataSource just have the server return different types of objects based on the parentId in the request. Those different objects can have different sets of properties, not declared in the DataSource, which you can access on the client-side (record.getAttribute()) to have different behaviors for different types of nodes.

                Comment


                  #9
                  Sorry if it seems obvious, but I'm new to SmartGWT. I'm also trying to hook up two DataSources to the Column Tree, and I'm afraid I'm not sure what you mean by create a facade. For now, I'm using 2 local XML files as the DataSources. Examples are below:

                  tfnGroups.data.xml:

                  Code:
                  <list>
                  
                  <tfnGroup>
                  <GroupID>1</GroupID>
                  <MediaLabel>Media1</MediaLabel>
                  </tfnGroup>
                  
                  <tfnGroup>
                  <GroupID>2</GroupID>
                  <MediaLabel>Media2</MediaLabel>
                  </tfnGroup>
                  
                  <tfnGroup>
                  <GroupID>3</GroupID>
                  <MediaLabel>Media3</MediaLabel>
                  </tfnGroup>
                  
                  </list>
                  tfn.data.xml:

                  Code:
                  <list>
                  
                  <tfn>
                  <TfnID>555-555-1001</TfnID>
                  <ParentTfnGroup>1</ParentTfnGroup>
                  </tfn>
                  
                  <tfn>
                  <TfnID>555-555-1002</TfnID>
                  <ParentTfnGroup>2</ParentTfnGroup>
                  </tfn>
                  
                  <tfn>
                  <TfnID>555-555-1003</TfnID>
                  <ParentTfnGroup>3</ParentTfnGroup>
                  </tfn>
                  
                  </list>
                  In my code I have

                  Code:
                  public class TfnGroupXmlDS extends DataSource {
                  
                  	private static TfnGroupXmlDS instance = null;
                  	public static String TFN_GROUP_DS_ID = "tfnGroupDS";
                  	public static String TFN_GROUP_ID_KEY = "GroupID";
                  	public static String MEDIA_LABEL_KEY = "MediaLabel";
                  
                      public static TfnGroupXmlDS getInstance() {
                          if (instance == null) {
                              instance = new TfnGroupXmlDS(TFN_GROUP_DS_ID);
                          }
                          return instance;
                      }
                  
                      public TfnGroupXmlDS(String id) {
                  
                      	setClientOnly(true);
                          setID(id);
                          setTitleField("MediaLabel");
                          setRecordXPath("/list/tfnGroup");
                          DataSourceTextField mediaLabelField = new DataSourceTextField(MEDIA_LABEL_KEY, "MediaLabel", 64);
                  
                          DataSourceIntegerField tfnGroupIdField = new DataSourceIntegerField(TFN_GROUP_ID_KEY, "GroupID");
                          tfnGroupIdField.setPrimaryKey(true);
                          tfnGroupIdField.setRequired(true);
                  
                          setFields(mediaLabelField, tfnGroupIdField);
                  
                          setDataURL(GWT.getModuleBaseURL() + "resources/test_data/tfnGroups.data.xml");
                          setClientOnly(true);
                      }
                  }
                  and

                  Code:
                  public class TfnXmlDS extends DataSource {
                  
                  	private static TfnXmlDS instance = null;
                  	
                  	public static String TFN_DS_ID = "tfnDS";
                  	public static String TFN_ID_KEY = "TfnID";
                  	public static String PARENT_TFN_GROUP_KEY = "ParentTfnGroup";
                  
                      public static TfnXmlDS getInstance() {
                          if (instance == null) {
                              instance = new TfnXmlDS(TFN_DS_ID);
                          }
                          return instance;
                      }
                  
                      public TfnXmlDS(String id) {
                  
                      	setClientOnly(true);
                          setID(id);
                          setTitleField("ParentTfnGroup");
                          setRecordXPath("/list/tfn");
                          DataSourceTextField tfnIdField = new DataSourceTextField(TFN_ID_KEY, "TfnID", 10);
                          tfnIdField.setPrimaryKey(true);
                          tfnIdField.setRequired(true);
                  
                          DataSourceIntegerField parentTfnGroupIdField = new DataSourceIntegerField(PARENT_TFN_GROUP_KEY, "Parent TFN Group ID");
                          parentTfnGroupIdField.setForeignKey(TfnGroupXmlDS.TFN_GROUP_DS_ID + "." + TfnGroupXmlDS.TFN_GROUP_ID_KEY);        
                          parentTfnGroupIdField.setRequired(true);
                  
                          setFields(tfnIdField, parentTfnGroupIdField);
                  
                          setDataURL(GWT.getModuleBaseURL() + "resources/test_data/tfn.data.xml");
                          setClientOnly(true);
                      }
                  }

                  I'm struggling with getting the foreign key to link up with the primary key of the first XML table. Can you provide more detail about the facade?

                  Thanks.
                  Last edited by rabn08; 25 Jun 2009, 08:22.

                  Comment


                    #10
                    By "facade" we mean creating a third DataSource that declares only an id, parentId and titleField, then providing data to that DataSource that populates these three fields by pulling data from different properties for the different node types.

                    In your example below, on the initial fetch of <tfnGroup>s, you would populate the "id" field from <GroupID> and the titleField from <MediaLabel>. On the subsequent fetch, you would populate the "parentId" field from <ParentTfnGroup> and the titleField presumably from <TfnID> (if that's what you want shown as the node title in the resulting tree display).

                    This work of mapping fields from the underlying datasets to fields of the DataSource can be done client or server-side. For example, the server could produce an XML result that blends the two datasets, such that fetching either kind of node (tfnGroup or tfn) returns an XML result that has a similar structure for the basic tree properties:

                    Code:
                    <list>
                        <node>
                            <id>someId</id>
                            <parentId>someParentId</parentId>
                            <title>title for node</title>
                            ... further elements specific to the type of node ...
                    Or, you can work with your current XML formats, and transform the data client-side within transformResponse(), by working directly with the "data" object and using XMLTools APIs to extract pieces of each XML message to ultimately populate DSResponse.data with a uniform set of records.

                    Which approach to take just comes down to the details of your environment and which approach you understand more clearly.

                    Comment


                      #11
                      Any news about this feature

                      Hello,

                      I would like to know if there was any news on the development of this feature (multi-DataSource tree) ?

                      Or is the "facade" still the way to go for implementing such a feature ?

                      Thank you

                      Comment


                        #12
                        @michael0101 The facade approach is still the recommended approach.

                        Bear in mind you can always sponsor a feature, or even just sponsor the development of an example that ships with SmartGWT and shows the facade approach in more detail.

                        Comment


                          #13
                          Sponsorship

                          Hi Isomorphic,

                          I have to create a tree that represents 3 (and maybe 4 in the future) different datasources (one at each level of the hierarchy obviously) by next thursday so I guess sponsorship in not an option for this one...but good to know.

                          Thank you for your help

                          Comment


                            #14
                            Just FYI, that's a doable timeline for rush work if you don't have to go through a complex approval process, at least for a sample of best practices with existing functionality.

                            Comment


                              #15
                              Sponsorship

                              Hi Isomorphic,

                              Sorry for the delay, I was waiting for the situation to evolve on my side...

                              I will have a meeting this afternoon, and I can present the solution of sponsorship. Nevertheless I have a few question related to that...

                              (FYI I am using smartGWTEE 1.2)

                              - How much money are we talking about to develop the example of the facade ? How much time would that take ? (I am just asking for an approximation here, to get an idea...)

                              - How much for the complete feature ? How much time ?

                              - What would be the difference between the facade approach and the complete feature ?

                              - I would like a tree that is representing a different datasource on each node level (those datasources will be related by a foreign key), each node representing a datasource would have a different icon and a different menu/behavior (for example node representing datasource1, at level 1 will have menu1 assigned to the right click, node representing datasource2, at level 2 will have menu2 assigned to the right click,...) is that possible with the facade approach ? with the complete feature ?

                              Thank you for your attention

                              Comment

                              Working...
                              X