Skip to content

fix: support single-question multiSelect in AskUserQuestion#17

Open
NOirBRight wants to merge 9 commits into
ygncode:mainfrom
NOirBRight:fix/multiselect-single-question
Open

fix: support single-question multiSelect in AskUserQuestion#17
NOirBRight wants to merge 9 commits into
ygncode:mainfrom
NOirBRight:fix/multiselect-single-question

Conversation

@NOirBRight
Copy link
Copy Markdown

@NOirBRight NOirBRight commented May 30, 2026

Problem

When AskUserQuestion has a single question with multiSelect: true, clicking an option immediately sends the answer as a single choice — the same behavior as a single-question single-select. The multiSelect property is completely ignored.

Also, the "Type something." free-text input row that pi TUI always shows for single-select questions was missing in pi-web entirely, and multi-select questions with free-text options (like "其他"/"Other"/"自定义"/"Custom") rendered them as regular buttons instead of text inputs.

Root Cause

Three layers all had the same bug:

  1. Rendering: data-multiple attribute and ask-question-multiselect CSS class were never emitted for question blocks, so the UI had no way to distinguish multi-select from single-select.

  2. Click handling: chat-composer-runner.js used questionCount === 1 as the sole condition for immediate-send, without checking the multiSelect / data-multiple flag.

  3. Export renderer: The standalone export page (internal/ui/export/app/50-render-entry.js) had the same rendering omission.

Additionally, none of the renderers emitted a free-text input row, and there was no mechanism to detect free-text option labels.

Fix

Multi-select rendering (3 files)

  • web/src/session/render/session-entry-renderer.js
  • web/src/session/live/live-renderer.js
  • internal/ui/export/app/50-render-entry.js

Each now checks q.multiSelect === true alongside question count:

  • isMulti = questions.length > 1 || questions.some(q => q.multiSelect === true) (for card-level)
  • qMultiple = q.multiSelect === true (for per-question data-multiple attr)
  • Adds ask-question-multiselect class to multi-select option elements

Click handling (chat-composer-runner.js)

  • Condition for immediate-send changed from questionCount === 1 to questionCount === 1 && !qMultiple
  • Multi-select toggle: option.classList.toggle("selected")
  • Multi-select submit: collects all .selected options, joins with comma
  • Multi-select question blocks also get a "Send answers" button

Free-text input row (same 3 renderers + chat-composer-runner)

  • Single-select: always shows a text input at the bottom of options
  • Multi-select: shows a text input when an option label matches free-text heuristics:
    • "Type something." (pi standard)
    • Labels containing "其他", "Other", "自定义", "Custom", "自行输入", "自由输入", "enter your"
  • Free-text option labels are hidden from the button list and rendered as a dashed-border <input> instead
  • Enter key in the freetext input submits the answer (single-select sends immediately; multi-select collects with other selected options)
  • data-freetext="true" attribute on question blocks that have a freetext input

Styling (session.css)

  • .ask-question-option.multiselect — dashed border, ☐/☑ indicators
  • .ask-question-freetext-input — dashed border, accent focus color

Tests

  • session-entry-renderer.test.js — 2 new test cases for data-multiple and ask-question-multiselect
  • live-renderer.test.js — 1 new test case for multiSelect rendering
  • chat-composer-runner.test.js — 4 new test cases for multi-select toggle, submit, single-select guard
  • ask_user_question_render_test.go — Go embedded asset test checks for data-multiple and ask-question-multiselect

Testing

  • All frontend tests pass
  • All Go tests pass
  • Manual browser verification: single-select shows freetext input, multi-select with "其他" shows freetext input, regular multi-select shows Submit button

Paul Qu added 9 commits May 30, 2026 17:38
…tion

- session-entry-renderer: isMulti now checks q.multiSelect, add data-multiple
  attribute and ask-question-multiselect class
- live-renderer: same qaMulti check, data-multiple attribute and multiselect class
- Both renderers show Submit button for single-question multiSelect cards
- Added tests for data-multiple, multiselect class, and submit button visibility
- Dashed border for multiselect options
- Checkbox indicators: ☑ for selected, ☐ for unselected
…rQuestion

- Click handler: single question + multiSelect now toggles selection
  instead of sending immediately
- Submit handler: multiSelect blocks collect all selected answers
  joined with commas
- Added tests for toggle behavior and comma-separated submission
The export page has its own copy of the AskUserQuestion renderer in
export/app/50-render-entry.js. Apply the same multiSelect fixes:
- isMulti now checks q.multiSelect
- data-multiple attribute on question blocks
- ask-question-multiselect class on options
Detect free-text option labels heuristically: Type something, 其他/Other,
自定义/Custom, 自行输入/自由输入/Enter your. Single-select always shows
freetext input; multi-select shows it when a free-text option is detected.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant