ExpressionScript 示例调查
From LimeSurvey Manual
简介
学习使用 ExpressionScript 的最佳方式,是试用可运行的示例,并根据您的需求对其进行修改。
下面提供了一组示例调查,用于演示(和测试)如何使用 EM 来增强您的调查。这些调查可以在发行包的 /docs/demosurveys 文件夹中找到。
关联、定制和方程式
概览
以下示例会计算每位受访者的 BMI(体重指数)。下面列出了此示例所演示的功能。
演示的 EM 功能
- 关联 - 支持强大的条件逻辑;
- 管道 / 定制 - 可以对答案和问题元数据进行管道传递或定制;
- 动态定制 - 请注意,当您回答问题时,页面上的报告会随之变化。
- 微定制 - 使用 if() 语句在句子和报告中进行条件定制
- 方程式 - 一种新的问题类型,可让您进行计算并将结果存储在数据库中,即使该计算是隐藏的
- 条件验证 - 验证条件(例如允许的最小值)可以是有条件的,例如基于方程式。
截图
此示例计算体重指数(BMI),即根据您的体重和身高来判断您属于体重过轻、正常、超重还是肥胖。请注意,最初您只会看到四个必答问题:

输入您的信息后(您可以选择使用公制还是非公制单位),您会看到一份定制的报告,其中总结了您输入的内容,并告知您的体重状态:

下面是另一个示例,使用非公制单位来展示结果如何动态变化:

内部有隐藏的方程式类型问题,用于将数据转换为公制(如有需要),并将公制的身高、体重、BMI 和体重状态存储到数据库中,无需自定义 JavaScript。
在接下来的一组示例中,您可以看到如何在定制报告中使用数学函数及其他函数。这是在您输入任何数据之前页面的样子。系统使用了条件逻辑:如果未输入数据(或输入的不是数字),则显示空白单元格,而不是显示“NaN”或“Divide by Zero”。

输入数字时,页面上的报告会随之变化,显示正在执行的计算及其结果。

此示例调查中还有许多其他示例。例如,下面的截图展示了填写“动态关联”页面的数十种方式之一。正如帮助文本所述,请尝试不同的年龄,尤其是不合逻辑的回答组合,以查看底部生成的有趣消息。另请注意,如果您说自己有不止一个孩子,消息将显示“I hope you enjoy playing with your X children”,而不是“I hope you enjoy playing with your child”。这展示了您如何轻松地对句子进行微定制,使其与受访者的性别和/或数量相匹配。您甚至可以根据性别和数量轻松地进行动词变位和名词变格。

下载
要获取该示例调查,请点击以下链接:LS3_em_tailoring.zip。
人口普查示例
概览
这是一个人口普查示例,询问您的家庭中有多少人。
它演示了组级别的关联如何使实现问题“循环”变得更容易。创建“Person 1”的组之后,我导出了该组。由于我使用的是 p1_name 这样的 qcode 变量名,而不是 SGQA 代码,因此可以使用文本编辑器快速编辑并多次重新导入该组(例如,编辑并重新导入每个重复的组大约只需 10 秒,同时确保所有变量都具有唯一的变量名,且组级别的逻辑正确无误)。
您也可以使用复制问题功能,但速度不如上述方法快。
此示例还演示了如何在调查真正完成之前(例如,在所有必要的组都已完成之前)阻止显示“已完成”消息。
演示的 EM 功能
- 组级相关性 - 后续组(Person 1-5)仅在指定的同住人数范围内显示;
- 定制 - 最终报告汇总每位同住人的人口统计数据;
- 渐进式问题显示 - 无论是分组模式还是全部在一页模式,只有在回答完前面的问题后,才会显示后续问题。
截图
该调查会生成一份定制报告,显示指定数量同住人的人口统计信息:

如果切换到逐题模式,您会看到索引会对问题进行定制。由于用户表示该人是女性,因此会询问“她叫什么名字”。而且由于我们回答了“Mary”,下一个问题就会显示为“Mary 多大了”?

