# 研究项目登记 · 动态表单示例

这是为 Frontend & Data Lab **新建的教学示例**，用原生 HTML、CSS 和 JavaScript 展示分步表单设计。它不连接真实研究管理系统，不代表过往已上线项目，也不向服务器提交内容。

直接用浏览器打开 [index.html](index.html) 即可，包括 `file://` 方式；无构建步骤、第三方运行依赖、远程字体或网络请求。页面采用暖白与墨绿配色，支持手机、键盘操作和减少动画设置。

## 交互流程

1. **定义项目**：填写名称，选择研究方向。
2. **规划研究**：描述问题，选择数据来源和预期产出。选择公开或本地数据时，显示必填的数据准备说明。
3. **确认内容**：检查摘要，分别返回修改；确认后只在本页完成演示。
4. **完成**：清除草稿，可导出本机 JSON 文件或重新填写。

不收集姓名、邮箱或联系方式。所有用户输入通过 `textContent` 或表单控件的 `value` 呈现，不作为 HTML 插入页面。

## 代码结构

| 文件 | 职责 |
| --- | --- |
| [form-core.js](form-core.js) | 字段配置、条件字段、校验、显式状态转换和草稿编解码；纯逻辑供浏览器和 Node 共用 |
| [app.js](app.js) | 安全 DOM 渲染、焦点管理、本地存储、下载交互 |
| [styles.css](styles.css) | 响应式排版、状态样式、减少动画支持 |
| [form-core.test.cjs](form-core.test.cjs) | Node 内置测试，无需安装包 |

状态为 `basics → plan → review → complete`。仅配置的动作可以转换状态；每次前进先校验，完成时重新校验全部字段。用户可返回上一步；确认页提供分区修改；完成状态仅允许重新开始。

## 草稿规则

- 存储键：`frontend-data-lab.research-form.v1`；内容包含版本、保存时间、当前步骤与字段值。
- 输入后延迟 350 毫秒保存；步骤切换和离开页面时同步保存。恢复时检查版本、字段类型、选项和长度，进度不能跳过未完成步骤。
- 损坏草稿恢复为空白表单并提示；未知版本不会解释为当前格式。开始填写新内容会保存当前版本草稿。
- “清除草稿”要求一次页面内确认，同时清空本次表单。完成登记也会清除草稿。
- 浏览器禁用或限制 `localStorage` 时，以内存继续完成流程和导出；刷新后无法恢复。`file://` 的存储隔离行为因浏览器而异。

## 检查

从本目录运行（Node.js 18+）：

```sh
node --test form-core.test.cjs
node --check app.js
node --check form-core.js
```

测试覆盖非法状态转换、逐步校验、条件必填、最终复核、草稿版本和损坏恢复、恢复进度约束、输入作为文本保留。测试使用合成输入，不访问网络，也不写入真实项目数据。

可手动检查：空表单前进提示、切换数据来源、返回修改、刷新恢复、清除取消/确认、完成后导出，以及移动端键盘导航。已有保存输出不是本示例的研究结果；导出的 JSON 仅表示用户在本机填写的登记内容。
