canvas-sheet

This example demonstrates dynamic dropdown filtering based on the current row's data.

Showing (...) rows

          
  const LOCATIONS = [
    { id: 1, name: "New York" },
    { id: 2, name: "London" },
    { id: 3, name: "Tokyo" },
    { id: 4, name: "Paris" },
    { id: 5, name: "Sydney" },
    { id: 6, name: "Berlin" },
    { id: 7, name: "Cairo" },
    { id: 8, name: "Rio de Janeiro" },
    { id: 9, name: "Moscow" },
    { id: 10, name: "Beijing" },
  ];
  
  const DEPARTMENTS = [
    { id: 1, name: "Sales", locationId: 1 },
    { id: 2, name: "Marketing", locationId: 3 },
    { id: 3, name: "Engineering", locationId: 7 },
    { id: 4, name: "Finance", locationId: 1 },
    { id: 5, name: "Human Resources", locationId: null },
    { id: 6, name: "Legal", locationId: 9 },
    { id: 7, name: "Customer Support", locationId: 4 },
    { id: 8, name: "Research", locationId: 8 },
    { id: 9, name: "IT", locationId: 3 },
    { id: 10, name: "Management", locationId: 10 },
  ]
  async function getAsyncData(rowData: DataRow) {
    return new Promise(resolve => {
      setTimeout(() => {
        if (rowData.locationId) {
          resolve(Array.from({ length: rowData.locationId + 1 }, (_, i) => ({ id: i + 1, name: `Checkout ${i + 1}` })));
        } else {
          resolve([]);
        }
      }, 1000 + (Math.random() * 2000));
    });
  }
  // --- Schema Definition ---
  const schema: SpreadsheetSchema = {
    id: { type: "number", decimal: false, label: "ID", required: true },
    name: {
      type: "text",
      required: true,
      maxlength: 20,
      label: "Full Name",
    },
    email: {
      type: "email",
      required: true,
      // placeholder: "Enter email",
      label: "Email Address",
    },
    dob: { type: "date", label: "Date of Birth", defaultValue: new Date().toISOString().split('T')[0] },
    locationId: {
      type: "select",
      label: "Location",
      // tooltip: "Select your location",
      values: LOCATIONS,
      // custom dropdown filtering logic
      filterValues: (rowData: DataRow) => {
        if (rowData.departmentId) {
          const department = DEPARTMENTS.find(d => d.id === rowData.departmentId);
          if (!department || !department.locationId) return LOCATIONS;
          const location = LOCATIONS.find(l => l.id === department.locationId);
          return location ? [location] : LOCATIONS;
        }
        return LOCATIONS;
      },
    },
    departmentId: {
      type: "select",
      label: "Department",
      // tooltip: "Select your department",
      values: DEPARTMENTS,
      // custom cell disabling logic
      disabled: (rowData: DataRow) => {
        return !rowData.locationId;
      },
      // custom dropdown filtering logic
      filterValues: (rowData: DataRow) => {
        return [
          { id: null, name: '(Empty)' },
          ...DEPARTMENTS.filter(d => !d.locationId || d.locationId === rowData.locationId)
        ];
      },
    },
    checkoutId: {
      type: "select",
      label: "Checkout",
      filterValues: getAsyncData,
    },
    isRestricted: { type: "boolean", label: "Restricted", nullable: true, defaultValue: true },
    salary: { type: "number", label: "Salary" },
    notes: { type: "text", label: "Notes" },
  };