CSV Option Upload for Survey Questions
Overview
When creating MULTIPLE_CHOICE questions with many options (e.g., a list of 195 countries, job titles, languages), manually typing each option is tedious and error-prone. This feature allows survey creators to upload a CSV file to bulk-populate the options list for a question.
Related Specs: WeHappers Migration | Structured Assessments
Use Cases
- Country dropdown: WeHappers needs a "What country are you in?" question with 195+ countries
- Organization lists: Large NGOs with many partner organizations
- Skill inventories: Competency assessments with predefined skill lists
- Location lists: Cities, regions, or districts within a country
User Flow
- User is in the Survey Builder editing a MULTIPLE_CHOICE question
- User clicks "Import from CSV" button (next to the manual "Add Option" button)
- File picker opens, accepts
.csvand.txtfiles - File is parsed client-side (no server upload needed)
- Options are extracted and displayed in the options list
- User can review, reorder, add, or remove individual options before saving
- User saves the question normally
CSV Format
Simple format (one column, no header)
Canada
France
Germany
United States
With header (auto-detected and skipped)
Country
Canada
France
Germany
United States
With weights (two columns)
For MULTIPLE_CHOICE questions that use weighted_options scoring, a second column provides the weight:
Option,Weight
Strongly Agree,5
Agree,4
Neutral,3
Disagree,2
Strongly Disagree,1
Parsing Rules
- Accept
.csvand.txtfiles - If the file has one column, treat each row as an option label
- If the file has two columns, treat column 1 as the label and column 2 as the weight (for
option_weightsinscoring_config) - Auto-detect and skip header row if it matches common patterns ("Option", "Label", "Name", "Country", "Value")
- Trim whitespace from each value
- Remove empty rows
- Remove duplicate values (case-insensitive comparison, keep first occurrence)
- Maximum 500 options per question
Frontend Implementation
Component: CsvOptionImport.tsx
Location: frontend/src/components/CsvOptionImport.tsx
interface CsvOptionImportProps {
onImport: (options: string[], weights?: Record<string, number>) => void;
}
Behavior:
- Renders a secondary button "Import from CSV" in the question builder
- Opens native file picker on click
- Parses CSV client-side using basic string splitting (no library needed for this simple format)
- Calls
onImportwith the parsed options array - Shows a toast with count: "Imported 195 options"
- If duplicates were removed, shows: "Imported 195 options (3 duplicates removed)"
Integration with QuestionBuilder
In the existing QuestionBuilder.tsx, add the import button when question.type === "MULTIPLE_CHOICE":
[Add Option] [Import from CSV]
The imported options replace the current options list (with a confirmation dialog if options already exist).
Backend Changes
None. The CSV parsing happens entirely on the frontend. The backend receives the same options: string[] array it always does when saving a question. The weights (if provided) populate the existing scoring_config.option_weights field.
Validation
- File size limit: 100KB (prevents accidental large file uploads)
- Option length limit: 200 characters per option
- Option count limit: 500 per question
- Show clear error messages for malformed files
Edge Cases
- File with mixed encodings: Parse as UTF-8, show error if parsing fails
- Options with commas: Support quoted values (
"New York, NY") - Existing options: Prompt "Replace existing options?" or "Append to existing options?"
- Empty file: Show error "No options found in file"
Example: Country List
A ready-made CSV file with all countries could be provided as a downloadable template in the Survey Builder UI:
[Import from CSV] [Download country template]
This template file would contain the standard ISO country list (195 countries) for immediate use.