Announcement

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

    Customizing ListGrid fields created from DataSource

    Quite a bit of our list grids have fields derived from the data source. I did not find a proper event, in which I can change some of the properties of such fields. Attempt to call getFieldByName returns null in onInit override. I also tried setFieldProperties, but setShowHover(true) setting at least was not copied to the field created from the datasource metadata.

    Could you please provide a working sample/snippet on how to customize such fields?

    #2
    Hi Michael,

    The idea is that your specified ListGridFields act as a kind of overlay of DataSource fields. You can see samples of doing this (via setFields()) in the QuickStart Guide, Data Binding chapter. The same approach works if you want to create a subclass - just call setFields() from onInit(), for example. If you want to know the set of default fields, you can just iterate over the DataSource fields.

    Note that the default fields are normally created on draw, so you can access them after that. It also works to just call setFields() with no arguments, to cause earlier creation.

    Finally, setFieldProperties() is how you change properties on fields after draw().

    Comment


      #3
      1. I will try setFields() in onInit followed by setFieldProperties(), thanks for the hint.

      Again, cant help but notice that this follows the same pattern as scrolling I wrote before. Cumbersome!

      You can make implementation smarter, remember settings and apply them whenever is best. It is standard practice in other toolkits with delayed change processing, e.g. Adobe Flex and WPF. We can discuss then after work order contract is signed.

      2. As for the sample of overlay, for example, https://www.smartclient.com/smartcli...tsMergedFields, it is totally misleading in this context. Change fields definition to have only one and the grid will have only one, not four. So indeed KIND of overlay.

      I am pretty sure you can do better!

      isc.ListGrid.create({
      ID: "countryList",
      width:500, height:224, alternateRecordStyles:true,
      fields:[
      // move countryCode before country name and replace with flag image/title
      {name:"countryCode", title:"Flag", width:40, type:"image", imageURLPrefix:"flags/16/", imageURLSuffix:".png"},
      {name:"countryName"},
      ],
      dataSource: countryDS,
      autoFetchData: true
      })

      Comment


        #4
        Originally posted by michaelplavnik View Post
        1. I will try setFields() in onInit followed by setFieldProperties(), thanks for the hint.

        Again, cant help but notice that this follows the same pattern as scrolling I wrote before. Cumbersome!

        You can make implementation smarter, remember settings and apply them whenever is best. It is standard practice in other toolkits with delayed change processing, e.g. Adobe Flex and WPF. We can discuss then after work order contract is signed.
        Hi Michael, it's difficult to follow this critique. We recommend setFields() as the approach both for configuring a ListGrid and for subclasses and for changing fields on the fly, because:

        1. it gives a single approach for all 3 cases, and others
        2. the code you have to write is shorter and reads better than a series of calls to setFieldProperties()
        3. it's more performant: do all the work at once

        We could definitely make setFieldProperties(), of course. But then people would be using a slower and worse API. So, perhaps the best approach here is to change the docs of setFieldProperties() to point out that setFields() is actually better for all but certain rare circumstances (updating just selected properties on one field), point to setFields() as the correct approach, and perhaps even log a warning if someone calls setFieldProperties() at the wrong time, again pointing to setFields(), in case they missed it in the QuickStart. Would you agree?

        Originally posted by michaelplavnik View Post

        2. As for the sample of overlay, for example, https://www.smartclient.com/smartcli...tsMergedFields, it is totally misleading in this context. Change fields definition to have only one and the grid will have only one, not four. So indeed KIND of overlay.

        I am pretty sure you can do better!

        isc.ListGrid.create({
        ID: "countryList",
        width:500, height:224, alternateRecordStyles:true,
        fields:[
        // move countryCode before country name and replace with flag image/title
        {name:"countryCode", title:"Flag", width:40, type:"image", imageURLPrefix:"flags/16/", imageURLSuffix:".png"},
        {name:"countryName"},
        ],
        dataSource: countryDS,
        autoFetchData: true
        })
        Hi Michael, yes, this is an overlay - notice how countryName has no properties other than name, but the ListGridField is configured with all of the properties specified in the DataSource - they did not need to be repeated.

        What you may be looking for, also covered in the QuickStart Guide, is the setting useAllDataSourceFields:true, in which case you get DataSource fields and your fields are treated as an overlay in the sense that all DataSource fields are implicitly present - including the ability to set hidden:true to get rid of specific fields you don't want!

        Please let us know if you see possibilities for improvement here, including any improvements to the docs that might make it easier to find this information. Perhaps you think the various modes of overlay are important enough to cover in the QuickStart (it's already kind of long..)? Or perhaps it's best that the Reference has a more complete discussion so that it's not necessary to read the QuickStart? Please let us know.

        Comment


          #5
          First of all, I need to apologize, as my post seems aggressive. Actually, I think for the size and domain of the company, you have achieved almost impossible level of business success and my expectations are very high in accordance.
          That said, our discussion went several routes at once. To simplify, let’s tackle simple things first. useAllDataSourceFields:true is exactly what I was missing and hoping for.
          This, however, leads to the route of documentation. I regard Quick Start Guide as a high level document (as many lower level details are missing in it), thus, was not expecting to find this detail in it. Will do a better job next time. I also do not expect that you can afford significant effort on detailed documentation, which is not API docs. So the only reasonable expectation I would have is improvement of showcase. For example, in this case, either second grid with the flag set, or just link to documentation of the flag inside case description would be enough.

          Comment


            #6
            This post touches on more ideological/criticism points, and thus, tough to make constructive.
            My critics came from two experiences.
            First one, I am developing a page (widget) with multiple tabs and each tab host scrollable content. As a result of a refresh, previous instance of the page is discarded and a new one is created (taking aside why discard was needed in a first place). I want to restore scroll position of each tab. The most straightforward approach is to create a page and then call its methods to assign the state including scroll state. However, this will not work if widget did not reach certain point in its lifecycle and request is simply ignored. It was suggested to force lifecycle transaction by causing reflow.
            Second one, I need to override certain properties of the grid columns (show overlay flag in this case). Let’s assume for the sake of this example that useAllDataSourceFields does not exist in the library, and the only way to apply an override is by calling setFieldProperties (does not matter how performant it is). The most straightforward approach is to create a grid and then call setFieldProperties along with setting other properties of the grid. Ops, setFieldProperties request is silently ignored. Again, it was suggested to force lifecycle transaction by calling setFields() without parameters.
            I am looking on these two examples, and making a conclusion about ideology behind certain choices in SmartClient library. Certain operations (which one exactly are unknown and undocumented unless tried, or if I am wrong, then not obvious how to get such knowledge ahead of time) are silently ignored in construction part of the lifecycle of the widget. To remediate this situation, case by case method that can transition widget in its lifecycle are suggested.
            In my book it is called cumbersome. And it is perfectly workable design ideology.

            Comment


              #7
              Thanks for the kind words, and don't worry about the tone.

              We definitely do not have an ideology where we want to force developers to worry about lifecycle issues, our philosophy is the reverse: make the API do the obvious thing. We are constantly refining our API every time we get feedback or someone misunderstands the docs.

              As far as setFieldProperties, to give some context, for 20 years setFields() has been the way fields are configured, and, setFields() works at any point in the lifecycle, and whether creating an instance or a custom class - it's all setFields()).

              Then, more recently, we added a setFieldProperties() utility method to allow an optimization in a corner case. To clarify, even if useAllDataSourceFields didn't exist, you still would not use setFieldProperties(). You should probably just forget you ever found setFieldProperties() :) It's for an edge case and the product existed for 15 years without it.

              So really what happened here isn't related to lifecycle handling. The problem here was, it simply didn't occur to us that a developer could come in looking solely at the JavaDoc, and, because of the name setFieldProperties(), guess that this was the main way to set up fields, when the API really just exists for a corner case.

              Now, the docs have been changed to redirect people to setFields() and the QuickStart Guide so this misunderstanding is impossible - we even went so far as to carefully change the first sentence of the doc, since in JavaDoc you actually have to click through to see the rest!

              --

              Separately, the point about scrollTo() not working before draw is an interesting one, but there's actually a surprising amount of complexity there. Drawing can be asynchronous as can data load, and both can change the scrollable area (consider eg listGrid.autoFitData:"vertical" - height expanding to asynchronously loaded data).

              Because of this, it would be really difficult to define the right behavior for a delayed scrollTo() - should the delayed scrolling happen when everything is drawn - meaning the entire widget hierarchy under the scrolled element? But then what about synchronous post-draw additions? Maybe it should wait until all data is loaded by any DataBoundComponents in the hierarchy, since that might change sizes? Or should it wait until everything quiesces, like AutoTest.isSystemDone()?

              For your use case, you probably wanted the last of these possible behaviors, but it doesn't seem like it would be the right default in the framework, as it might postpone the scroll action indefinitely.

              So, we definitely have done a lot of work to make most APIs order-independent, and will continue to do so. But with scrollTo(), we're just going to add an explicit note to the docs that it doesn't work before draw.

              --

              As far as what made you refresh the entire page, we're not sure what necessitated that, but we'd welcome a new thread where we could maybe help figure out another approach - page reloads are definitely undesirable in general, as you lose all your cached data, making it a scalability and responsiveness hit.


              Comment

              Working...
              X