下载
要下载该调查示例,请点击此处:LS3_group_relevance.zip。
级联阵列筛选
概览
此调查基于 Joy Lane Research, LLC 提供的调查设计。
截图
请注意以下几点:
- Q02 仅显示在 Q01 中勾选的产品集合(通过使用 array_filter)
- Q02 还会显示“Another product”,即在 Q01 的“Other electronic”字段中输入的文本
- Q04 仅显示 Q02 中被勾选的产品(因此阵列筛选是级联的)
- Q05 仅显示在 Q02 中未被勾选的产品(使用级联的 array_filter_exclude)


下载
点击以下链接下载上述示例:LS2_cascading_array_filter 调查示例。
在所有问题类型和属性中使用管道/定制
概览
如果您对如何命名变量(SGQA 与 Qcode)感到困惑,您并不孤单。尽管主文档介绍了如何构成 Qcode 变量名,但没有什么比查看实际演示更直观。此调查展示了如何使用 ExpressionScript 访问问题属性和回答。
内容
- 每种问题类型的示例
- 包含所有可使用“其它”的问题类型,以便您了解其对变量命名的影响
- 所有接受默认值的问题类型的默认值
- 定制 - 页面内和页面外的报告,显示全部 16 种可用的 EM 点号表示法后缀。
- 这些报告会显示当前已输入的所有数据(因此可以向您展示如何为用户生成自己的可打印报告,以代替打印答案界面)
- 所有变量均采用正确的 Qcode 和 SGQA 命名
截图
这是一个非常庞大的调查,因此我们没有附上截图。请下载并亲自体验。
下载
点击以下链接下载该调查:LS3_EM_question_attributes.lss
传统验证的全新演绎
概览
本示例演示了所有使用表达式的验证类型,以及它们如何影响各个支持验证的问题类型。在许多情况下,验证提示一开始处于隐藏状态,只有当问题未通过验证条件时才会显示(问题通过验证条件后提示也会随之消失)。
演示的验证类型
- min_num_value_n - 答案的最小值
- max_num_value_n - 答案的最大值
- min_answers - 所需答案的最少数量
- max_answers - 允许的答案最大数量
- multiflexible_min - 答案允许的最小值(适用于多重弹性数字问题类型)
- multiflexible_max - 答案允许的最大值(适用于多重弹性数字问题类型)
- min_num_value - 该问题所有答案之和允许的最小值
- max_num_value - 该问题所有答案之和允许的最大值
- equals_num_value - 该问题所有答案之和必须等于此值
- validation - 这是针对该问题的正规表达式验证,可应用于单个单元格
屏幕截图
通过使用新的 CSS 样式,每种验证类型都会显示单独的提示。如果这些提示已显示,可以通过 hide_tip 选项将其隐藏。默认设置是:如果问题未通过验证条件,则以红色字体显示;如果通过,则以绿色显示:

用户无法提交存在验证错误的页面。如果输入了错误的信息,系统会立即向用户发出警告:

验证可以应用于阵列中的单个单元格。例如在本示例中,正规表达式验证可确保每个输入项都是格式正确的美国电话号码(包括区号)。

下载
要下载上述示例,请点击以下链接:LS3_Validation_tests.zip。
验证方程式
概览
有时您需要自定义验证,而这无法通过传统的最小值/最大值条件来实现。为此,您需要使用 em_validation_q 和 em_validation_sq 选项,它们可让您分别在问题和子问题级别构建复杂的验证方程式。
演示的 EM 功能
- em_validation_q - 用于判断整个问题是否有效的方程式
- em_validation_q_tip - 当问题未通过 em_validation_q 条件时显示的消息
- em_validation_sq - 用于判断每个子问题(阵列单元格)是否有效的方程式
- em_validation_sq_tip - 当任一子问题无效时显示的消息。
通常,使用 em_validation_sq 时,如果任何单元格无效,该单元格的背景颜色会变为红色,以提示存在错误。
屏幕截图

