Announcement

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

    Use a SelectItem on a static array of data

    Using the latest SmartClientJS 13, I'm trying to create a DynamicForm field for payment methods. I have the payment methods in a static array, similar to this (simplified) example:

    Code:
    const methods = [
      { code: 'credit_card', name: 'Credit Card', percentage: 3 },
      { code: 'debit_card', name: 'Debit Card', percentage: 1 }
    ];
    I want to show a pick list with two columns: "name" and "percentage".

    I've managed to get this working by defining the field similar to this:

    Code:
    {
      displayField: 'name',
      editorType: 'SelectItem',
      getClientPickListData: function () {
        return methods;
      },
      name: 'payment_method_code',
      pickListFields: [
        { name: 'name', title: 'Name', type: 'text' },
        { name: 'percentage', title: 'Percentage', type: 'float', width: 80 }
      ],
      pickListWidth: 240,
      title: 'Payment method',
      valueField: 'code',
      valueMap: methods.getValueMap('code', 'name'),
      width: '*'
    }
    I must include the "valueMap" property, else no data gets shown and the scroll bar suggests there's lots of data.

    The question is, is this the right way of doing this? So I don't want server side data and I can't use just a valueMap, since I need to display the extra "percentage" value. An alternative solution is create an optionDataSource instance of type isc.DataSource with "cacheData" and "clientOnly" = true, but this seems a bit overkill.

    #2
    There's most likely something wrong in my data source configuration, because I've now made the above example without data source and then it works. It wasn't apparent from the example above that in my application there's actually a data source bound to the form containing the SelectItem.
    Last edited by wallytax; 28 Apr 2024, 22:26.

    Comment


      #3
      This should be a working stand-alone example to demonstrate the different behavior between using a data source or not. Using the example below, doesn't show data in the pick list.

      Code:
      isc.DataSource.create({
        clientOnly: true,
        fields: [{ name: 'payment_method_code', type: 'text' }],
        ID: 'TEST_DS'
      });
      
      isc.DynamicForm.create({
        autoDraw: true,
        dataSource: 'TEST_DS',
        fields: [{
          displayField: 'name',
          editorType: 'SelectItem',
          getClientPickListData: function () {
            return [
              { code: 'credit_card', name: 'Credit Card', percentage: 3 },
              { code: 'debit_card', name: 'Debit Card', percentage: 1 }
            ];
          },
          name: 'payment_method_code',
          pickListFields: [
            { name: 'name', title: 'Name', type: 'text' },
            { name: 'percentage', title: 'Percentage', type: 'float', width: 100 }
          ],
          title: 'Method',
          type: 'text',
          valueField: 'code',
          width: 200
        }]
      });
      To make it work, there are two options:
      • Remove the "dataSource" option in the form, but this is no option for my situation.
      • Add the "valueMap" property to either the form field or the data source field with this value { credit_card: 'Credit Card', debit_card: 'Debit card' }.
      Is this intentional behavior and it option 2 a good solution?

      Comment


        #4
        In the DataSource version, you don't have a primaryKey declared, which is required. You should see this reported in the client-side log.

        Either option is fine, but the valueMap one is clearly more compact code-wise.

        Comment


          #5
          1) I don't see any errors in the developer console of te browser of in the SmartClient console.

          2) Where do I need to add the primary key? Like this?
          Code:
          isc.DataSource.create({
            clientOnly: true,
            fields: [
              { name: 'id', primaryKey: true, type: 'integer' },
              { name: 'payment_method_code', type: 'text' }
            ],
            ID: 'TEST_DS'
          });
          That doesn't seem to make a difference.

          3) AFAIK the value map only allows for one "column" in the pick list, making it more like a default SELECT box in the browser? I'm not sure how I would be able to add extra fields (in this case the percentage field).

          Please let me know if my question is unclear?

          Comment


            #6
            You can't just add a primary key that's not actually in the data! In your data, the PK appears to be "code" although we don't know if that's unique.

            Yes, if you want multiple fields in the dropdown, you need a DataSource.

            Comment


              #7
              The data source that I use is for the form (TEST_DS) is not the one that I expect to be used for the pick list's data, that's different data. My goal is to have a SelectItem field that is totally unbound to any data source (client or server), just using an array as data because I want more than one pick list field. Using a ValueMap that goal is partially achievable since I can then only have one pick list field.

              Comment


                #8
                This is a working solution with a data source, but in my opinion that has a lot of redundant code:
                Code:
                isc.DynamicForm.create({
                  autoDraw: true,
                  fields: [{
                    displayField: 'name',
                    editorType: 'SelectItem',
                    name: 'payment_method_code',
                    optionDataSource: isc.DataSource.create({
                      cacheData: [
                        { code: 'credit_card', name: 'Credit Card', percentage: 3 },
                        { code: 'debit_card', name: 'Debit Card', percentage: 1 }
                      ],
                      clientOnly: true,
                      fields: [
                        { name: 'code', primaryKey: true, type: 'text' },
                        { name: 'payment_method_code', type: 'text' },
                        { name: 'percentage', type: 'float' }
                      ],
                    }),
                    pickListFields: [
                      { name: 'name', title: 'Name' },
                      { name: 'percentage', title: 'Percentage', width: 100 }
                    ],
                    title: 'Method',
                    type: 'text',
                    valueField: 'code',
                    width: 200
                  }]
                });
                Then I found that getClientPickListData() method and thought that's what I need, but I can't get it to work in a concise way.

                Comment


                  #9
                  This seems to work as well, making it more concise:
                  Code:
                  isc.DynamicForm.create({
                    autoDraw: true,
                    fields: [{
                      displayField: 'name',
                      editorType: 'SelectItem',
                      name: 'payment_method_code',
                      optionDataSource: isc.DataSource.create({
                        cacheData: [
                          { code: 'credit_card', name: 'Credit Card', percentage: 3 },
                          { code: 'debit_card', name: 'Debit Card', percentage: 1 }
                        ],
                        clientOnly: true
                      }),
                      pickListFields: [
                        { name: 'name', title: 'Name', type: 'text' },
                        { name: 'percentage', title: 'Percentage', type: 'float', width: 100 }
                      ],
                      title: 'Method',
                      type: 'text',
                      valueField: 'code',
                      width: 200
                    }]
                  });
                  Ideally, the "optionDataSource" property could have been replaced by getClientPickListData() returning the array that is now nested as "cacheData".

                  Comment

                  Working...
                  X