You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在SurveyJS中根据前置问题答案设置Matrix Dynamic组件的固定行数

如何在SurveyJS中根据前置问题答案设置Matrix Dynamic组件的固定行数

我完全理解你的需求:希望用户先输入班级数量,再自动生成对应行数的矩阵表单,且不允许用户随意添加或删除行——这和Kobo Toolbox里按家庭成员数量生成行的逻辑完全一致。你直接用{num_classrooms}绑定属性的方式行不通,是因为SurveyJS的rowCountminRowCount这类属性默认不会自动解析占位符,需要通过事件监听或者表达式绑定的方式来动态更新。

下面是两种可行的解决方案,其中事件监听的方式最直接且易维护:


方案一:通过onValueChanged事件动态更新行数

这是通用的实现方式,适用于所有SurveyJS运行环境(浏览器、React、Vue等)。核心思路是监听前置问题(num_classrooms)的值变化,实时同步更新矩阵的行数配置。

完整代码示例

<!-- 渲染Survey的页面容器 -->
<div id="surveyContainer"></div>

<script type="text/javascript">
const surveyJson = {
  "elements": [
    {
      "type": "text",
      "name": "num_classrooms",
      "inputType": "number",
      "min": 1,
      "max": 20,
      "title": "How many classrooms do you teach in this school?",
      "isRequired": true
    },
    {
      "type": "matrixdynamic",
      "name": "familyMatrix",
      "title": "Classroom Information",
      "columns": [
        {
          "name": "name",
          "title": "Name",
          "cellType": "text"
        },
        {
          "name": "age",
          "title": "Age",
          "cellType": "number"
        }
      ],
      // 初始设为0,后续通过事件动态更新
      "rowCount": 0,
      "minRowCount": 0,
      "maxRowCount": 0
    }
  ]
};

// 创建Survey实例
const survey = new Survey.Model(surveyJson);

// 监听问题值变化事件
survey.onValueChanged.add((sender, options) => {
  // 仅当变化的是班级数量问题时触发逻辑
  if (options.question.name === "num_classrooms") {
    // 将用户输入的字符串转为整数,避免非数字值导致错误
    const classCount = parseInt(options.value, 10);
    // 获取矩阵问题的实例
    const matrixQuestion = sender.getQuestionByName("familyMatrix");
    
    if (matrixQuestion && !isNaN(classCount) && classCount > 0) {
      // 统一设置行数配置,确保用户无法添加/删除行
      matrixQuestion.rowCount = classCount;
      matrixQuestion.minRowCount = classCount;
      matrixQuestion.maxRowCount = classCount;
      // 刷新矩阵组件,让行数变化立即生效
      matrixQuestion.render();
    }
  }
});

// 将Survey渲染到页面容器中
survey.render("surveyContainer");
</script>

代码逻辑说明

  1. 事件监听:通过survey.onValueChanged捕获班级数量问题的数值变化;
  2. 类型校验:把用户输入的字符串转为整数,过滤非数字输入的异常情况;
  3. 锁定行数:将矩阵的rowCountminRowCountmaxRowCount设为同一个值,彻底禁用行的增减操作;
  4. 即时刷新:调用render()方法确保行数变化立刻在页面上显示。

方案二:使用SurveyJS表达式绑定(进阶配置方式)

如果你更倾向于通过配置而非代码事件实现,可以利用SurveyJS的表达式功能。部分属性需要通过Expression后缀来启用动态绑定(不同版本的SurveyJS可能略有差异):

修改surveyJson中矩阵部分的配置:

{
  "type": "matrixdynamic",
  "name": "familyMatrix",
  "title": "Classroom Information",
  "columns": [/* 你的列配置保持不变 */],
  // 用表达式绑定行数
  "rowCountExpression": "{num_classrooms}",
  "minRowCountExpression": "{num_classrooms}",
  "maxRowCountExpression": "{num_classrooms}",
  // 禁用行增减按钮(可选)
  "allowAddRows": false,
  "allowRemoveRows": false
}

注意事项

  • 并非所有SurveyJS版本都支持rowCountExpression这类属性,建议先在你的项目版本中测试;
  • 表达式使用SurveyJS原生语法,{num_classrooms}会自动解析为对应问题的数值;
  • 搭配allowAddRowsallowRemoveRowsfalse,可以完全锁定行的数量,避免用户误操作。

最终效果验证

两种方案都能实现你想要的流程:

  1. 用户首先输入1-20之间的班级数量;
  2. 输入完成后,矩阵自动生成对应数量的行;
  3. 用户只能逐行填写班级信息,无法修改行的数量,流程清晰直观。

这个实现完美匹配你提到的Kobo Toolbox式用户体验,先确定数量再填写详情,避免了用户操作的混乱。

内容来源于stack exchange

火山引擎 最新活动