此问题通过应用以下验证方程式,确保您按降序输入子女的年龄:
q1_sq1 >= q1_sq2 && q1_sq2 >= q1_sq3 && q1_sq3 >= q1_sq4

在下面的示例中,验证通过应用以下验证方程式,确保任意一行中最多只回答 3 个问题:
(sum(Test_A_1, Test_A_2, Test_A_3, Test_A_4, Test_A_5) <= 3) && (sum(Test_B_1, Test_B_2, Test_B_3, Test_B_4, Test_B_5) <= 3) && (sum(Test_C_1, Test_C_2, Test_C_3, Test_C_4, Test_C_5) <= 3)
您也可以按如下方式编写,LimeSurvey 会在运行时自动将其转换为上述表达式。
(sum(self.sq_A) <= 3) && (sum(self.sq_B) <= 3) && (sum(self.sq_C) <= 3)

下载
要下载上述示例中使用的调查样本,请点击以下链接:ls2_test_em_sq_validation.lss。
子问题相关性
概览
本示例展示 array_filter 与验证条件如何相互作用。对于适用于求和的验证,仅考虑相关(可见)的值。
演示的 EM 功能
它还展示了对核心问题中已回答问题数量的动态报告。
截图
更改可见行数会动态改变总和。将子问题标记为不相关并不会清除其值。相反,如果某个子问题不相关,其值不会计入任何公式。


请注意,当我们在第一个问题“下方应显示哪些行”中勾选“第五个子问题”时会发生什么。请注意,第二个问题“输入一些数字”的总和现在是 5。尽管该问题的子问题 5 仍然保留值 14(例如,如果您取消勾选第五个子问题,就会再次看到值 14),但由于该值当前不相关,因此不会计入总和。所有不相关的数据在提交时都会被清除(在数据库中设为 NULL),但它们仍保留在页面上,以便用户想要或需要改变答案时使用。

下载
要下载我们的示例,请点击此处:ls2_subquestion_relevance.lss。
使用逗号作为基数分隔符(小数点)
概览
ExpressionScript 可确保数字字段中只能输入有效的数字。如果您输入了无效的数字,系统会提醒您有错误(例如,在 fruity 主题中,整个问题会变成红色)。
请注意,数值在数据库中始终会被转换为以句点作为基数分隔符的形式。这样,统计分析才能正常进行。
要更改基数分隔符,请访问位于设置选项卡下的文字元素选项,并找到十进制标记功能。
使用基数分隔符的问题类型
- 数字输入 [N]
- 多数字输入 [K]
- 阵列(数字) [:]
- 阵列 (文本) [;],使用 numbers_only 属性时
- 列表(单选) [L],使用 other_numbers_only 属性时
- 短自由文本 [S],使用 numbers_only 属性时
- 多短文本 [Q],使用 numbers_only 属性时
- 多选题 [M],使用 other_numbers_only 属性时
- 带评论的多选题 [P],使用 other_numbers_only 属性时
截图
您可以在下面的截图中看到,逗号可以用作基数分隔符。

下载
要下载上述示例,请点击以下链接:ls2_comma_as_radix_separator.lss。
随机分组
概览
本调查演示如何使用 random_group 属性。
如果使用此属性,每次启动调查时,问题顺序都会被随机化。但是,调查一旦启动,随机顺序就会保持固定,即使您切换语言也不会改变。
截图
让我们一起来看下面的示例。页面上的第一个随机问题将是 Q1、Q4 或 Q7。页面上的第二个随机问题将是 Q2、Q5 或 Q8。

这是我第一次测试此调查时生成的随机顺序。

第二次测试该调查时,生成了不同的随机顺序。

但是,当我切换到法语时(没有重新启动调查),随机顺序保持不变。

