Announcement

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

    Parent Child Relations

    Hello,
    I've been trying to test Parent Child relations in SmartGWT. I couldn't find any helpful information/tutorials on foreign Keys with SQL datasources in GWT. While I'm no database expert I tested out constraints and small projects on my dataset and it appears my foreign Keys work as expected in the database and a few small test widgets.

    I used the BuiltInDS to try to see if I can mimic the "transactions"
    http://www.smartclient.com/smartgwte...ions_queued_md with my own dataset. I thought it would be a straightforward process since I've used these datasets in samples such as master Detail
    http://www.smartclient.com/smartgwt/..._master_detail

    I'm not concerned with processing but specifically the grid relations.
    Since I am working with sensitive data I had to make some changes to the code of course

    **explaination after the code

    parent Datesource
    Code:
    //parentTable
    <DataSource
        ID="parentTableSQL"
        serverType="sql"
        tableName="parentTable"
      
    >
        <fields>
            <field name="id"    hidden="true"  type="text"   required="true"  rootValue="root"  foreignKey="parentTableSQL.name" length="128" />
        	<field name="name"            title="Parent"      type="text"	length="128" primaryKey="true" required="true"/>
        </fields>
    </DataSource>

    Child DataSource
    Code:
    //childTable
    <DataSource
        ID="childTableSQL"
        serverType="sql"
        tableName="childTable"
    >
        <fields>
            <field name="id"         type="sequence"  hidden="true"   primaryKey="true"/>
        	<field name="name"            title="Name"    type="text" length="128" required="true"/>
    		<field name="parent"            title="Parent FK"      type="text" length="128" foreignKey="parentTableSQL.name" required="true"/>
    		
        </fields>
    </DataSource>


    Code:
    import com.smartgwt.client.data.DataSource;  
    import com.smartgwt.client.rpc.RPCManager;  
    import com.smartgwt.client.rpc.RPCRequest;  
    import com.smartgwt.client.rpc.QueueSentCallback;  
    import com.smartgwt.client.util.SC;  
    import com.smartgwt.client.widgets.Canvas;  
    import com.smartgwt.client.widgets.IButton;  
    import com.smartgwt.client.widgets.Label;  
    import com.smartgwt.client.widgets.events.ClickEvent;  
    import com.smartgwt.client.widgets.events.ClickHandler;  
    import com.smartgwt.client.widgets.form.DynamicForm;  
    import com.smartgwt.client.widgets.form.fields.SelectItem;  
    import com.smartgwt.client.widgets.grid.ListGrid;  
    import com.smartgwt.client.widgets.grid.ListGridField;  
    import com.smartgwt.client.widgets.grid.ListGridRecord;  
    import com.smartgwt.client.widgets.layout.HLayout;  
    import com.smartgwt.client.widgets.layout.VLayout;  
    import com.google.gwt.user.client.Timer;  
      
    import java.util.HashMap;  
    import java.util.Map;  
      
    import com.google.gwt.core.client.EntryPoint;  
      
    public class OneToOne2 extends VLayout {  
      
      
      //passed "parTypeSQL","childTableSQL" through the constructor 
    	public OneToOne2(String dsPar, String dsChild) {  
            DataSource parDs = DataSource.get(dsPar);    
            DataSource childDs = DataSource.get(dsChild);    
      
            final DynamicForm form = new DynamicForm();  
            form.setWidth(300);  
            form.setDataSource(parDs);  
            form.setUseAllDataSourceFields(true);  
      
            final ListGrid listGrid = new ListGrid();  
            listGrid.setHeight(224);  
            listGrid.setWidth100();  
            listGrid.setCanEdit(true);  
            listGrid.setAutoSaveEdits(false);  
      
            
            ListGridField parField = new ListGridField("name", "Parent Name");  
            SelectItem parSelectItem = new SelectItem();  
            parSelectItem.setOptionDataSource(parDs);  
            parField.setEditorType(parSelectItem);  
      
      
            ListGridField childField = new ListGridField("parent", "Children");  
            SelectItem childSelectItem = new SelectItem();  
            childSelectItem.setOptionDataSource(childDs);  
            childField.setEditorType(childSelectItem);  
    
            ListGridField qtyField = new ListGridField("quantity", "Qty", 30);
            
            listGrid.setFields(qtyField, parField, childField);  
      
            IButton addButton = new IButton("Add Contact Line");  
            addButton.setWidth(110);  
            addButton.addClickHandler(new ClickHandler() {  
                public void onClick(ClickEvent event) {  
                    Map defaults = new HashMap();  
                    defaults.put("quantity", 1);  
                    listGrid.startEditingNew(defaults);  
                }  
            });  
      
            IButton saveButton = new IButton("Save contact");  
            saveButton.setWidth(100);  
            saveButton.addClickHandler(new ClickHandler() {  
                public void onClick(ClickEvent event) {  
                    RPCManager.startQueue();  
                    form.saveData();  
                    listGrid.saveAllEdits();  
                    RPCManager.sendQueue();  
                    form.editNewRecord();  
                    listGrid.setData((ListGridRecord[])null);  
                    SC.say("Order saved in single batch.");  
      
                }  
            });  
      
            HLayout hLayout = new HLayout(10);  
            hLayout.addMember(addButton);  
            hLayout.addMember(saveButton);  
      
            VLayout layout = new VLayout(20);  
            layout.setAutoHeight();  
            layout.addMember(form);  
            layout.addMember(listGrid);  
            layout.addMember(hLayout);  
      
            final ServerCountLabel serverCountLabel = new ServerCountLabel();  
      
            layout.addMember(serverCountLabel);  
      
            RPCManager.setQueueSentCallback(new QueueSentCallback() {  
                public void queueSent(RPCRequest[] requests) {  
                    serverCountLabel.incrementAndUpdate(requests);  
                    //flash the label  
                    serverCountLabel.setBackgroundColor("ffff77");  
                    new Timer() {  
                        public void run() {  
                            serverCountLabel.setBackgroundColor("ffffff");  
                        }  
                    }.schedule(500);  
                }  
            });  
      
            layout.draw();  
            this.addMember(form);
            this.addMember(listGrid);
            this.addMember(hLayout);
            this.addMember(layout);
           // this.addMember(itemField);
        }  
      
        class ServerCountLabel extends Label {  
            private int count = 0;  
      
            ServerCountLabel() {  
                setPadding(10);  
                setWidth(300);  
                setHeight(40);  
                setBorder("1px solid grey");  
                setContents("<b>Number of server trips: 0<br>No queues sent</b>");  
            }  
      
            public void incrementAndUpdate(RPCRequest[] requests) {  
                count++;  
                setContents("<b>Number of server trips: " + count +  
                        "<br/>Last queue contained: " + requests.length + " request(s)</b>");  
            }  
        }  
      
    }
    I wanted the user to select the first field "name" (Parent Name) and depending on the item they selected populate the "parent" (Children options)

    ("parent" is of course my foreign Key established in ds.xml as well as mysql)

    The method I have seems to pull the first field as expected but allows all rows to be shown regardless of the first option. This happens for field column I put in the child except for the "name".

    When I use name it wont populate the second field with names but copy the first field over. When I try to edit that option it shows all of my parentType(foreignKey) which is odd. Even after I cleared my browser cache and restarted the app to be sure this will still happen consistently.

    I ordered a book in efforts to hopefully understand this software a little better. Is there anything in this code that seems blatantly culprit? I don't think its a bug. I have a feeling it's how I'm addressing the foreign keys in the ds.xml file. Also are there in good in-depth materials aside from the quickStart guide that may be of use to this?

    Thanks for any help in advance



    SmartClient Version: SC_SNAPSHOT-2011-12-05/EVAL Deployment

    tested in IE9(Compatibility view on and off) and Chrome
    Last edited by mdawson; 12 Jul 2012, 12:33.

    #2
    Each of your fields with an optionDataSource is going to fetch all records when the dropdown is open - which is as doc'd. It's not clear what else you're expecting to happen - some kind of context-sensitive filtering maybe - but you should read the docs for optionDataSource and immediate linked docs (valueField, displayField, getPickListFilterCriteria, etc) and also check out the Dependent Selects examples in the Showcase.

    Comment


      #3
      Thanks for the quick response. I'll definitely look into those. However #transactions_queued_md uses setOptionDatasource similar to how I have it arranged in my code yet the data seems to return filtered results unlike my attempts

      Ideally lets say I have tables designed as below

      parentTable (name=pk)
      id, name
      1, parent1
      2, parent2
      3, parent3


      childTable (id=pk parent=fk **referencing parentTable name)
      id, name, parent
      1, name1, parent1
      2, name2, parent2
      3, name3, parent3
      4, name4, parent1
      5, name5, parent2
      6, name6, parent3
      7, name7, parent1

      My intent and assumption of what #transactions_queued_md does is to
      call parent1 from the parentTable. In the second table I should have the options of name1, name4, and name7. If I call parent2 in the first field filter to name 2 and name5 of course.

      I was expecting that if my datasource is defined I could just use the appropriate ds.xml files similar to how I mentioned. I'm just not sure why it won't work the same with my datasource.
      Last edited by mdawson; 13 Jul 2012, 06:10.

      Comment


        #4
        Read through the docs a bit and worked on this more. Still getting the same result. I tried to copy the related files from the showcase example (QueuedMasterDetailAddSample.java, supplyItem.ds.xml, supplyCategory.ds.xml, queuedAdd_orderItem.ds.xml, queuedAdd_order.ds.xml) the only changes I made were

        1. including files in the bootstrap

        2. changed the tableNames to point to the database
        supplyCategory.ds.xml points to parentTable.
        supplyItem.ds.xml points to childTable
        changed foreignKey to "supplyCategory.name"

        3. in supplyCategory.ds.xml
        changed "categoryName" to "name" and "parentID" to "id"
        changed "itemID" to "id", "itemName" to "name", and "parent" to "parent"
        changed foreignKey to "supplyCategory.name"

        4. in the QueuedMasterDetailAddSample.java
        changed "categoryName" to "name"
        changed "itemName" to "name"
        re-changed "itemName" to "parent"
        (this of course is based off of the datasource I mentioned in the previous reply)

        Not sure If I'm missing a step. I was expecting that I could do a quick swap with my data-source without making major code changes since the logic was prebuilt.
        I will do some more thorough reading and studying this weekend (I am obviously new to this), but for right now I would really like to get this specific feature working if nothing else. I really appreciate all the assistance.
        Last edited by mdawson; 13 Jul 2012, 06:58.

        Comment


          #5
          Sorry, we'd still not understanding what you're expecting to happen.

          The example you're referring to saves new records only, it doesn't load them, but previously you seemed to be having a problem loading data..

          All we can recommend for now is a careful read of the QuickStart Guide, from at least Data Binding onward, with particular attention to DataSources and the CRUD operations they provide.

          Comment


            #6
            Sorry for the confusion


            I'm actually really looking for understanding the logic of the grid. Right now I'm not interested in saving. I just wanted to be able to populate the "ListGrid".

            In the example mentioned. When I click on "accessories" in the category column I get ONLY the data related to category such as "magnetic Letters Quartlet 25 mm (1)" and "Whiteboard Eraser Standard"

            This is the part I want to understand and reproduce. The ability to save data is cool but that's not what I'm looking for right now.

            What I have been able to do is populate the "Category" column with my own data but I haven't been able to filter the "item"s based on the Category. I get everything in that category regardless of the foreignKey relation.

            So my question comes down to how do I get the "Item" dependent on "Category". This may not be the best example explaining it but it has exactly what I want using SQL with ds.xml files

            http://www.smartclient.com/smartgwt/...ed_nested_grid
            has a similar relationship but is performed in XML
            Attached Files
            Last edited by mdawson; 13 Jul 2012, 07:59.

            Comment


              #7
              So again, take a look at the Databound Dependent Selects example we previously referred you to - that's the approach being used here. It looks like the source code for the example on the website might be stale, but the actual source in the Showcase project uses the same approach as is shown in the Databound Dependent Selects sample.

              Comment


                #8
                Still no luck. It's more than likely my database.
                Thanks for the patience and assistance. I should be able to figure something out.

                Comment

                Working...
                X