Announcement

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

  • Isomorphic
    replied
    So, almost all screens use just the enabled users, and you don't want to have to add criteria everywhere to omit the disabled users.

    A typical approach here with a server-side DataSource would be to have implicitCriteria that omits disabled users, then a special operationId you can use to get the full list.

    clientOnly DataSources don't currently support operationBindings (though they probably will have to soon, for Reify). However, you can do the same thing pretty easily:

    1) create a cacheAllData:true DataSource called "allUsers". This will fetch all users (enabled and disabled) the first time it's accessed

    2) create a second DataSource "users" as a facade. This DataSource passes all requests through to "allUsers", adding criteria to eliminate disabled users unless a specific operationId is set

    https://smartclient.com/smartgwt-6.1.../DsFacade.html

    Leave a comment:


  • mathias
    replied
    Good morning!

    Yes, I have looked into cacheAllData, and I have it for a couple of simple, kind of static, datasources. I would really like to use it for users - they are all over the place, obviously - creating scheduling, work period data, report filters etc.

    However, I have the concept of disabled users, that are kind of only used in the users tab. In the client side, I only want to show enabled users (obviously) everywhere, but for user management I must be able to show a list if disabled, to reenable.

    So I use a different criteria there, and re-fetch the users from the server when the user filters, so, if I use local data I would have to download all users, including disabled, and then filter them out everywhere but the users tab. Seemed error-prone and a hassle, so I wasn't sure how to get local data working with that, and I never had the time to look into it properly (the IOS app, or Android app, or some DB stuff, or making a new image, or client support got in the way :) )


    Regarding the select item - yeah I know it's a listgrid, I've seen your cool examples, I just didn't think of it. I have a DefaultFKSelectitem, that I use when I need, so it's really only in one place.

    Really great thread, this.

    Leave a comment:


  • Isomorphic
    replied
    That's very strange that you would have trouble declaring these things in the DataSource, since that's very basic stuff we rely on pervasively. If you revisit that someday, you will likely be able to delete reams of code.

    Yes, the SelectItem pages data like a ListGrid, in fact, the drop-down is a ListGrid, which is why it can do multiple columns, inline filtering, etc.

    If your "users" DataSource is so small that you are not bothering with paging, then don't miss our comment above about DataSource.cacheAllData - with a simple boolean setting you get a write-through cache that is established the first time a component accesses that DataSource. Then there will be no more server data requests for the life of the page (or whatever you set the expiry to).

    Note that the client-side cache can handle whatever DSRequests you throw at it - AdvancedCriteria, multi-level sort, even aggregation - it's better than your backend!

    Leave a comment:


  • mathias
    replied
    Hey thanks for responding Yeah, I do know you're supposed to be able to enter it in the xml, but I never got it to work when I set the datasources up, so I have It centralised in code instead. I'm sure I did something wrong :)

    2. oh right, you mean that it might not fetch all users at once but fetch continuously like in a listgrid? Well, for my purposes they are the same. I want to fetch all, and I want them to use the same dataset.

    Well, I did get it down to one fetch by using the datasource-local field as display field and setting localdisplayfieldvalue, so I guess I got it working.

    Leave a comment:


  • Isomorphic
    replied
    Taking these out of order:

    2) it's not the same data, because the SelectItem is just fetching the first batch of records, and there's no way of knowing whether the display value needed for the read-only text field is going to be in there

    1) the displayField values in the local vs foreign DataSource may differ, and in this case you haven't given the system the information it would need to know that they are the same: there is no "includeFrom" in <fields> definition you shared earlier. That's what would allow the system to know the values are equivalent.

    Actually, in your DataSource fields, there isn't even a "displayField" declaration, or "foreignDisplayField". You know you can put that in the DataSource? There's no need to be setting the optionDataSource/displayField etc in every form and grid, it can all be automatic.

    Leave a comment:


  • mathias
    replied
    Ok. I have done some tinkering. See how I create the combobox at the bottom.

    What I have found is that the first call to get all the users must indeed be to show the username in the combobox textfield. For this, it uses the optiondatasource since that's how it is defined.

    I can get rid of the first call, by calling setdisplayfield to the field that is a string inside the timebank datasource (FULLNAME below), but I HAVE to also call "setUsLocalDisplayFieldValue" otherwise it will fetch the user datasource anyway....


    So my takeaway:

    1. I don't understand why the form still wants to fetch the users when I've set the selectitem to use display field in the timebank datasource rather than the optiondatasource. What is is fetching the data for if I'm not using it for anything?

    2. I haven't been able to understand why the two fetches (one for the textfield, and one for the select item popup) are needed in the first place, since they use the same data.

    Code:
     reporter = new ComboBoxItem();
    reporter.setName(reporterField.getName());
    reporter.setTitle(foreign.getTitle());
    reporter.setOptionDataSource(foreign);
    reporter.setValueField(CSConstants.FIELD_ID);
    
    //fiddling. These two doesn't do anything on their own, but if both are called, it works.
    
    reporter.setDisplayField(CSConstants.FIELD_FULLNAME);
    reporter.setUseLocalDisplayFieldValue(true);

    Leave a comment:


  • mathias
    replied
    hey hey,

    Blama I doubted it since I set the form item to hidden right away, and it stays hidden until the first fetch happens and beyond. I did test anyway and the fetch is still there.

    Isomorphic
    No there is no criteria, both requests are just doing a regular fetch:
    Code:
    <transaction xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance" xsi:type="xsd:Object"><transactionNum xsi:type="xsd:long">4</transactionNum><operations xsi:type="xsd:List"><elem xsi:type="xsd:Object"><criteria xsi:nil="true"/><operationConfig xsi:type="xsd:Object"><dataSource>user</dataSource><repo xsi:nil="true"/><operationType>fetch</operationType><textMatchStyle>exact</textMatchStyle></operationConfig><componentId>isc_DefaultForm_0</componentId><appID>builtinApplication</appID><operation>user_fetch</operation><oldValues xsi:nil="true"/></elem></operations></transaction>
    <transaction xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance" xsi:type="xsd:Object"><transactionNum xsi:type="xsd:long">5</transactionNum><operations xsi:type="xsd:List"><elem xsi:type="xsd:Object"><criteria xsi:nil="true"/><operationConfig xsi:type="xsd:Object"><dataSource>user</dataSource><repo xsi:nil="true"/><operationType>fetch</operationType><textMatchStyle>substring</textMatchStyle></operationConfig><componentId>isc_PickListMenu_0</componentId><appID>builtinApplication</appID><operation>user_fetch</operation><oldValues xsi:nil="true"/></elem></operations></transaction>
    I am literally hiding it on the next row, after I create the form item, before I even attach it to the form:
    Code:
    reporter = new FKComboBoxWithGridFilterItem(ds, CSConstants.FIELD_REPORTERID, grid, CSConstants.FIELD_REPORTERID, CSConstants.FIELD_ID);
    reporter.setVisible(false);
     reporter.setEmptyPickListMessage(i18n.strings.timeBankEmptyMessage());
    
    balance = new BalanceFormItem(ds.getField(CSConstants.FIELD_BALANCE));
    ....etc        
    form.setDataSource(ds, reporter, balance, expTimeMon, expTimeTue, expTimeWed, expTimeThu, expTimeFri, expTimeSat, expTimeSun, breakPoint, note, editedCanvas);
    I'll try to look at those localdisplayvalue thingies and see if I can come up with something.

    Leave a comment:


  • Isomorphic
    replied
    Because textMatchStyle is "exact", the first fetch sounds like a fetchMissingValues fetch. This would not normally be a fetch for all users, but just to get the displayValue for the one record being edited.

    You've never shown the request itself, but it would normally include criteria that has the PK value of the user record that a displayValue is needed for.

    The next step is to figure out whether the criteria are absent (which could indicate some kind of misconfiguration) or whether your server just ignores the criteria (server problem).

    You can also look at useLocalDisplayValue and foreignDisplayValue to understand the circumstances in which it would be necessary to fetch a displayValue, and tweak how it works. It does seem like it is necessary here.

    Finally, a hidden SelectItem would not normally fetch data. What may be happening here is that you are hide()ing the SelectItem after the form has already drawn or has gone through the initialization that would trigger this fetch.

    Leave a comment:


  • Blama
    replied
    Hi mathias,

    I got that. My question was about the technical how. Perhaps it is related to your show/hide code?

    What happens if you comment out all show() or all hide()?

    Perhaps a visibleWhen-rule or a showIf-condition would work here as well and save you many lines of code?

    Best regards
    Blama

    Leave a comment:


  • mathias
    replied
    Blama Because when editing an existing timebank, you can't change the user, so there's no reason to show it. The user name is already in the header.

    (We spend quite a lot of time reducing cognitive load, a lot of our users are not very computer savvy.)


    If you wonder what we do with the select item, it's something like this:

    1. on page load it's hidden.
    2. when clicking around in the list grid, still hidden.
    3. when editing/cancelling/saving, still hidden.

    4. when clicking "new", we show it, then hide it again on save/cancel. (For other tabs, for example the scheduling module, we might show it both in edit mode and new mode)
    Last edited by mathias; 20 Mar 2024, 05:03.

    Leave a comment:


  • mathias
    replied
    Hey claudiobosticco thanks for pitching in. Yeah I did check that, thought I had written it here but apparently not.

    As I write, the first time it's the dynamic form fetching, and the second time it's the pick list, as evidenced by the HTTP requests in the logs. The only differences between the 2 fetch requests are:

    Code:
    <componentId>isc_DefaultForm_0</componentId><textMatchStyle>exact</textMatchStyle>
    <componentId>isc_PickListMenu_0</componentId><textMatchStyle>substring</textMatchStyle>

    Leave a comment:


  • Blama
    replied
    Hi mathias,

    what are you doing so that for ListGrid-selection -> editRecord() there is no SelectItem in the screenshot, but for the click on "+" below "Time bank" there is?
    There must be some hiding/showing of the SelectItem going on, correct?

    Best regards
    Blama

    Leave a comment:


  • claudiobosticco
    replied
    Hi mathias did you check in the dev console (RPC Tab) which are the components responsible for the double fetch? You may also track down to the line code responsible for the fetch in the "Call Stack" tab (in the lower left part)

    Leave a comment:


  • mathias
    replied
    I have a "HeaderLayout" class that listens for form events, takes the selected record and populates the labels with specified attributes. For this, the "full name" attribute is also used, so the foreign key field is not touched.

    I actually forgot to mention one thing: If I take out the select item from the form, no user fetch is performed at all, so that should prove that it is only the select item that's the source for the fetches.


    Edit: 13.0-p20240228, although it's been like this for a very long time.
    Last edited by mathias; 20 Mar 2024, 04:06.

    Leave a comment:


  • Blama
    replied
    Hi mathias,

    OK, so to me it seems that the 1st fetch of all users is the unnecessary/wrong one. It's a form not showing the user-SelectItem and prefetching the data here seems unnecessary, especially as you can't edit the user anyway.
    EDIT: This is not a read-only form, removed that word.

    How is the "Mark Knopfler" above "Current balance: 0" in the screenshot in #7 generated? This is not a SelectItem, but a Label, correct?
    Perhaps the SelectItem you can see in #9 is actually also present in #7, but hidden? This would not explain the re-fetch/2nd fetch, but perhaps why the fetch happens when just showing the form?

    Also, can you give you version/build? I don't need it, but Isomorphic might.

    Best regards
    Blama

    Leave a comment:

Working...
X