下载
要下载上述示例,请点击以下链接:Randomization_Group_Test.lss
每组随机提问一个问题
概览
本调查演示如何将调查配置为每个组随机显示一个问题。其中有 5 个组,每组 6 个问题。一开始,在第 0 组中,有五个隐藏的方程式问题,名为 ask1-ask5。每个问题的问题文本字段中的值均为 {floor(rand(1,6.9999))},这意味着变量 ask1-ask5 的值都介于 1 到 6 之间。然后,组内的每个问题都有一个类似 "ask1==N" 的相关表达式,其中 N 是该问题在组内的序号(因此第 1 组中的第三个问题的相关表达式为 "ask1==3")。
本调查在整个调查一页显示、按组分页和逐题显示模式下都同样适用。由于随机化是在第一个组中设置的,并且该组实际上是隐藏的(因为所有 ask1-ask5 问题都是隐藏的),因此对同一受访者而言随机结果保持不变;但每位不同的受访者都会有不同的随机结果。
演示的功能
- 方程式问题类型
- 随机化函数
- 条件(if)函数
截图
这是第 0 组,它使用方程式问题类型为每个组选择 1 到 6 之间的随机值(最后一个组除外,该组只有 4 个问题)。请注意,"if()" 函数首先检查 ask1 是否已被设置,如果已设置,则使用该值;如果尚未设置,则使用随机值来设置 ask1 的值。

此组演示了如何使用第 0 组中的变量 (ask4) 来控制第四组中显示哪个问题。

下载
要下载上述调查示例,请点击此处:组内随机问题调查示例。
在组内随机提问指定数量的问题(问题的子集)
概览
此调查演示如何在一个组中随机显示部分问题。例如,在一个组内的 10 个问题中随机显示 5 个问题。
该调查包含一个组,组内有 10 个问题。所有问题都被分配了相同的随机题组名称,因此页面加载时它们将以随机顺序显示。每个问题都设置了一个相关表达式:组内所有其他问题的“relevanceStatus”之和小于您希望显示的问题数量。由于 relevanceStatus 是在问题渲染时赋值的,因此这实际上是对之前已显示问题的数量进行累计。
因此,在我们“10 选 5”的示例中,Q1 的表达式为:
sum(Q2.relevanceStatus, Q3.relevanceStatus, Q4.relevanceStatus, Q5.relevanceStatus, Q6.relevanceStatus, Q7.relevanceStatus, Q8.relevanceStatus, Q9.relevanceStatus, Q10.relevanceStatus) LT 5
Q2 的表达式为:
sum(Q1.relevanceStatus, Q3.relevanceStatus, Q4.relevanceStatus, Q5.relevanceStatus, Q6.relevanceStatus, Q7.relevanceStatus, Q8.relevanceStatus, Q9.relevanceStatus, Q10.relevanceStatus) LT 5
依此类推……
演示的功能
下载
要下载上述示例,请点击以下链接:10 选 5 随机调查示例。
对用户输入的产品列表进行评分
概览
下面的示例演示如何让用户列出他们感兴趣的一组产品,然后对这些产品进行评分。
演示的 ES 功能
- 定制答案 - 在对产品评分时,标签来自前一个多选题的评论字段
- 定制尺度 - 许多高级问题选项(如尺度标题)同样可以进行定制。
截图
此图显示,由于只选择了产品 1、3 和 5,因此仅显示这 3 个产品(使用 array_filter 属性)。此外,第二个问题中的行标签要么是产品编号(如果评论字段中未输入任何内容),要么是评论字段的内容。

此图显示了如何指定定制答案:

下面是该问题的“显示逻辑文件”,通过它我们可以验证条件逻辑是否按预期工作(例如,检查是否存在语法错误):

下图显示了一个组,您可以在其中指定 5 分评分尺度(选项 1-5)、尺度标题以及要评分的产品。最后一个问题表明,阵列问题的每个部分都可以进行定制:

下图显示了最后一个问题的逻辑文件视图。如您所见,子问题、答案和尺度标题都可以进行定制。

下载
要下载上述调查示例,请点击以下链接:对用户输入的产品列表进行评分的调查示例。