Announcement

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

    What operator is used in ComboBoxItems?

    Using SmartClientJS 13.0, I have a ListGrid with searchForm and in that SearchForm I have a ComboBoxItem where addUnknownValues is false. The goal is that I can type a value in the combo box and this should cause an advanced "contains" operator request on the related item. After I click an individual item, it should perform an "exact" operator request on the model itself.

    Besides that, is it possible to change the field name that gets send to the server? By default, it uses the display field name. I've managed to change this via getPickListFilterCriteria() but was wondering it there's a property for this.

    I've searched for similar questions but couldn't find any.

    #2
    comboBoxItem (CBI) "textMatchStyle" affects the default operator used for searches against the displayField.

    Once an item is chosen, the value stored is based on cbi.valueField. If a CBI is present in a SearchForm, it's this value that would be used as the criteria from the form. Whether that ends up as an exact match or not depends on what you do with the criteria from the SearchForm.

    If you do something like create a new CBI where cbi.value has been set to a specific value, you'll see the cbi issue a request to get the corresponding display value, and that will use an exact match on the valueField value. See formItem.fetchMissingValues for details on this behavior.

    There's no setting that would cause a CBI that has been configured with a valueField and displayField to instead filter on some other field, and we can't really imagine a coherent feature in that direction. However, the valueField and displayField of course do not have to actually exist as DB storage, so you can basically provide such values however you like. The only constraints are what the CBI needs to function: that the valueField is unique, and that it can acquire a displayField value for any valueField value via the fetchMissingValues operation.

    If you adhere to those basic constraints, which are the minimal constraints for any comboBox-like control to be able to function, you can return data in whatever way you like.





    Comment


      #3
      Thanks for the quick reply!

      I will try the "textMatchStyle" property again and will try to create a stand-alone example, because I believe I've already tried changing it. Maybe it is isn't working as I would like it to do, because I override the getPickListFilterCriteria() method because of my desire to change the field name that gets sent to the server. Let me explain the - IMHO - reasonable use case for this:

      I have a mechanisme of "global searching" where an user can enter a text in a search field and multiple columns in the database are searched for that text (eg. the user's first, middle or last name, or its e-mail address). I use this search mechanism for multiple models (orders, users, etc.). I have a generic mechanism that does this and I want that mechanism to always receive the "search" request parameter. The ComboBoxItem sends the displayField request parameter as name and this might differ. Not only between different models, but also within the same model: in one screen I might want to show the user's e-mail address as display field and on another screen I might want to show its name.

      Comment


        #4
        BTW, this phrase in your comment "Whether that ends up as an exact match or not depends on what you do with the criteria from the SearchForm." is unclear to me. I believe I've found another forum post describing the same issue. I want an "equals" operation to be sent when the user selects a record, not a "contains". But I think this can be enforced via the "operator" property.

        Comment


          #5
          I've spent quite some more time on the whole issue above, unfortunately without satisfying results. Hopefully anyone can help me out.

          GOAL:
          Show a list of orders with a filter field (in a search form) to filter by a specific customer. That customer should be selected from a data bound drop down (ComboBoxItem) and it must be able to search for it by typing text in the text field of the ComboBoxItem.

          QUESTION:
          Is it possible to have the ComboBoxItem send advanced criteria when a customer is searched for?

          The ComboBoxItem is added to the search form as follows:

          Code:
          {
            addUnknownValues: false,
            allowEmptyValue: true,
            cachePickListResults: false,
            changed: (form) => form.submit(),
            displayField: 'name',
            editorType: 'ComboBoxItem',
            initialSort: [{ property: 'name' }],
            optionDataSource: isc.RestDataSource.create({
              dataFormat: 'json',
              dataURL: '/customers.json',
              jsonPrefix: '',
              jsonSuffix: '',
              operationBindings: [
                { dataProtocol: 'postMessage', operationType: 'fetch' },
                { dataProtocol: 'postMessage', operationType: 'add' },
                { dataProtocol: 'postMessage', operationType: 'update' },
                { dataProtocol: 'postMessage', operationType: 'remove' }
              ]
            }),
            pickListCriteria: { active: true },
            title: 'Customer',
            type: 'integer',
            useAdvancedCriteria: true,
            valueField: 'id'
          }

          Comment


            #6
            Presumably you’ve got the ComboBoxItem fetching data, and you can select a value.

            Now, you can retrieve that value in the normal way CBI.getValue() or form.getValues(), or searchForm.getCriteria().

            Then, you can apply it to the grid as criteria in the normal way, as well, such as ListGrid.fetchData().

            How these methods work and how criteria operate is comprehensively documented.

            But it seems as if you are still focused on the CBI in the searchForm and haven’t even looked at how its value is applied to the grid - that’s what you need to look at.

            Comment


              #7
              The problem is mainly in the ComboBoxItem fetching its data. Once I select a record, it more or less works. I say "more or less" because there are more issues with that, but I've already asked something about this in another thread. The combo box does not send advanced criteria to filter its data. It sends a simple criteria object where I would have expected an advanced criteria object.

              But this problem is solved for me now because I've changed my server side implementation and I use the "filterFields" property to have it send a different name than the display field. For those interested to know what I've done (which hopefully is an acceptable solution):

              Code:
              {
                <options as described two messages above>,
                filterFields: ['search'],
                textMatchStyle: 'substring'
              }
              The request parameters sent by the ComboBoxItem are "search" = "text" and "textMatchStyle" = "substring". In the server I check for the request parameter "search" and if it exists, I use the "textMatchStyle" request parameter to determine the right operator.

              Comment


                #8
                Well, that certainly went in circles. We would ask that you please re-visit your posts here and try to be more concrete in the future.

                Particularly problemetic was "on the model itself" in your first post, especially in reference to some request that happens after an item is selected. The comboBox does not send an additional request after an item is selected. So even knowing what you ended up doing here, this still reads like you were filtering something else, after using the comboBox to determine criteria.

                Finally, it sounds like your implementation is still wrong. You can't just decide on the server what filter operator is to be used, because then, your server filtering will not match client filtering. Nor is this any apparent need to do anything like this, since getPickListFilterCriteria() already gives you complete control over the criteria (which is used both client and server side).

                Comment


                  #9
                  I'm sorry for not really understanding what's going on here. For me the last weeks have been very stressful because the customer expects things to work and I can't deliver. I even consider no longer using SmartClient because - after more than 15 years of working with it - I feel I'm not in control if I try something just a bit out of the normal flow (don't know the English expression for this).

                  I don't like Java, especially not more than 15 years ago when I started working with SmartClient and therefore decided to use RubyOnRails as server. I still feels great even if not so much people use it. I've created my own toolset that generates (advanced) queries, handles user roles, attempts to be as "DRY" as possible. A year ago I decided to use SmartClient 13 and "redesign" everything I have created before with SmartClient, trying to extend the framework to the bare minimum to make it work smoothly with RubyOnRails 7 (the latest version). A lot of things work, but unfortunately I can't get my finger behind a couple of things (after all these years). It feels embarrassing and this gives me a lot of stress. Especially since I don't know a lot of SmartClient developers in the Netherlands.

                  Enough crying... for me it still is way too confusing to see examples using all kinds of methods that do (or don't) fire HTTP requests. I've seen more today that also initiate requests. It's -at least for me - not intuitive enough. On the grid I've now seen:
                  • autoFetchData
                  • setImplicitCriteria() (see this example)
                  • filterByEditor() (see this example)
                  • refreshData() (also the above example)
                  • filterData()
                  • fetchData()
                  • invalidateCache()
                  And there's probably more, but these one come into mind right now.

                  I'm grateful for the product SmartClient is and I have managed to create lots of nice stuff, but at the moment it's hell... and I'm not 100% sure that it's all my "fault". I don't want to blame anyone, but I just wanted to express my concerns and tell about the stress that comes with the job every now and then.

                  About the thread above and probably some other threads I've started the last weeks. I have implemented getPickListFilterCriteria() and it worked for years, but now that I've changed my server to mainly parse "advanced criteria" I was surprised to see I can't have the ComboBoxItem to sent the criteria as advanced objects. Parsing the "textMatchStyle" parameter was a work-around and I felt quite fine that I sort of was able to deliver something working. But now it turns out that isn't the right approach either. That feels like not being in control... at all!

                  I have tried to express the examples as good as I can, I'm no native English speaker, but apparently I fail to explain what I need and I think the best way is to use the Java server and rebuild the whole application. Well that's a no-go and if I have to chose, I would certainly drop the front-end then and switch to native HTML.

                  Please feel free to comment, also others... I'm still willing to learn and I still have good hope I will succeed to get the whole filtering working, with SmartClient.

                  With kind regards,
                  Walter

                  Comment


                    #10
                    Sorry about all the stress, but, if you wanted the ComboBoxItem to send AdvancedCriteria, you can just return AdvancedCriteria from getPickListCriteria(). Thats it. Nothing else is required.

                    In fact the documentation for getPickListFilterCriteria() discusses situations in which the default is to return AdvancedCriteria..

                    Note further that all of the methods you describe above are also thoroughly documented, and have distinct use cases (none are redundant with the others), and the documentation generally explains how the use case is distinct and directs you to use other methods in other use cases.

                    The only thing we can suggest is that when you describe "struggling", it sounds as if you may be trying random settings and hoping for a result. That is not an effective approach and will burn a lot of time.

                    Instead, read the documentation. The documentation has been carefully refined for over 20 years with small clarifications, better interlinking, etc - we make small tweaks constantly, anytime we see someone confused.

                    If you have suggestions for improving the documentation, we'd love to hear them.

                    Comment


                      #11
                      Re-reading your answer once more, I think you are also saying that my initial problem wasn't clear. So the least I can do, is to try and re-explain. ;-)

                      Situation: a grid with orders, belonging to customers. I want to give the application user an option to filter the orders for one particular customer. I could have used the filter editor, but I decided to use a search form (inside a toolbar, similar to the one in the Custom Toolbar example, that doesn't contain a search form actually).

                      I've created a SearchForm instance and put a field in it with editorType "ComboBoxItem" and "optionDataSource" set to an instance of my (self-created) CustomersDataSource class. Setting the "addUnknownValues" property to false makes the ComboBoxItem a filterable "select box" where the application user needs to select a customer. By typing characters in the ComboBoxItem, a HTTP request is made to retrieve all customers that have one of their fields contain that text (a "global" search over multiple fields and even related models, like an address). When the list of customers is shown that match the typed text, the application user selects a record and then the "changed" event of the ComboBoxItem is called and in it, I simply call form.submit(). This causes the OrdersGrid to refetch its data, filtering on the "customer_id" column it contains. The value it filters by, is the "id" field of the Customer model. The pick list of the ComboBoxItem shows the customer's number and name. Once a customer is selected, the box only shows its name since I've configured that as display field.

                      (Mis)using the "filterFields" property of the ComboBoxItem, I've managed to have the box send "search" as "field name" (instead of "name") so that the server knows it needs to search globally in the Customer model (not only in its "name" column), thus also in its e-mail address, phone number, etc. and related addresses: it might be handy if someone calls and tells his/her postal code and the application user can find his customer record by it, don't you agree?

                      Hopefully this makes sense?!

                      Comment


                        #12
                        That makes sense and a more thorough description like that will get you help much faster and save both of us time.

                        However the solution is still just to use getPickListFilterCriteria() to return whatever criteria you want.

                        Comment


                          #13
                          I'm glad the explanation helped . ;-)

                          I do read quite a lot of the documentation actually, but sometimes it still isn't always as clear to me as you might think. Vice versa: I was under the impression that the question I had at the start of this thread was clear enough for others to understand. Apparently it wasn't, even after the other messages I wrote in this thread.

                          The thing that goes wrong here (at least that's what I guess) is that a data bound ComboBoxItem causes requests in two situations:
                          1. When it filters the items of the combo box item itself by sending a request (in this occasion to the /customers.json URL).
                          2. When a customer is selected, the form.submit() in the changed() method (which I implemented myself) causes a request to the /orders.json URL.
                          The docs mention the "useAdvancedCriteria" property (in CombiBoxItem) and it is not clear (enough) that this only applies to the second request. At least, I hope it does, because I am not 100% sure. The first request, in my opinion applies to the pick list component inside the ComboBoxItem. I have tried to set "useAdvancedCriteria" of the ComboBoxItem's "pickListProperties" property but it does not affect the criteria being sent to the server. I was convinced I was doing something wrong, because I thought it must always be possible to have SmartClient sent advanced criteria, but apparently that isn't the case.

                          While typing this message, I'm looking into the docs and find there's no useAdvancedCriteria in the PickList interface, but... isn't the pick list component of the ComboBoxItem also using parts of ListGrid? Because if it is, ListGrid has an useAdvancedCriteria property so my guess was that I could use it. Finding out it doesn't cause an advanced criteria to be sent, I was looking in my code to check if I made a mistake or so. That takes a lot of time...

                          My point is that although the documentation is extensive, it still might be misleading, at least it is for me. Once a solution isn't working, I attempt to try another one (like checking the "textMatchStyle" parameter which I described somewhere above), because in the end I need to deliver working code. And once I start doing that, I found myself on the wrong track most of the times. That's why the goal of my refactoring since last year is to stay as close to the framework as possible, but how do I (always) know what's possible or not? For this particular case (using advanced criteria) I was convinced SmartClient must be able to send advanced criteria when filtering combo box item data, but apparently it isn't, or is it?

                          And to end my message: it's not about blaming you guys... I guess it's more about communication (in both directions).

                          Comment


                            #14
                            It sounds like your #2 request is actually the request to populate data in the grid.

                            In both our first response and second response, we asked how you were applying the criteria from the SearchForm to the grid.

                            You've still not answered this.

                            Apparently, you don't know how your code is populating the grid?

                            There are basically two possibilities. Either:

                            1) you have code somewhere that calls fetchData() or similar on the grid to initiate that fetch. In this case, you can pass whatever criteria you want

                            .. or ..

                            2) you may have set listGrid.searchForm to declaratively connect your grid and form. In that case, read the docs for the property you set to discover how criteria is derived, and if you don't want it that way, see #1

                            We're guessing maybe the fetch on the grid is a mystery to you because you either forgot that you had set listGrid.searchForm, or copied it from somewhere but never read the docs?

                            Comment


                              #15
                              Yes, request #2 populates data in the grid.

                              The grid sets the "searchForm" property, new in SmartClient 13. The "customer_id" field (the ComboBoxItem) has a changed() method that only calls form.submit(). This is how the grid repopulates. And initially, it is populated via auto fetching. Thus, I use option 2 of your reply. In an earlier version I used the option 1, but the "searchForm" property seemed much easier to work with, especially when the grid also has a filter editor row. Reading your reply now makes me think I should drop the new "searchForm" option at all, because it only gives new issues. I had something working in SmartClient 12 (option 1), but this also had issues (mainly when a filter editor was used in combination with a search form).

                              Sorry, but I don't understand what you mean with "read the docs for the property you set to discover how criteria is derived". I've read the docs extensively, yes honestly, but apparently I still don't understand it. Again, something goes wrong in the communication and I'm figuring out if I'm not being clear. That's why I ask a colleague for his opinion. Sometimes that helps. ;-)

                              I need to set up a modified Custom Toolbar example to make it clear I guess. I tried this but the data source it uses isn't quite suitable I guess...

                              Comment

                              Working...
                              X