持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第1天
线上文档:surveyjs.io
surveyjs 问卷创建
<template>
<div class="surveyCreator_box">
<a-button class="button_class" type="primary" @click="router.go(-1)">返回</a-button>
<div id="surveyCreator"></div>
</div>
</template>
<script setup>
import { onMounted } from 'vue';
import 'survey-core/defaultV2.min.css';
import 'survey-core/survey.i18n';
import 'survey-creator-core/survey-creator-core.i18n';
import 'survey-creator-core/survey-creator-core.min.css';
import { SurveyCreator } from 'survey-creator-knockout';
import { localization } from 'survey-creator-core';
import { surveyLocalization } from 'survey-core';
import { useMessage } from '/@/hooks/web/useMessage';
import { useRouter } from 'vue-router';
const router = useRouter();
// 自定义属性按钮
// Serializer.addProperty('radiogroup', {
// name: 'radioValue',
// type: 'itemvalues',
// // default: 0,
// choices: [
// { value: '3', text: '选项- 1' },
// { value: '2', text: '选项- 2' },
// { value: '1', text: '选项- 3' },
// ],
// category: 'choices',
// });
surveyLocalization.supportedLocales = ['zh-cn', 'en'];
surveyLocalization.defaultLocale = 'zh-cn';
// surveyLocalization.getProperty('radiogroup', '');
localization.currentLocale = 'zh-cn';
const translations = localization.getLocale('zh-cn');
translations.ed.survey = '问卷';
translations.pe.tabs.general = '常规';
translations.pe.tabs.logo = '问卷标题 Logo';
translations.pe.tabs.pages = '分页页面';
translations.pe.tabs.logic = '逻辑';
translations.pe.tabs.data = '数据';
translations.pe.tabs.validation = '校验';
translations.pe.tabs.layout = '布局';
translations.qt.image = '图片';
translations.qt.ranking = '排序';
translations.qt.signaturepad = '签名';
// const obj = router.currentRoute.value.query.obj;
let obj = window.localStorage.getItem('question_data');
console.log(obj);
let question_text = {};
question_text = JSON.parse(obj);
onMounted(() => {
document.documentElement.style.setProperty('--primary', '#6793ff');
const creator = new SurveyCreator({
showLogicTab: true,
isAutoSave: false,
questionTypes: ['radiogroup'],
haveCommercialLicense: true,
});
// let blackList = ['visible', 'isRequired'];
// creator.onShowingProperty.add(function (_, options) {
// if (options.obj.getType() == 'panel') {
// // Hide properties found in `blackList`
// options.canShow = blackList.indexOf(options.property.name) < 0;
// // Hide all properties except those found in `whiteList`
// // options.canShow = whiteList.indexOf(options.property.name) > -1;
// }
// });
const { createMessage } = useMessage();
if (question_text.isUpdate === 'true') {
// console.log(question_text.question_data);
if (Object.keys(question_text.question_data).length === 0) {
return createMessage.error('问卷为空');
}
// 回显问卷
creator.text = JSON.stringify(question_text.question_data);
}
// 保存问卷
creator.saveSurveyFunc = (saveNo, callback) => {
if (creator.text == '{}') {
return createMessage.error('问卷不得为空');
}
if (question_text.isUpdate === 'true') {
createMessage.success('问卷编辑成功~');
} else if (question_text.isUpdate === 'false') {
createMessage.success('问卷新建成功~');
} else {
createMessage.warning('问卷状态不明,请重试~');
}
router.go(-1);
callback(saveNo, true);
};
creator.render('surveyCreator');
});
</script>
<style lang="less" scoped>
.surveyCreator_box {
width: 100%;
height: 100%;
padding: 15px 0px 15px 15px;
// background-color: #fff;
.button_class {
margin-left: 93.5%;
// margin-top: 10px;
margin-bottom: 10px;
}
#surveyCreator {
width: 100%;
height: calc(100vh - 115px);
}
}
</style>
surveyjs 问卷回答
<html lang="en">
<head>
<title>问卷填答</title>
<meta name="viewport" charset="UTF-8" content="width=device-width"/>
<script src="./components/knockout-latest.js"></script>
<script src="./components/survey.core.min.js"></script>
<script src="./components/survey.i18n.min.js"></script>
<script src="./components/survey-knockout-ui.js"></script>
<link href="./components/defaultV2.min.css" type="text/css" rel="stylesheet"/>
</head>
<style>
.sd-completedpage{
background-color: #fbfbfd;
/* background-image: url(../../src/assets/xxxxx.png);
background-position: left;
background-size: 100% 100%; */
}
/* .heard_box{
color: #fff;
} */
.answer_class{
margin: 0 auto;
width: 100%;
display: block;
text-align: left;
/* background-color: rgb(38, 25, 25); */
display: flex;
justify-content: center;
align-items:center;
flex-direction: column;
}
.answer_class_label{
font-size: 16px;
font-weight: 600;
line-height: 2;
width: 100%;
}
.answer_class_value{
font-size: 14px;
font-weight: normal;
}
/* form {
margin: 0;
} */
.surveyResult{
/* width: 100%; */
/* height: calc(100vh - 165px); */
display: block;
/* background-image: url(../../src/assets/images/Graphs-Graph\ Sidebar.png);
background-position: left;
background-size: 100% 100%; */
padding: 0 10px;
}
.sd-container-modern{
width: 100vw;
margin: 0;
padding: 0;
}
</style>
<body style="margin: 0; width: 100vw; height: 100vh">
<div id="surveyElement" style="display:inline-block;width:100%;"></div>
<div id="surveyResult"></div>
<script type="text/javascript" src="./surveyQuestion.js"></script>
</body>
</html>
Survey.locale = 'zh-cn'
Survey.StylesManager.applyTheme("defaultV2");
var json = {
"logoPosition": "right",
"title": "测试问卷名称",
"description": "测试问卷问卷描述文本",
"completedHtml": "<h3 class='heard_box'>填答完毕,感谢您的参与!</h3>",
"pages": [
{
"name": "页面1",
"title": "页面名称1",
"description": "页面1说明",
"elements": [
{
"type": "radiogroup",
"name": "页面1-问题1",
"choices": [
{
"value": "opt-1:10",
"text": "选项1"
},
{
"value": "opt-2:5",
"text": "选项2"
},
{
"value": "opt-3:5",
"text": "选项3"
}
]
},
{
"type": "radiogroup",
"name": "页面1-问题2",
"choices": [
{
"value": "opt-1:10",
"text": "选项1"
},
{
"value": "opt-2:7",
"text": "选项2"
},
{
"value": "opt-3:3",
"text": "选项3"
}
]
}
]
},
{
"name": "页面2",
"title": "页面名称2",
"description": "页面2说明",
"elements": [
{
"type": "radiogroup",
"name": "页面2-问题1",
"choices": [
{
"value": "opt-1:100",
"text": "选项1"
},
{
"value": "opt-2:50",
"text": "选项2"
},
{
"value": "opt-3:50",
"text": "选项3"
}
]
},
{
"type": "radiogroup",
"name": "页面2-问题2",
"choices": [
{
"value": "opt-1:80",
"text": "选项1"
},
{
"value": "opt-2:60",
"text": "选项2"
},
{
"value": "opt-3:30",
"text": "选项3"
}
]
}
]
}
],
"pagePrevText": "上页",
"pageNextText": "下页",
"completeText": "提交"
}
window.survey = new Survey.Model(json);
// localization.currentLocale = 'zh-cn';
survey.onComplete.add(function (sender) {
console.log('答案');
console.log(sender.data);
// let a = {
// 问题1: 'opt-1:10',
// 问题2: 'opt-2:7',
// };
let b = [];
for (const k in sender.data) {
if (sender.data[k]) {
b.push(+sender.data[k].split(':')[1]);
}
}
let num = b.reduce((a, b) => a + b)
let htmlText = `
<span class="answer_class">
<span class="answer_class_label">
您的回答:
<span class="answer_class_value"> ${JSON.stringify(sender.data, null, 3)} </span>
</span>
<span class="answer_class_label">
您的得分:
<span class="answer_class_value"> ${num}分 </span> </span>
</span>
</span>
`
document.querySelector('#surveyResult').className = 'surveyResult'
document.querySelector('#surveyResult').innerHTML = htmlText
});
var storageName = "question_data_value";
var timerId = 0;
function loadState(survey) {
// Here should be the code to load the data from your database
var storageSt = window.localStorage.getItem(storageName) || "";
var res = {};
if (storageSt)
res = JSON.parse(storageSt);
// Set the loaded data into the survey.
if (res.currentPageNo)
survey.currentPageNo = res.currentPageNo;
if (res.data)
survey.data = res.data;
}
function saveState(survey) {
var res = {
currentPageNo: survey.currentPageNo,
data: survey.data
};
// Here should be the code to save the data into your database
window.localStorage.setItem(storageName, JSON.stringify(res));
}
survey.onCurrentPageChanged.add(function (survey, options) {
saveState(survey);
});
survey.onComplete.add(function (sender, options) {
// kill the timer
clearInterval(timerId);
// save the data on survey complete. You may call another function to store the final results
saveState(sender);
});
// Load the initial state
loadState(survey);
// save the data every 10 seconds, it is a good idea to change it to 30-60 seconds or more.
timerId = window.setInterval(function () {
saveState(survey);
}, 10000);
survey.render("surveyElement");
surveyjs 问卷分析
<template>
<div class="analysis">
<a-button class="btn" type="primary" @click="$router.go(-1)">返回</a-button>
<div id="surveyVizPanel" />
</div>
</template>
<script>
import 'survey-analytics/survey.analytics.min.css';
import { Model } from 'survey-core';
import { VisualizationPanel } from 'survey-analytics';
const surveyJson = {
pages: [
{
name: '页面1',
title: '页面名称1',
description: '页面1说明',
elements: [
{
type: 'radiogroup',
name: '页面1-问题1',
choices: [
{
value: 'opt-1:10',
text: '选项1',
},
{
value: 'opt-2:5',
text: '选项2',
},
{
value: 'opt-3:5',
text: '选项3',
},
],
},
{
type: 'radiogroup',
name: '页面1-问题2',
choices: [
{
value: 'opt-1:10',
text: '选项1',
},
{
value: 'opt-2:7',
text: '选项2',
},
{
value: 'opt-3:3',
text: '选项3',
},
],
},
],
},
{
name: '页面2',
title: '页面名称2',
description: '页面2说明',
elements: [
{
type: 'radiogroup',
name: '页面2-问题1',
choices: [
{
value: 'opt-1:100',
text: '选项1',
},
{
value: 'opt-2:50',
text: '选项2',
},
{
value: 'opt-3:50',
text: '选项3',
},
],
},
{
type: 'radiogroup',
name: '页面2-问题2',
choices: [
{
value: 'opt-1:80',
text: '选项1',
},
{
value: 'opt-2:60',
text: '选项2',
},
{
value: 'opt-3:30',
text: '选项3',
},
],
},
],
},
],
};
const surveyResults = [
{
'页面1-问题1': 'opt-3:5',
'页面1-问题2': 'opt-3:3',
'页面2-问题1': 'opt-2:50',
'页面2-问题2': 'opt-2:60',
},
{
'页面2-问题1': 'opt-2:50',
'页面2-问题2': 'opt-1:80',
'页面1-问题1': 'opt-3:5',
'页面1-问题2': 'opt-1:10',
},
{
'页面1-问题1': 'opt-1:10',
'页面1-问题2': 'opt-1:10',
'页面2-问题1': 'opt-1:100',
'页面2-问题2': 'opt-2:60',
},
{
'页面1-问题1': 'opt-2:5',
'页面1-问题2': 'opt-2:7',
'页面2-问题1': 'opt-3:50',
'页面2-问题2': 'opt-3:30',
},
];
const vizPanelOptions = {
allowHideQuestions: false,
};
export default {
name: 'survey-analytics',
mounted() {
const survey = new Model(surveyJson);
const vizPanel = new VisualizationPanel(
survey.getAllQuestions(),
surveyResults,
vizPanelOptions,
);
vizPanel.showHeader = false;
vizPanel.render(document.getElementById('surveyVizPanel'));
},
};
</script>
<style lang="less" scoped>
.analysis {
width: 100%;
height: 100%;
padding: 15px 0;
text-align: right;
.btn {
display: inline-block;
margin-right: 30px;
}
#surveyVizPanel {
text-align: left;
}
}
</style>
- 有些依赖,需要单独下载。比如(survey-core/defaultV2.min.css);
- 里面还有只读类型的问卷,暂时没用到过;
- 有没有大神看一下,我的那个回答问卷的,demo为啥不能在vue3中使用