Dropdown Interaction with Validation Functions

In this section, you will see how you can combine dropdown functionality with validation functions if you so desire that a field is actually constrained to those set of valid options.

By default, dropdowns act as guides for the user rather than being hard restrictions on the values that can be entered in a field. Even if a field is constrained to a set of possible values, it’s still possible for the autocomplete engine to synthesize values that don’t match.

If it is desired that the field is actually constrained to those set of valid options, this can be achieved using a custom validation function along with the `validOptions`. This isn’t enabled by default since there are a wide variety of complicated business rules that can be represented using the dynamically retrieved valid options and it could possibly conflict with those in unexpected ways.

Custom validators have this function signature:

type ValidationResult = boolean | { errorMessage?: string } | string;
 
type ValidationFunction = (rows: (string | null)[][]) =>
  Promise<ValidationResult[]>;

The custom validation function passed to `validator` receives the current values of all output rows as a 2D array, allowing all rows to be validated at once for efficiency. The return value is an array of validation results for each row which must be the same length as the provided `rows` array.

Here’s an example of a validation function that actually does constrain the values entered (or synthesized) for the “Payment Type” field to match one of the valid options:

{
 name: 'paymentType',
 validOptions: ['cash', 'credit', 'debit', 'paypal'],
 validator: async (rows) => {
   return rows.map((row) => {
     const paymentType = row[0];
     if (!['cash', 'credit', 'debit', 'paypal'].includes(paymentType)) {
       return 'This field must be one of the valid payment types';
     }
 
     return true;
   });
 }
}

If invalid values are synthesized, they will be marked as errors with the custom error message in the UI shown to the user:

An actual upload snippet with this example of a dropdown field may look like the JavaScript below:

<!-- Osmos File Upload Button -->
<!-- See this link for more docs. https://docs.osmos.io/osmos-uploader/webpage-integration -->
<script src="https://cdn.osmos.io/button/embed/v1/OsmosButton.js"></script>
<script>
  Osmos.configure({
  schema: {
    fields: [
      {
        name: "ProductID",
        displayName: "ProductID",
        description: "<Your field description here>"
      },
      {
        name: "FirstName",
        displayName: "FirstName",
        description: "<Your field description here>"
      },
      {
        name: "LastName",
        displayName: "LastName",
        description: "<Your field description here>"
      },
      {
       name: 'paymentType',
       validOptions: ['cash', 'credit', 'debit', 'paypal'],
       validator: async (rows) => {
         return rows.map((row) => {
           const paymentType = row[0];
           if (!['cash', 'credit', 'debit', 'paypal'].includes(paymentType)) {
             return 'This field must be one of the valid payment types';
           }
           return true;
         });
       }
      }
    ]
  },
  token: "example_some_uploader_token_uuid_example",
  uploadDescription: "<Include a description of your uploader upload here which will be shown to users that click the uploader>",
  

  // Set to false to show the schema for the destination connector in the uploader on the file upload screen.
  hideUploadSchema: true,

  // Set to false to show the uploader description on the file upload screen.
  hideUploadDescription: true,

  // Set to false to show the advanced version of the uploader, with formulas, SmartFill, and QuickFixes.
  disableAdvancedMode: true,

  // Maximum number of records displayed in the Uploader UI (User Interface).
  // This value is capped at 100,000 and higher values will default back to 100,000.
  // Can be lowered to increase UI performance when using expensive validators.
  // NOTE: Your file can have >100,000 rows and will be processed fully. There are no limits to how many records can be uploaded.
  //       This setting only limits the number of rows displayed in the UI.
  maxRecords: 100000,

  // Set to true to hide the preview pane screen for CSV files in the uploader.
  hideCSVPreviewPane: false,

});
</script>
<button class="ftl-button" onclick="Osmos.handleClick('w9ziodyyfx4mq6wl2tw1y6dpp6tctfardjeuqsl_n0i-gtsbb')">
  Upload Your Data
</button>
<!-- End Osmos File Upload Button -->

Last updated