并不简单的基础开发工作(三):信息录入表单

本文继续以“学生信息管理系统”为例,讲述信息录入表单设计与开发中的一些问题。

需求

前一篇文章所需功能的基础上,实现学生信息录入页面:

身份证号码:  上传照片
姓名:
性别:
民族:
户籍地址:
出生日期:
学院:
班级:
学号:
联系电话:
未来意向:
荣誉或奖励:
所受处分:

原理

当用户点击“保存”按钮时,浏览器会将表单输入内容发送给后台,后台接收到数据(通常由框架实现)之后,需要进行一些校验,校验通过后,将输入内容INSERT到数据库中。

除了新增内容,用户有时需要对现有内容进行修改。这时候需要由列表页面向表单页面传入现有内容的id。表单页面加载之前,需根据此id去数据库读取记录,并将数据库内容展示到用户页面中。当用户点击保存时,除了页面输入内容,此id也要传到后台,这样后台才能得知用户是修改已有记录并执行UPDATE操作,而不是增加新记录。

设计方面的问题

自由输入

能做成选择题的地方就不要做成填空题!

如果把可以做成选择题的地方做成填空题,让用户自由输入,会难以规范输入内容,给后续统计、分析等工作带来麻烦。例如填写地址,同样是山东莱芜(莱芜已并入山东省会济南),用户可以填成:

  • 莱芜
  • 莱芜市
  • 山东莱芜
  • 山东省莱芜市
  • 山东莱芜市
  • 山东省莱芜
  • 山东省济南市莱芜区
  • 山东省济南市来无区(不小心打错字了)
  • 山东省济南市莱城区(写成了旧地名,还写错了)
  • 济南市莱芜区
  • 山东 莱芜
  • 山東省濟南市萊蕪區(忘把繁体字开关关掉了)
  • ……

页面布局

录入表单是一件令人不爽的事情,操作时间长了,很容易陷入疲劳。

如果页面摆放凌乱,该对齐的地方不对齐,字体、字号、间距不一致,用户肯定感到不爽。就算有对齐,各页面风格不一致(甚至同一页面内部风格就不一致)也会让人迷惑。

如果需要录入的字段很多,页面应适当分组,让用户有“喘气”的时间,例如:

基本信息
身份证号码:
姓名:
性别:
...
学籍信息
学院:
班级:
学号:
...
学生个人发展信息
未来意向:
...

或者

1 基本信息 → 2 学籍信息 → 3 学生发展情况
身份证号码:
姓名:
...
 下一步

选填与必填

如果页面既有必填项,也有选填项,应明确告知用户,这样用户就能及时把必填项填好。如果用户点提交按钮的时候才知道页面开头有个东西是必填项,而且需要自己翻到页面开头把东西填好,心情一定会非常差。

区分必填和选填也有一些技巧,例如:

  • 全部为必填项时,不需要特意告知用户字段必填。可以用校验代替。
  • 必填项比选填项多时,选填项提示(选填)
  • 选填项比必填项多时,必填项提示(*)
  • 全部是选填项时,需要在业务层面考虑一下必要性。如果确实需要,在页面顶部显眼位置给出提示。

排布字段时,尽量把必填项放前面,选填项放后面。

不必要的字段

尽量减少字段数量。如果字段在业务上没有意义,而技术上又是必需的(例如id、数据有效性等),那么不要暴露给用户,放到后台处理。

常用字段可以提供默认值,例如“民族”默认值可以设置成“汉族”(通常是汉族人多——如果不是民族学校的话)。能自动填写的字段也尽量做成自动填写,例如自动带出历史数据,或者在填好“身份证号”之后,由系统自动填写“生日”和“性别”。

提示信息

提示信息应该简单、明确,并且措辞要考虑实际业务场景,避免产生歧义。举一些不好的例子:

  • 请输入姓名(必填):[ ](啰嗦,姓名(*):就够了)
  • 电话号(格式:xxx-xxxxxxx):[ ](应当用input标签的placeholder代替)
  • 类型:[ ](“类型”、“情况”等词语语意含糊,容易产生歧义,除非业务本身就这么叫)

对于用户容易犯错误的地方:

  • 如果能由程序“消化”,例如输入数据包含空格,那么默默地“消化”即可。
  • 否则给加个显眼的提示,例如提示“2019级”和“2019届”的区别。

“表单填写注意事项”要放在醒目位置,用醒目的样式书写,以便引起用户重视。许多人经常不在乎注意事项,所以行文更要挑重点,避免占篇幅。值得注意但能让用户在填写时顺便留意的事情可以交给校验处理。

“下一个”

需要考虑一下业务场景:在实际操作时,用户需要录入的数据多吗?

如果数据量比较多,那么建议给用户加个“下一个”按钮,录完一个就直接进下一个(当然别忘了把数据给保存好),节约时间。数量越多,节约效果越好。

实现方面的问题

权限问题

在读取数据和保存数据时应对用户权限进行验证,防止读取或修改无权操作的记录。

假如编辑的URL是http://127.0.0.1:8080/student/edit/3,而数据库id=2的记录是其他人录入的,我们无权操作,那么在浏览器输入http://127.0.0.1:8080/student/edit/2之后就不应该把数据库里的数据查出来,否则就是一个严重的安全漏洞。

重复提交问题

开发环境的网络往往非常好,点完按钮就能跳转到操作成功的页面。但是,用户的网络不一定非常好,他们可能急于操作,担心系统保存不上而反复点击提交按钮,这样会产生多条提交的请求,系统可能也会产生多条相同记录。

这类问题有两种解决方法:

一种是在表单中设置隐藏的token,每次进入表单都生成不同的token。一旦重复提交,系统会发现token已经无效而拒绝进一步操作。有一种常见的Web攻击方式是跨站请求伪造攻击(CSRF),Web框架通常会提供基于token的解决方案,顺便就把重复提交问题给解决了。

还有一种简单粗暴却很有效果的方法:点击提交按钮之后,相关按钮立刻变灰,不允许用户点击,并且由页面给出“正在保存”的反馈信息,使用户能够耐心等待表单提交。当然,一旦保存失败,不要忘记让按钮变回原来可以点击的状态。

校验问题

前台校验是不可信任的:如果只在前台进行校验,未在后台进行校验,那么用户就可以先进入浏览器控制台,再输入document.forms[0].submit()来绕过各类校验。出于安全考虑,即使赶工或偷懒,也要先把后台校验给做好。

校验失败的错误提示不要含糊不清,不要只告诉用户“输入内容有误”,而是要告诉用户“手机号格式错误、学号格式错误”。除此之外,报错要避免像挤牙膏一样一次只提示一种错误,尽量一口气把所有错误都告诉用户,否则用户改了好几遍还提交不上去,心情就是崩溃的了。

另外,各表单校验风格应当统一:A页面将所有错误用一个弹窗提示出来,而B页面将每个错误字段的提示信息都放在对应字段右边,这样也会让用户困扰。

为了规避这些问题,建议使用(或自行实现专门的)校验框架来实现校验,既能统一行为,又能简化代码,让后续调整也变得方便些。

没有反馈

用户提交完成后,系统不要什么反馈都没有,否则用户容易认为系统有故障。系统要给用户一个明显的信号,例如提示“提交成功”,或者直接进入下一步操作页面。即使又回到了输入页面,也不要让用户输入数据发生变化甚至消失。

本系列目录

  1. 登录页面
  2. 信息展示列表
  3. 信息录入表单
  4. 业务申办-审批流程