|
|
@@ -99,11 +99,15 @@
|
|
|
:class="{ selected: isFreeformSelected(cardIdx) }">
|
|
|
<span class="qc-option-label">{{ getOtherOptionLabel(card) }}</span>
|
|
|
<div class="qc-option-content">
|
|
|
+ <!-- ⚠️ focus / click 都要接管:点一下输入框就等于"选了 A",
|
|
|
+ 否则点了输入框却不高亮、右边的 B 还一直亮着(用户 2026-09-24 反馈) -->
|
|
|
<textarea :ref="(el) => setFreeformRef(cardIdx, el)"
|
|
|
class="qc-freeform-input inline"
|
|
|
:placeholder="card.freeformPlaceholder || '请输入补充信息...'"
|
|
|
- v-model="freeformTexts[cardIdx]" rows="1" @focus="handleFreeformFocus"
|
|
|
- @blur="handleFreeformBlur" @click.stop></textarea>
|
|
|
+ v-model="freeformTexts[cardIdx]" rows="1"
|
|
|
+ @focus="handleAlwaysOnFreeformInteract(cardIdx)"
|
|
|
+ @click="handleAlwaysOnFreeformInteract(cardIdx)"
|
|
|
+ @blur="handleFreeformBlur"></textarea>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
@@ -427,25 +431,44 @@ const isCardFreeformAlwaysOn = (cardIdx: number): boolean =>
|
|
|
/**
|
|
|
* 自由输入那一行是否算"选中"(同时决定它的边框样式、以及答案是否算作出自输入框)。
|
|
|
*
|
|
|
- * ⚠️ 2026-09-24 修(用户报「一次应该只有一个选项是选中样式」):
|
|
|
- * 以前这里是 `常驻输入框 || 被点开` —— **常驻输入框恒为 true**,
|
|
|
- * 于是那一行永远带着选中边框,点旁边的选项也不会变。
|
|
|
- * 现在按"答案出自谁"判定:
|
|
|
- * · 常驻输入框(freeformInputOnTop):**填了内容**、且(单选时)**没有选中别的选项** → 才算选中
|
|
|
- * · 普通「其他」输入框:被点开就算选中(原行为不变)
|
|
|
+ * ⚠️ 2026-09-24 两次修正,别改回去:
|
|
|
+ * ① 最早写的是 `常驻输入框 || 被点开` —— **常驻输入框恒为 true**,那一行永远带选中边框;
|
|
|
+ * ② 改成"只有填了内容才算"又过头了:**点了输入框却没有高亮**,而且点了它右边的选项还亮着
|
|
|
+ * (用户反馈「左边可以输入,但是边框没有高亮;点击右边高亮后,再点左边右边依旧高亮」)。
|
|
|
+ * 现在:**被点/聚焦过(isFreeformActive)或填了内容**都算选中它;
|
|
|
+ * 单选卡片在 `handleAlwaysOnFreeformInteract` 里会把别的选项清掉,所以高亮仍然只跟一个走。
|
|
|
*/
|
|
|
const isFreeformSelected = (cardIdx: number): boolean => {
|
|
|
const card = questions.value[cardIdx];
|
|
|
if (!isCardFreeformAlwaysOn(cardIdx)) {
|
|
|
return !!isFreeformActive.value[cardIdx];
|
|
|
}
|
|
|
+ const chosenByInteraction = !!isFreeformActive.value[cardIdx];
|
|
|
const hasText = (freeformTexts.value[cardIdx] || '').trim().length > 0;
|
|
|
- if (!hasText) return false;
|
|
|
+ if (!chosenByInteraction && !hasText) return false;
|
|
|
if (card?.multiSelect) return true; // 多选:选项与自由输入可以同时成立
|
|
|
const selected = selectedOptions.value[cardIdx];
|
|
|
return !selected || selected.size === 0;
|
|
|
};
|
|
|
|
|
|
+/**
|
|
|
+ * 点/聚焦"常驻输入框"这一行 = 选了 A:
|
|
|
+ * · 记下"自由输入已激活"(高亮它)
|
|
|
+ * · **单选卡片顺手清掉已选选项** —— 这正是"一次只有一个选项是选中样式"
|
|
|
+ */
|
|
|
+const handleAlwaysOnFreeformInteract = (cardIdx: number) => {
|
|
|
+ if (submitted.value) return;
|
|
|
+ const card = questions.value[cardIdx];
|
|
|
+ if (!card) return;
|
|
|
+ if (!isFreeformActive.value[cardIdx]) {
|
|
|
+ isFreeformActive.value = { ...isFreeformActive.value, [cardIdx]: true };
|
|
|
+ }
|
|
|
+ if (!card.multiSelect && (selectedOptions.value[cardIdx]?.size || 0) > 0) {
|
|
|
+ selectedOptions.value = { ...selectedOptions.value, [cardIdx]: new Set() };
|
|
|
+ }
|
|
|
+ handleFreeformFocus();
|
|
|
+};
|
|
|
+
|
|
|
/** 自由输入是否算作"已作答":需已启用且确实填了内容 */
|
|
|
const hasFreeformAnswer = (cardIdx: number): boolean =>
|
|
|
isFreeformSelected(cardIdx) && (freeformTexts.value[cardIdx] || '').trim().length > 0;
|