Announcement

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

    Subclass PresetDateRangeItem to create a reusable filter that is not dependent on the field name

    Referring to this sample: https://www.smartclient.com/smartcli...eFilterPresets
    I would like to do something similar but I want to re-use the subclassed item in multiple grids/fields without having to specify the field name each time.

    In the example, the field name is hard-coded to orderDate which works great if the field name is always orderDate. Is there a way to specify it so that item uses the field name that it is attached to?


    #2
    Yes - just look at this.name and then assign generated options with that field and to this.options.

    Comment


      #3
      I get the this.name part although that doesn't seem to work. Not sure what you mean by "assign generated options with that field and to this.options".

      Here is some (simplified) sample code. Could you modify it or perhaps modify the showcase example to illustrate how this can be done?

      Code:
      // Create a RecentDateRangeItem
      // To use, set the filterEditorType of a field in a datasource to RecentDateRangeItem
      
      var myClass = isc.defineClass("RecentDateRangeItem", "PresetDateRangeItem");
      
      myClass.addProperties({
          showCustomOption: true,            
          options: {
      
              "Previous Week":
              {
                  _constructor: "AdvancedCriteria", operator: "and",
                  criteria: [
                      {
                          fieldName: this.name,  // <-- 'this' does not resolve to the field, fieldName ends up blank.
                          operator: "greaterThan",
                          value: "2020-02-12"  
                      },
                      {
                          fieldName: this.name, // <-- 'this' does not resolve to the field, fieldName ends up blank.
                          operator: "lessOrEqual",
                          value: "2020-02-19"
                      }
                  ]
              }
          }
      });
      Thanks.





      Comment


        #4
        It's literally just what we said. In an override of FormItem.init, see if "name" is set in any of the passed properties objects, then that's your field name. Then assign your options, using the field name, to this.options.

        Comment


          #5
          Note that in your code above, "this.name" is just referring to window.name, because you're just in JavaScript global scope - there is no "this" except the window.

          Comment


            #6
            For anyone who just wants simple sample code, this worked for me:

            Code:
            // Create a RecentDateRangeItem
            // To use, set the filterEditorType of a field in a datasource to RecentDateRangeItem
            
            var myClass = isc.defineClass("RecentDateRangeItem", "PresetDateRangeItem");
            
            myClass.addProperties({
                showCustomOption: true, // How to make this show the regular DateRangePicker?
                init: function (field) {
            
                    if (field.name) {
                        var options = {
            
                            "Previous Week":
                            {
                                _constructor: "AdvancedCriteria", operator: "and",
                                criteria: [
                                    {
                                        fieldName: field.name,  
                                        operator: "greaterThan",
                                        value: "2020-02-12"
                                    },
                                    {
                                        fieldName: field.name, 
                                        operator: "lessOrEqual",
                                        value: "2020-02-19"
                                    }
                                ]
                            }
                        }
            
                        this.options = options;
                    }
            
                    // IMPORTANT: Do this AFTER setting the options above.
                    this.Super("init", arguments);
                },
            });
            The next question is, "How would I use the reqular DateRangePicker for the custom option?" I suspect it involves setting the getCustomCriteria() method but I don't know how to hookup a form item. Would I need to create a dynamic form and specify a field or is there an easier way?

            Comment


              #7
              You wouldn't be able to do that via the "custom option", as all that does is call getCustomCriteria(). But there are multiple ways you could offer the user the ability to enter non-preset options, such as a formItemIcon, or specialValues in the pickList (since your class is ultimately a subclass of selectItem).

              Comment


                #8

                I am confused. According to the documentation:
                Allows the user to pick from pre-set date ranges or choose a custom date range via a DateRangeDialog.

                To use this item in the FilterEditor or FilterBuilder, create a trivial subclass which defines preset options, then set ListGridField.filterEditorType to use this class with the FilterEditor, or define a custom operator and set Operator.editorType to use it with the FilterBuilder.

                See the Date Range (Presets) example for sample code.
                I've created the trivial subclass which defines the preset options and set the filterEditorType accordingly and it works. How do provide the user the option to choose a custom date range via a DateRangeDialog?

                Comment


                  #9
                  We’re unclear on your question: first you’ve said you’d like to have a custom option work via “DateRangePicker”. There is no such class, but we explained how to create your own custom option that does whatever you want.

                  Now you seem to be asking about having a custom option that opens a DateRangeDialog. But that’s the built-in behavior of the class, so...?

                  Comment


                    #10
                    I was unclear.... when I wrote 'DateRangePicker', I meant DateRangeDialog.

                    It does seem to me that the built-in behavior would be to open a DateRangeDialog when the user selects the custom option. However, I am not seeing that behavior. To test, I have modified the code from the sample https://www.smartclient.com/smartcli...eFilterPresets by copying the code in the RecentDateRangeItem tab and pasting it into the dateRangeFilterPresets.js tab. Then modify to add showCustomOption: true. When run, I DO see the Custom Date Range option in the drop down. However, selecting that option does not bring up a DateRangeDialog or anything else. Here is the complete code (I've removed the advanced filter portion as that is not needed for this sample):


                    Code:
                    // ---------------------------------------------------------------------------------------
                    // Date Range (Presets)
                    
                    isc.defineClass("RecentDateRangeItem", "PresetDateRangeItem").addProperties({
                    [B]showCustomOption: true,   // <-- Is this all that is needed to get the DateRangeDialog or is something else needed?[/B]
                        options: {
                            "Previous Month" :
                                { _constructor: "AdvancedCriteria", operator: "and", 
                                    criteria: [
                                        { fieldName: "orderDate", operator: "greaterThan", 
                                            value: { _constructor: "RelativeDate", value: "-1M" }
                                        },
                                        { fieldName: "orderDate", operator: "lessOrEqual", 
                                            value: { _constructor: "RelativeDate", value: "$today" }
                                        }
                                    ]
                                },
                            "Previous Week" :
                                { _constructor: "AdvancedCriteria", operator: "and", 
                                    criteria: [
                                        { fieldName: "orderDate", operator: "greaterThan", 
                                            value: { _constructor: "RelativeDate", value: "-1W" }
                                        },
                                        { fieldName: "orderDate", operator: "lessOrEqual", 
                                            value: { _constructor: "RelativeDate", value: "$today" }
                                        }
                                    ]
                                },
                            "Yesterday" :
                                { fieldName: "orderDate", operator: "equals",
                                    value: { _constructor: "RelativeDate", value: "$yesterday" }
                                },
                            "Today" :
                                { fieldName: "orderDate", operator: "equals", 
                                    value: { _constructor: "RelativeDate", value: "$today" }
                                }
                        }
                    });
                    
                    isc.DataSource.create({
                        ID: "presetDateRangeDS",
                        clientOnly: true,
                        fields: [
                            { name: "customerID" },
                            { name: "customerName" },
                            { name: "orderID", width:80 },
                            { name: "orderDate", type: "date", width:100 },
                            { name: "orderDescription" },
                            { name: "orderQty" }
                        ],
                        testData: presetDateRangeData
                    });
                    
                    
                    presetDateRangeDS.addSearchOperator({
                        ID: "recentDateRange",
                        title: "in recent date range",
                        valueType: "custom",
                        editorType: "RecentDateRangeItem"
                    }, ["date"] );
                    
                    isc.Label.create({
                        ID: "recentDateLabel1",
                        contents: "RecentDateRangeItem (ListGrid FilterEditor)",
                        width: 750,
                        height: 25,
                        autoDraw: true,
                        baseStyle: "exampleSeparator"
                    });
                    
                    isc.ListGrid.create({
                        ID: "grid1",
                        width: 750,
                        height: 150,
                        dataSource: presetDateRangeDS,
                        autoFetchData: true,
                        useAllDataSourceFields: true,
                        showFilterEditor: true,
                        canGroupBy: true,
                        fields: [
                            { name: "orderDate", filterEditorType: "RecentDateRangeItem" }
                        ]
                    });
                    
                    
                    
                    isc.VLayout.create({
                        width: "100%",
                        height: "100%",
                        membersMargin: 10,
                        members: [
                            recentDateLabel1, grid1
                        ]
                    })
                    So I guess the question is, "Is there something else I need to do to get the DateRangeDialog to open or is it just not working as expected?". Note that I also tried clicking the filter button with the Custom Date Range option selected, but that didn't do anything either.

                    Comment


                      #11
                      See the docs for PresetCriteriaItem.showCustomOption - you need to install getCustomCriteria()

                      Comment


                        #12
                        Actually, there is indeed a framework issue here - getCustomCriteria() isn't running because internal ListGrid code is clobbering the method that calls it.

                        We'll update here when we've fixed it.

                        Comment


                          #13
                          Cool. I look forward to the update. Could you also enhance the showcase example to use the DateRangeDialog? I think that would be a lot quicker than trying to explain in a forum. Thanks.

                          Comment


                            #14
                            It's fixed for tomorrow's builds and, yes, we'll switch showCustomOption on in that sample, by way of demonstration

                            Comment


                              #15
                              I've installed the 03/07/2020 version and tested in the showcase. The showCustomOption is now working. However, using the init method to capture the field name does not seem to be working any more (actually not sure if it ever worked in the showcase but it used to work in my own code). It seems that when the init method is called, there are no arguments passed in, thus no way to check for a field name. Here is the complete code that I tested in the showcase:


                              Code:
                              // ---------------------------------------------------------------------------------------
                              // Date Range (Presets)
                              
                              var myClass = isc.defineClass("RecentDateRangeItem", "PresetDateRangeItem");
                              
                              myClass.addProperties({
                                   showCustomOption: true,   // <-- This now works.... :)
                              
                                   init: function (field) {  // <-- but this doesn't :(
                              
                                      if (field) {
                                          var options = {
                              
                                              "Previous Week":
                                              {
                                                  _constructor: "AdvancedCriteria", operator: "and",
                                                  criteria: [
                                                      {
                                                          fieldName: field.name,  
                                                          operator: "greaterThan",
                                                          value: "2020-02-12"
                                                      },
                                                      {
                                                          fieldName: field.name, 
                                                          operator: "lessOrEqual",
                                                          value: "2020-02-19"
                                                      }
                                                  ]
                                              }
                                          }
                              
                                          this.options = options;
                                      }
                                      else {
                                         isc.say("No arguments in the init method.");
                                      }
                              
                                      // IMPORTANT: Do this AFTER setting the options above.
                                      this.Super("init", arguments);
                                  }
                              });
                              
                              isc.DataSource.create({
                                  ID: "presetDateRangeDS",
                                  clientOnly: true,
                                  fields: [
                                      { name: "customerID" },
                                      { name: "customerName" },
                                      { name: "orderID", width:80 },
                                      { name: "orderDate", type: "date", width:100 },
                                      { name: "orderDescription" },
                                      { name: "orderQty" }
                                  ],
                                  testData: presetDateRangeData
                              });
                              
                              
                              
                              isc.Label.create({
                                  ID: "recentDateLabel1",
                                  contents: "RecentDateRangeItem (ListGrid FilterEditor)",
                                  width: 750,
                                  height: 25,
                                  autoDraw: true,
                                  baseStyle: "exampleSeparator"
                              });
                              
                              isc.ListGrid.create({
                                  ID: "grid1",
                                  width: 750,
                                  height: 150,
                                  dataSource: presetDateRangeDS,
                                  autoFetchData: true,
                                  useAllDataSourceFields: true,
                                  showFilterEditor: true,
                                  canGroupBy: true,
                                  fields: [
                                      { name: "orderDate", filterEditorType: "RecentDateRangeItem" }
                                  ]
                              });
                              
                              isc.VLayout.create({
                                  width: "100%",
                                  height: "100%",
                                  membersMargin: 10,
                                  members: [
                                      recentDateLabel1, grid1
                                  ]
                              })
                              Maybe something else is getting clobbered now?

                              Comment

                              Working...
                              X