Announcement

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

    Displaying fields from related objects in a ListGrid

    I'm trying to produce a ListGrid that will display a list of customers, showing first name and last name along with their preferred addresses.

    Addresses in this system are immutable shared objects with a sequenced ID field, and the Customer object has a preferredAddress field with a foreign key to a particular address:

    customer.ds.xml
    Code:
    <field name="id" type="sequence" hidden="true" primaryKey="true" />
    <field name="givenName" type="text" required="true" />
    <field name="familyName" type="text" required="true" />
    <field name="preferredAddress" type="integer" foreignKey="physicalAddress.id" />
    physicalAddress.ds.xml
    Code:
    <field name="id" type="sequence" hidden="true" primaryKey="true" />
    <field name="line1" type="text" required="true" />
    <field name="line2" type="text" />
    <field name="city" type="text" required="true" />
    <field name="st" type="text" required="true" />
    <field name="zip" type="integer" required="true" />

    When I create a ListGrid with the "customer" DataSource and no specified fields, I see all the customer information and [Object object], as seen in several other threads.

    Unlike in the Data Selection example, I am not wanting to flatten the DataSource to present address information as part of the customer's record; these addresses are needed in several parts of the system, and I just want to display part of the joined address to help users select the correct customer.

    I thought for some reason that adding a ListGridField("preferredAddress.line1") would make the grid follow the foreign key to the "preferredAddress" DataSource, but instead I get blank lines, and the server doesn't indicate a fetch for addresses.

    What should I be doing instead to have the grid field reflect a value from a different but related DataSource?

    #2
    If what you want is information from the address displayed as a ListGridField, then the Data Selection approach is the way to do it. Adding those fields for the purposes of display in a grid doesn't imply anything about the Address being flattened in any other context - it can still be edited as an independent object in another part of the system.

    Comment


      #3
      Hello,
      I have this exact same question, however I'm not sure where to locate these suggested samples? I'm looking in the showcase, but can't find the specified "Data Selection" approach.

      The problem I keep running into with the examples I'm finding is the foreign keys are not sequences, for example: "categoryName". My foreign keys happens to be sequences too, and I want to display the related textual value.

      Thanks

      Comment


        #4
        The Data Selection sample and all other samples related to Pro/EE functionality is here in the Pro/EE Showcase.

        The Data Selection approach will also let you traverse from an id to a text value (not sure what your concern about sequences is here), however, unless you have special reasons to use Hibernate, consider the SQLDataSource - it's more powerful, easier to customize and generally has better performance. See this sample for how you would do name/value mapping with the SQLDataSource, and see also the QuickStart Guide, which goes into this and related features in some depth.

        Comment


          #5
          Originally posted by Isomorphic
          If what you want is information from the address displayed as a ListGridField, then the Data Selection approach is the way to do it. Adding those fields for the purposes of display in a grid doesn't imply anything about the Address being flattened in any other context - it can still be edited as an independent object in another part of the system.
          I should have been more expansive with my question, but it was late here. ;-)

          This isn't the only use for the Address object. Specifically, each Customer has a list of associated Addresses and a single preferred Address. We want to be able to change a Customer's preferred Address via a dropdown or drag-and-drop interface, which suggests to me that we really do need the DataSource to understand that these fields are in a foreign-key relationship.

          Is there an approach (such as with a formatter) that would allow us to set the column to really traverse the join?

          Comment


            #6
            What you might be missing is that you can have a DataSource for physicalAddress *and also* use valueXPath to flatten the fields into the customer DataSource. These approaches are not mutually exclusive.

            So, for example, let's say you want several fields from the primary address to be displayed as a single ListGrid field, but wanted to edit it via a SelectItem that loads related addresses.

            Define a field in the customer DataSource called preferredAddress is an FK to the physicalAddress field.

            Use valueXPath in the customer DataSource to pull in fields from the related Address object server-side. Mark these fields "hidden" and use a CellFormatter on the physicalAddress field in the ListGrid to grab values from the hidden fields in the Record to provide a special rendering (eg one that looks like "address line 1, address line 2, city, state, zip").

            When you go to edit this field, because it's got an FK, the default behavior will show a SelectItem that allows scrolling through Address records.

            What's saved to the server is the PK of the related Address record.

            Comment


              #7
              Thanks, I'll give this a shot.

              As a side note, the formatters are hard to find documentation for. It would help immensely to have a link from the JavaDoc to wherever the format specification lives.

              Comment


                #8
                What formatters?

                Comment


                  #9
                  Sorry, the formatter interfaces. For example, CellFormatter takes an "Object value", but there's no explanation of what that object is. It looks like a GWT JavaScriptObject proxy, but you cast it to regular Java types.

                  EDIT: More specifically, what is "value" for a foreign-key ListGrid cell? Is there a way for me to look into it and read its attributes for display or cell highlighting?
                  Last edited by chrylis; 27 Oct 2010, 16:54.

                  Comment


                    #10
                    The Object is the field value as found in the Record, and it really can be anything, hence is typed Object.

                    Comment


                      #11
                      It feels to me like I'm overlooking something, so thanks for your patience.

                      In this example, I want to attach a CellFormatter to the ListGridField called "preferredAddress" (with the DS schema I described above). With no formatter, it displays "[object Object]", which is understandable, since there's no toString that gets propagated to the client.

                      What I'm trying to understand is, in this particular case, what is the "value" parameter passed to the CellFormatter? Is it the foreign key of the preferredAddress? Is it some form of Record describing the Address object referred to? Or is it something else entirely?

                      EDIT: When I make the ListGrid editable, I still don't get a dropdown for that column; instead, I get a text edit. Is there something else I need to do on the client side to wire up the ListGrid beyond passing it an XML-derived DataSource?

                      Comment


                        #12
                        In your system, addresses have unique and separate identity, addresses can be searched and edited separately from customers, and multiple objects can presumably be linked to a single address.

                        So, what you want to edit is not the address as such, but the FK value from the customer to the address. So declare the FK field explicitly in your bean and declare a DataSource field to that, then you'll see a databound SelectItem as the editing interface.

                        Separately, you can use valueXPath to pull in values from the related Address bean in order to create nice formatting for the FK field (that is, show a short form of the address, all in one listGrid column).

                        In your current approach of mapping a DataSource field to the Address bean directly (and not it's FK), the field value is a JavaScriptObject representing the nested object being delivered (see the RPC tab in the Developer Console). From this JavaScriptObject, you could construct a Record which represents the related Address, and that could make sense if your use case were more like this one, where the order "owns" the orderItems and the orderItems have no separate PKs. But you don't want to do this as covered above.

                        Comment


                          #13
                          When you say to declare the FK field explicitly, do you mean having the actual business object that I put in the DSResponse return a long instead of an Address for getPreferredAddress()? I understood from the server docs that the appropriate way to handle this case was to define the field thus:

                          Code:
                          <field name="preferredAddress" type="integer" foreignKey="physicalAddress.id" />
                          and that the DataSource would understand from this description to substitute the "physicalAddress.id" property for this field on the client side. Should I instead define the DataSource as above but actually load the DSResponse with the key manually instead of with the referenced JPA object?

                          Comment


                            #14
                            You need to make the FK field explicit rather than implicit in your bean, because it's the value you want to deliver to the browser and have saved back. Here's a sample of the appropriate Java field declarations and annotations for a similar use case.

                            Comment


                              #15
                              I will try adding a getter/setter pair that wraps the address ID FK.

                              I would suggest as an enhancement that when a field is explicitly declared in the .ds.xml as a foreign key, the IDA server follow the attribute path to the appropriate foreign DataSource and pull out the ID itself. (For example, where my customer.ds.xml says <field name="preferredAddress" foreignKey="physicalAddress.id">, the server could look at the physicalAddress DataSource and replace the Customer Address field with the result of getPreferredAddress().getId().)

                              The current behavior is counterintuitive, and this requirement isn't obvious from the documentation.

                              Comment

                              Working...
                              X