ver1
This commit is contained in:
parent
dbab520f56
commit
fffb706427
147
css/analyzeQuestion.css
Normal file
147
css/analyzeQuestion.css
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
background: #C3C3C3;
|
||||||
|
}
|
||||||
|
header {
|
||||||
|
background-color: #CF9A30;
|
||||||
|
color: #EEE8E4;
|
||||||
|
text-align: start;
|
||||||
|
padding: 20px;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
main {
|
||||||
|
padding: 30px 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.box {
|
||||||
|
width: 90%;
|
||||||
|
padding: 14px;
|
||||||
|
background-color: #EBEBEB;
|
||||||
|
box-shadow: 1px 2px 2px rgba(0,0,0,0.4);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
.quesen{
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
font-size: 28px;
|
||||||
|
font-weight: bold;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 24px;
|
||||||
|
color: #CF9A30;
|
||||||
|
border-radius: 50px;
|
||||||
|
padding-top: 5px;
|
||||||
|
background-color: #EBEBEB;
|
||||||
|
position: absolute;
|
||||||
|
font-style: normal;
|
||||||
|
top: 14px;
|
||||||
|
left: 60px;
|
||||||
|
}
|
||||||
|
.title{
|
||||||
|
margin-left: 80px;
|
||||||
|
font-size: 24px;
|
||||||
|
line-height: 20px;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-right: 60px;
|
||||||
|
}
|
||||||
|
.nav-bar a {
|
||||||
|
line-height: 20px;
|
||||||
|
font-size: 20px;
|
||||||
|
color: #EEE8E4;
|
||||||
|
border: 2px solid #c78501;
|
||||||
|
padding: 2px;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.question-title {
|
||||||
|
width: 100%;
|
||||||
|
padding: 20px;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: bold;
|
||||||
|
background: #CEEACA;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.question-info {
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.question-item {
|
||||||
|
width: 100%;
|
||||||
|
margin: 10px 0;
|
||||||
|
padding: 20px;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 2px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.question-content {
|
||||||
|
flex: 1;
|
||||||
|
padding-right: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.question-item-title {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.option-item {
|
||||||
|
margin: 10px 0;
|
||||||
|
padding: 5px 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.option-item span {
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-container {
|
||||||
|
width: 300px;
|
||||||
|
height: 300px;
|
||||||
|
margin-left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.back-button {
|
||||||
|
margin-top: 20px;
|
||||||
|
padding: 8px 24px;
|
||||||
|
background: #CF9A30;
|
||||||
|
color: #fff;
|
||||||
|
border: none;
|
||||||
|
border-radius: 2px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.back-button:hover {
|
||||||
|
background: #c78501;
|
||||||
|
}
|
||||||
|
|
||||||
|
.total-responses {
|
||||||
|
margin-top: 10px;
|
||||||
|
font-size: 16px;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.question-list{
|
||||||
|
width: 100%;
|
||||||
|
}
|
200
css/createQuestion.css
Normal file
200
css/createQuestion.css
Normal file
@ -0,0 +1,200 @@
|
|||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
background: #C3C3C3;
|
||||||
|
}
|
||||||
|
header {
|
||||||
|
background-color: #CF9A30;
|
||||||
|
color: #EEE8E4;
|
||||||
|
text-align: start;
|
||||||
|
padding: 20px;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
main {
|
||||||
|
padding: 30px 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.box {
|
||||||
|
width: 90%;
|
||||||
|
padding: 14px;
|
||||||
|
background-color: #EBEBEB;
|
||||||
|
box-shadow: 1px 2px 2px rgba(0,0,0,0.4);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
a{
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.quesen{
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
font-size: 28px;
|
||||||
|
font-weight: bold;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 24px;
|
||||||
|
color: #CF9A30;
|
||||||
|
border-radius: 50px;
|
||||||
|
padding-top: 5px;
|
||||||
|
background-color: #EBEBEB;
|
||||||
|
position: absolute;
|
||||||
|
font-style: normal;
|
||||||
|
top: 14px;
|
||||||
|
left: 60px;
|
||||||
|
}
|
||||||
|
.title{
|
||||||
|
margin-left: 80px;
|
||||||
|
font-size: 24px;
|
||||||
|
line-height: 20px;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-right: 60px;
|
||||||
|
}
|
||||||
|
.nav-bar{
|
||||||
|
a{
|
||||||
|
line-height: 20px;
|
||||||
|
font-size: 20px;
|
||||||
|
color: #EEE8E4;
|
||||||
|
border: 2px solid #c78501;
|
||||||
|
padding: 2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.question-title{
|
||||||
|
width: 100%;
|
||||||
|
height: 68px;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #000;
|
||||||
|
background: #CEEACA;
|
||||||
|
box-shadow: 1px 2px 2px rgba(0,0,0,0.4);
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.question-title:hover{
|
||||||
|
background: #FCFF00;
|
||||||
|
}
|
||||||
|
.but{
|
||||||
|
width: 99%;
|
||||||
|
height: 40px;
|
||||||
|
background-color: #D3D3D3;
|
||||||
|
margin-bottom: 25px;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 40px;
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #000000;
|
||||||
|
padding: 10px 0 50px 0;
|
||||||
|
transition: margin-top 0.3s;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
hr{
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.ctrl-bar{
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin: 20px 0;
|
||||||
|
}
|
||||||
|
.endtime{
|
||||||
|
margin-left: 20%;
|
||||||
|
span{
|
||||||
|
margin-right: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.pushbut{
|
||||||
|
margin-right: 20%;
|
||||||
|
button{
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.quetype{
|
||||||
|
margin-top: 20px;
|
||||||
|
padding: 20px 20%;
|
||||||
|
width: 99%;
|
||||||
|
border: 1px solid #b3b3b3;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
button {
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 16px;
|
||||||
|
padding: 1px 25px;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
.question-item {
|
||||||
|
width: 99%;
|
||||||
|
margin: 20px 0;
|
||||||
|
padding: 20px;
|
||||||
|
background: #fff;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
box-shadow: 1px 2px 2px rgba(0,0,0,0.1);
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.question-header {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.question-content input[type="text"] {
|
||||||
|
width: 100%;
|
||||||
|
padding: 8px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.option-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin: 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.option-item input[type="text"] {
|
||||||
|
margin-left: 10px;
|
||||||
|
width: 80%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.delete-btn {
|
||||||
|
padding: 2px 8px;
|
||||||
|
background: #ff4d4f;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ctrl-btns {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 10px;
|
||||||
|
right: 10px;
|
||||||
|
gap: 10px;
|
||||||
|
background: rgba(255, 255, 255, 0.9);
|
||||||
|
padding: 5px;
|
||||||
|
border-radius: 4px;
|
||||||
|
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ctrl-btns button {
|
||||||
|
padding: 2px 8px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quelist{
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.question-item:hover .ctrl-btns {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.question-content {
|
||||||
|
margin-bottom: 40px;
|
||||||
|
}
|
200
css/editQuestion.css
Normal file
200
css/editQuestion.css
Normal file
@ -0,0 +1,200 @@
|
|||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
background: #C3C3C3;
|
||||||
|
}
|
||||||
|
header {
|
||||||
|
background-color: #CF9A30;
|
||||||
|
color: #EEE8E4;
|
||||||
|
text-align: start;
|
||||||
|
padding: 20px;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
main {
|
||||||
|
padding: 30px 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.box {
|
||||||
|
width: 90%;
|
||||||
|
padding: 14px;
|
||||||
|
background-color: #EBEBEB;
|
||||||
|
box-shadow: 1px 2px 2px rgba(0,0,0,0.4);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
a{
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.quesen{
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
font-size: 28px;
|
||||||
|
font-weight: bold;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 24px;
|
||||||
|
color: #CF9A30;
|
||||||
|
border-radius: 50px;
|
||||||
|
padding-top: 5px;
|
||||||
|
background-color: #EBEBEB;
|
||||||
|
position: absolute;
|
||||||
|
font-style: normal;
|
||||||
|
top: 14px;
|
||||||
|
left: 60px;
|
||||||
|
}
|
||||||
|
.title{
|
||||||
|
margin-left: 80px;
|
||||||
|
font-size: 24px;
|
||||||
|
line-height: 20px;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-right: 60px;
|
||||||
|
}
|
||||||
|
.nav-bar a {
|
||||||
|
line-height: 20px;
|
||||||
|
font-size: 20px;
|
||||||
|
color: #EEE8E4;
|
||||||
|
border: 2px solid #c78501;
|
||||||
|
padding: 2px;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.question-title{
|
||||||
|
width: 100%;
|
||||||
|
height: 68px;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #000;
|
||||||
|
background: #CEEACA;
|
||||||
|
box-shadow: 1px 2px 2px rgba(0,0,0,0.4);
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.question-title:hover{
|
||||||
|
background: #FCFF00;
|
||||||
|
}
|
||||||
|
.but{
|
||||||
|
width: 99%;
|
||||||
|
height: 40px;
|
||||||
|
background-color: #D3D3D3;
|
||||||
|
margin-bottom: 25px;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 40px;
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #000000;
|
||||||
|
padding: 10px 0 50px 0;
|
||||||
|
transition: margin-top 0.3s;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
hr{
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.ctrl-bar{
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin: 20px 0;
|
||||||
|
}
|
||||||
|
.endtime{
|
||||||
|
margin-left: 20%;
|
||||||
|
}
|
||||||
|
.endtime span{
|
||||||
|
margin-right: 16px;
|
||||||
|
}
|
||||||
|
.pushbut{
|
||||||
|
margin-right: 20%;
|
||||||
|
}
|
||||||
|
.pushbut button{
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
.quetype{
|
||||||
|
margin-top: 20px;
|
||||||
|
padding: 20px 20%;
|
||||||
|
width: 99%;
|
||||||
|
border: 1px solid #b3b3b3;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
.quetype button {
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 16px;
|
||||||
|
padding: 1px 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.question-item {
|
||||||
|
width: 99%;
|
||||||
|
margin: 20px 0;
|
||||||
|
padding: 20px;
|
||||||
|
background: #fff;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
box-shadow: 1px 2px 2px rgba(0,0,0,0.1);
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.question-header {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.question-content input[type="text"] {
|
||||||
|
width: 100%;
|
||||||
|
padding: 8px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.option-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin: 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.option-item input[type="text"] {
|
||||||
|
margin-left: 10px;
|
||||||
|
width: 80%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.delete-btn {
|
||||||
|
padding: 2px 8px;
|
||||||
|
background: #ff4d4f;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ctrl-btns {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 10px;
|
||||||
|
right: 10px;
|
||||||
|
gap: 10px;
|
||||||
|
background: rgba(255, 255, 255, 0.9);
|
||||||
|
padding: 5px;
|
||||||
|
border-radius: 4px;
|
||||||
|
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ctrl-btns button {
|
||||||
|
padding: 2px 8px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quelist{
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.question-item:hover .ctrl-btns {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.question-content {
|
||||||
|
margin-bottom: 40px;
|
||||||
|
}
|
149
css/fillQuestion.css
Normal file
149
css/fillQuestion.css
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
background: #C3C3C3;
|
||||||
|
}
|
||||||
|
header {
|
||||||
|
background-color: #CF9A30;
|
||||||
|
color: #EEE8E4;
|
||||||
|
text-align: start;
|
||||||
|
padding: 20px;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
main {
|
||||||
|
padding: 30px 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.box {
|
||||||
|
width: 90%;
|
||||||
|
padding: 14px;
|
||||||
|
background-color: #EBEBEB;
|
||||||
|
box-shadow: 1px 2px 2px rgba(0,0,0,0.4);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
.quesen{
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
font-size: 28px;
|
||||||
|
font-weight: bold;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 24px;
|
||||||
|
color: #CF9A30;
|
||||||
|
border-radius: 50px;
|
||||||
|
padding-top: 5px;
|
||||||
|
background-color: #EBEBEB;
|
||||||
|
position: absolute;
|
||||||
|
font-style: normal;
|
||||||
|
top: 14px;
|
||||||
|
left: 60px;
|
||||||
|
}
|
||||||
|
.title{
|
||||||
|
margin-left: 80px;
|
||||||
|
font-size: 24px;
|
||||||
|
line-height: 20px;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-right: 60px;
|
||||||
|
}
|
||||||
|
.nav-bar a {
|
||||||
|
line-height: 20px;
|
||||||
|
font-size: 20px;
|
||||||
|
color: #EEE8E4;
|
||||||
|
border: 2px solid #c78501;
|
||||||
|
padding: 2px;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.question-title {
|
||||||
|
width: 100%;
|
||||||
|
padding: 20px;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: bold;
|
||||||
|
background: #CEEACA;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.question-info {
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.question-item {
|
||||||
|
width: 100%;
|
||||||
|
margin: 10px 0;
|
||||||
|
padding: 20px;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.question-item-title {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.option-item {
|
||||||
|
margin: 10px 0;
|
||||||
|
padding: 5px 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.option-item input[type="radio"],
|
||||||
|
.option-item input[type="checkbox"] {
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.option-item label {
|
||||||
|
cursor: pointer;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-answer {
|
||||||
|
width: 100%;
|
||||||
|
min-height: 100px;
|
||||||
|
padding: 10px;
|
||||||
|
margin-top: 10px;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 2px;
|
||||||
|
resize: vertical;
|
||||||
|
}
|
||||||
|
|
||||||
|
.submit-button {
|
||||||
|
margin-top: 20px;
|
||||||
|
padding: 8px 24px;
|
||||||
|
background: #CF9A30;
|
||||||
|
color: #fff;
|
||||||
|
border: none;
|
||||||
|
border-radius: 2px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.submit-button:hover {
|
||||||
|
background: #c78501;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-message {
|
||||||
|
color: #ff4d4f;
|
||||||
|
margin-top: 5px;
|
||||||
|
font-size: 14px;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.question-list{
|
||||||
|
width: 100%;
|
||||||
|
}
|
83
css/index.css
Normal file
83
css/index.css
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
background: #C3C3C3;
|
||||||
|
}
|
||||||
|
header {
|
||||||
|
background-color: #CF9A30;
|
||||||
|
color: #EEE8E4;
|
||||||
|
text-align: start;
|
||||||
|
padding: 20px;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
main {
|
||||||
|
padding: 30px 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.box {
|
||||||
|
width: 90%;
|
||||||
|
padding: 40px 20px;
|
||||||
|
background-color: #EBEBEB;
|
||||||
|
box-shadow: 1px 2px 2px rgba(0,0,0,0.4);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.but{
|
||||||
|
width: 173px;
|
||||||
|
height: 36px;
|
||||||
|
background: #CF9A30;
|
||||||
|
border-radius: 2px;
|
||||||
|
border: 2px solid #c78501;
|
||||||
|
padding-bottom: 36px;
|
||||||
|
margin: 20px 0;
|
||||||
|
|
||||||
|
span{
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #EEE8E4;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 36px;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
a{
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.quesen{
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
font-size: 28px;
|
||||||
|
font-weight: bold;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 24px;
|
||||||
|
color: #CF9A30;
|
||||||
|
border-radius: 50px;
|
||||||
|
padding-top: 5px;
|
||||||
|
background-color: #EBEBEB;
|
||||||
|
position: absolute;
|
||||||
|
font-style: normal;
|
||||||
|
top: 14px;
|
||||||
|
left: 60px;
|
||||||
|
}
|
||||||
|
.title{
|
||||||
|
margin-left: 80px;
|
||||||
|
font-size: 24px;
|
||||||
|
line-height: 20px;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-right: 60px;
|
||||||
|
}
|
||||||
|
.nav-bar{
|
||||||
|
a{
|
||||||
|
line-height: 20px;
|
||||||
|
font-size: 20px;
|
||||||
|
color: #EEE8E4;
|
||||||
|
border: 2px solid #c78501;
|
||||||
|
padding: 2px;
|
||||||
|
}
|
||||||
|
}
|
211
css/myQuestion.css
Normal file
211
css/myQuestion.css
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
background: #C3C3C3;
|
||||||
|
}
|
||||||
|
header {
|
||||||
|
background-color: #CF9A30;
|
||||||
|
color: #EEE8E4;
|
||||||
|
text-align: start;
|
||||||
|
padding: 20px;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
main {
|
||||||
|
padding: 30px 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.box {
|
||||||
|
width: 90%;
|
||||||
|
padding: 20px;
|
||||||
|
position: relative;
|
||||||
|
background-color: #EBEBEB;
|
||||||
|
box-shadow: 1px 2px 2px rgba(0,0,0,0.4);
|
||||||
|
}
|
||||||
|
a{
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.quesen{
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
font-size: 28px;
|
||||||
|
font-weight: bold;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 24px;
|
||||||
|
color: #CF9A30;
|
||||||
|
border-radius: 50px;
|
||||||
|
padding-top: 5px;
|
||||||
|
background-color: #EBEBEB;
|
||||||
|
position: absolute;
|
||||||
|
font-style: normal;
|
||||||
|
top: 14px;
|
||||||
|
left: 60px;
|
||||||
|
}
|
||||||
|
.title{
|
||||||
|
margin-left: 80px;
|
||||||
|
font-size: 24px;
|
||||||
|
line-height: 20px;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-right: 60px;
|
||||||
|
}
|
||||||
|
.nav-bar{
|
||||||
|
a{
|
||||||
|
line-height: 20px;
|
||||||
|
font-size: 20px;
|
||||||
|
color: #EEE8E4;
|
||||||
|
border: 2px solid #c78501;
|
||||||
|
padding: 2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.grid-bar{
|
||||||
|
width: 85%;
|
||||||
|
display: flex;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
.grid-item-title{
|
||||||
|
color: #2E276D;
|
||||||
|
font-weight: bold;
|
||||||
|
span{
|
||||||
|
margin: 0 8px;
|
||||||
|
}
|
||||||
|
padding-right: 20px;
|
||||||
|
}
|
||||||
|
.grid-item-add{
|
||||||
|
color: #EEE8E4;
|
||||||
|
background: #CF9A30;
|
||||||
|
font-weight: bold;
|
||||||
|
padding: 0 5px;
|
||||||
|
border: 2px solid #c78501;
|
||||||
|
border-radius: 2px;
|
||||||
|
position: absolute;
|
||||||
|
right: 40px;
|
||||||
|
top: 20px;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
.list-item{
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
.quelist{
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.btn-group{
|
||||||
|
width: 33%;
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
.item-title{
|
||||||
|
/* width: 33%; */
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
background: transparent;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
th, td {
|
||||||
|
padding: 10px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.thtitle, .data-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.thadd, .data-item {
|
||||||
|
flex: 0.8;
|
||||||
|
padding: 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-row {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-row button {
|
||||||
|
padding: 2px 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.thtitle {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.thadd {
|
||||||
|
flex: 0.4;
|
||||||
|
padding: 0 5px;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-align: left;
|
||||||
|
color: #2E276D;
|
||||||
|
}
|
||||||
|
|
||||||
|
.thadd:last-child {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.data-row {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.data-item {
|
||||||
|
flex: 0.4;
|
||||||
|
padding: 0 5px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.data-item:last-child {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 5px;
|
||||||
|
justify-content: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
table th:first-child {
|
||||||
|
width: 35%;
|
||||||
|
}
|
||||||
|
|
||||||
|
table th:last-child {
|
||||||
|
width: 65%;
|
||||||
|
}
|
||||||
|
|
||||||
|
tr:not(:first-child) {
|
||||||
|
background-color: #EBEBEB;
|
||||||
|
box-shadow: 1px 2px 2px rgba(0,0,0,0.4);
|
||||||
|
margin-bottom: 10px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
tr:not(:first-child) td {
|
||||||
|
padding: 15px 10px;
|
||||||
|
border-bottom: 1px solid #C3C3C3;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
background: transparent;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box {
|
||||||
|
background: transparent;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 添加行悬停效果 */
|
||||||
|
tr:not(:first-child):hover {
|
||||||
|
background-color: #e0e0e0; /* 稍微深一点的灰色 */
|
||||||
|
transition: background-color 0.3s ease; /* 添加过渡效果 */
|
||||||
|
}
|
||||||
|
|
135
css/viewQuestion.css
Normal file
135
css/viewQuestion.css
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
background: #C3C3C3;
|
||||||
|
}
|
||||||
|
header {
|
||||||
|
background-color: #CF9A30;
|
||||||
|
color: #EEE8E4;
|
||||||
|
text-align: start;
|
||||||
|
padding: 20px;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
main {
|
||||||
|
padding: 30px 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.box {
|
||||||
|
width: 90%;
|
||||||
|
padding: 14px;
|
||||||
|
background-color: #EBEBEB;
|
||||||
|
box-shadow: 1px 2px 2px rgba(0,0,0,0.4);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
.quesen{
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
font-size: 28px;
|
||||||
|
font-weight: bold;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 24px;
|
||||||
|
color: #CF9A30;
|
||||||
|
border-radius: 50px;
|
||||||
|
padding-top: 5px;
|
||||||
|
background-color: #EBEBEB;
|
||||||
|
position: absolute;
|
||||||
|
font-style: normal;
|
||||||
|
top: 14px;
|
||||||
|
left: 60px;
|
||||||
|
}
|
||||||
|
.title{
|
||||||
|
margin-left: 80px;
|
||||||
|
font-size: 24px;
|
||||||
|
line-height: 20px;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-right: 60px;
|
||||||
|
}
|
||||||
|
.nav-bar a {
|
||||||
|
line-height: 20px;
|
||||||
|
font-size: 20px;
|
||||||
|
color: #EEE8E4;
|
||||||
|
border: 2px solid #c78501;
|
||||||
|
padding: 2px;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.question-title {
|
||||||
|
width: 100%;
|
||||||
|
padding: 20px;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: bold;
|
||||||
|
background: #CEEACA;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.question-info {
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.question-item {
|
||||||
|
width: 100%;
|
||||||
|
margin: 10px 0;
|
||||||
|
padding: 20px;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.question-item-title {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.option-item {
|
||||||
|
margin: 10px 0;
|
||||||
|
padding: 5px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.option-item input[type="radio"],
|
||||||
|
.option-item input[type="checkbox"] {
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-answer {
|
||||||
|
width: 100%;
|
||||||
|
min-height: 100px;
|
||||||
|
padding: 10px;
|
||||||
|
margin-top: 10px;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 2px;
|
||||||
|
resize: vertical;
|
||||||
|
}
|
||||||
|
|
||||||
|
.back-button {
|
||||||
|
margin-top: 20px;
|
||||||
|
padding: 5px 15px;
|
||||||
|
background: #CF9A30;
|
||||||
|
color: #fff;
|
||||||
|
border: none;
|
||||||
|
border-radius: 2px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.back-button:hover {
|
||||||
|
background: #c78501;
|
||||||
|
}
|
||||||
|
|
||||||
|
.question-list{
|
||||||
|
width: 100%;
|
||||||
|
}
|
90
index.html
90
index.html
@ -4,103 +4,19 @@
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>问卷网站</title>
|
<title>问卷网站</title>
|
||||||
<style>
|
<link rel="stylesheet" href="css/index.css">
|
||||||
* {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
body {
|
|
||||||
background: #C3C3C3;
|
|
||||||
}
|
|
||||||
header {
|
|
||||||
background-color: #CF9A30;
|
|
||||||
color: #EEE8E4;
|
|
||||||
text-align: start;
|
|
||||||
padding: 20px;
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
main {
|
|
||||||
padding: 30px 0;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
.box {
|
|
||||||
width: 90%;
|
|
||||||
padding: 40px 20px;
|
|
||||||
background-color: #EBEBEB;
|
|
||||||
box-shadow: 1px 2px 2px rgba(0,0,0,0.4);
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
.but{
|
|
||||||
width: 173px;
|
|
||||||
height: 36px;
|
|
||||||
background: #CF9A30;
|
|
||||||
border-radius: 2px;
|
|
||||||
border: 2px solid #c78501;
|
|
||||||
padding-bottom: 36px;
|
|
||||||
margin: 20px 0;
|
|
||||||
|
|
||||||
span{
|
|
||||||
font-size: 24px;
|
|
||||||
font-weight: bold;
|
|
||||||
color: #EEE8E4;
|
|
||||||
text-align: center;
|
|
||||||
line-height: 36px;
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
a{
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
.quesen{
|
|
||||||
width: 32px;
|
|
||||||
height: 32px;
|
|
||||||
font-size: 28px;
|
|
||||||
font-weight: bold;
|
|
||||||
text-align: center;
|
|
||||||
line-height: 24px;
|
|
||||||
color: #CF9A30;
|
|
||||||
border-radius: 50px;
|
|
||||||
padding-top: 5px;
|
|
||||||
background-color: #EBEBEB;
|
|
||||||
position: absolute;
|
|
||||||
font-style: normal;
|
|
||||||
top: 14px;
|
|
||||||
left: 60px;
|
|
||||||
}
|
|
||||||
.title{
|
|
||||||
margin-left: 80px;
|
|
||||||
font-size: 24px;
|
|
||||||
line-height: 20px;
|
|
||||||
font-weight: bold;
|
|
||||||
margin-right: 60px;
|
|
||||||
}
|
|
||||||
.nav-bar{
|
|
||||||
a{
|
|
||||||
line-height: 20px;
|
|
||||||
font-size: 20px;
|
|
||||||
color: #EEE8E4;
|
|
||||||
border: 2px solid #c78501;
|
|
||||||
padding: 2px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header>
|
<header>
|
||||||
<i class="quesen">?</i>
|
<i class="quesen">?</i>
|
||||||
<div class="title">问卷管理</div>
|
<div class="title">问卷管理</div>
|
||||||
<div class="nav-bar">
|
<div class="nav-bar">
|
||||||
<a href="/view/myQuestion.html">我的问卷</a>
|
<a href="view/myQuestion.html">我的问卷</a>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
<main>
|
<main>
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<a href="/view/createQuestion.html" class="but add">
|
<a href="view/createQuestion.html" class="but add">
|
||||||
<span>+ 新建问卷</span>
|
<span>+ 新建问卷</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
190
js/analyzeQuestion.js
Normal file
190
js/analyzeQuestion.js
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
let currentQuestionnaire = null;
|
||||||
|
let questionnaireAnswers = [];
|
||||||
|
|
||||||
|
function formatDate(timestamp) {
|
||||||
|
if (!timestamp) return '-';
|
||||||
|
const date = new Date(timestamp);
|
||||||
|
return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderPieChart(containerId, labels, data) {
|
||||||
|
const ctx = document.getElementById(containerId).getContext('2d');
|
||||||
|
return new Chart(ctx, {
|
||||||
|
type: 'pie',
|
||||||
|
data: {
|
||||||
|
labels: labels,
|
||||||
|
datasets: [{
|
||||||
|
data: data,
|
||||||
|
backgroundColor: [
|
||||||
|
'#FF6384',
|
||||||
|
'#36A2EB',
|
||||||
|
'#FFCE56',
|
||||||
|
'#4BC0C0',
|
||||||
|
'#9966FF',
|
||||||
|
'#FF9F40'
|
||||||
|
]
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
responsive: true,
|
||||||
|
maintainAspectRatio: false
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderBarChart(containerId, validCount, invalidCount) {
|
||||||
|
const ctx = document.getElementById(containerId).getContext('2d');
|
||||||
|
return new Chart(ctx, {
|
||||||
|
type: 'bar',
|
||||||
|
data: {
|
||||||
|
labels: ['有效回答', '无效回答'],
|
||||||
|
datasets: [{
|
||||||
|
data: [validCount, invalidCount],
|
||||||
|
backgroundColor: ['#36A2EB', '#FF6384']
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
responsive: true,
|
||||||
|
maintainAspectRatio: false,
|
||||||
|
scales: {
|
||||||
|
y: {
|
||||||
|
beginAtZero: true,
|
||||||
|
ticks: {
|
||||||
|
stepSize: 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
plugins: {
|
||||||
|
legend: {
|
||||||
|
display: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function analyzeAnswers(question) {
|
||||||
|
const answers = questionnaireAnswers.map(response =>
|
||||||
|
response.answers.find(a => a.questionId === question.id)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (question.type === 'text') {
|
||||||
|
const validCount = answers.filter(a => a && a.answer && a.answer.trim()).length;
|
||||||
|
const invalidCount = answers.length - validCount;
|
||||||
|
return { validCount, invalidCount };
|
||||||
|
} else {
|
||||||
|
const optionCounts = {};
|
||||||
|
question.options.forEach(opt => optionCounts[opt.id] = 0);
|
||||||
|
|
||||||
|
answers.forEach(answer => {
|
||||||
|
if (answer && answer.answer) {
|
||||||
|
const selectedOptions = Array.isArray(answer.answer) ? answer.answer : [answer.answer];
|
||||||
|
selectedOptions.forEach(optId => {
|
||||||
|
if (optionCounts[optId] !== undefined) {
|
||||||
|
optionCounts[optId]++;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return optionCounts;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderQuestion(question, index) {
|
||||||
|
const analysis = analyzeAnswers(question);
|
||||||
|
const chartId = `chart_${question.id}`;
|
||||||
|
|
||||||
|
let questionHtml = `
|
||||||
|
<div class="question-item">
|
||||||
|
<div class="question-content">
|
||||||
|
<div class="question-item-title">
|
||||||
|
${index + 1}. ${question.title}
|
||||||
|
${question.required ? '<span style="color: red; margin-left: 5px;">*(必答题)</span>' : ''}
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
if (question.type === 'text') {
|
||||||
|
questionHtml += `
|
||||||
|
<div class="text-analysis">
|
||||||
|
<div class="question-content">
|
||||||
|
<textarea class="text-answer" disabled
|
||||||
|
style="width: 100%; min-height: 100px; padding: 8px; margin-top: 10px; resize: vertical; background-color: #f5f5f5;"
|
||||||
|
placeholder="此处填写答案"></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="chart-container">
|
||||||
|
<canvas id="${chartId}"></canvas>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
setTimeout(() => renderBarChart(chartId, analysis.validCount, analysis.invalidCount), 0);
|
||||||
|
} else {
|
||||||
|
questionHtml += `
|
||||||
|
<div class="options">
|
||||||
|
${question.options.map(option => `
|
||||||
|
<div class="option-item">
|
||||||
|
<input type="${question.type}" disabled>
|
||||||
|
<label>${option.content}</label>
|
||||||
|
<span style="margin-left: 10px;"></span>
|
||||||
|
</div>
|
||||||
|
`).join('')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="chart-container">
|
||||||
|
<canvas id="${chartId}"></canvas>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
setTimeout(() => renderPieChart(
|
||||||
|
chartId,
|
||||||
|
question.options.map(opt => opt.content),
|
||||||
|
question.options.map(opt => analysis[opt.id])
|
||||||
|
), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
questionHtml += `</div>`;
|
||||||
|
return questionHtml;
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadQuestionnaireData() {
|
||||||
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
|
const questionnaireId = urlParams.get('id');
|
||||||
|
|
||||||
|
if (!questionnaireId) {
|
||||||
|
alert('问卷ID不存在!');
|
||||||
|
window.location.href = 'myQuestion.html';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const questionnaireList = JSON.parse(localStorage.getItem('questionnaireList') || '[]');
|
||||||
|
const questionnaire = questionnaireList.find(q => q.id === questionnaireId);
|
||||||
|
|
||||||
|
if (!questionnaire) {
|
||||||
|
alert('问卷不存在!');
|
||||||
|
window.location.href = 'myQuestion.html';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentQuestionnaire = questionnaire;
|
||||||
|
|
||||||
|
// 获取问卷答案
|
||||||
|
const allAnswers = JSON.parse(localStorage.getItem('questionnaireAnswers') || '[]');
|
||||||
|
questionnaireAnswers = allAnswers.filter(a => a.questionnaireId === questionnaireId);
|
||||||
|
|
||||||
|
// 填充问卷信息
|
||||||
|
document.querySelector('.question-title').textContent = questionnaire.title;
|
||||||
|
document.querySelector('.create-time').textContent = formatDate(questionnaire.createTime);
|
||||||
|
document.querySelector('.publish-time').textContent = formatDate(questionnaire.publishTime);
|
||||||
|
document.querySelector('.end-time').textContent = formatDate(questionnaire.data.endTime);
|
||||||
|
document.querySelector('.status').textContent = questionnaire.status;
|
||||||
|
document.querySelector('.response-count').textContent = questionnaireAnswers.length;
|
||||||
|
|
||||||
|
// 渲染问题列表
|
||||||
|
const questionListHtml = questionnaire.data.questions
|
||||||
|
.map((question, index) => renderQuestion(question, index))
|
||||||
|
.join('');
|
||||||
|
document.querySelector('.question-list').innerHTML = questionListHtml;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.onload = loadQuestionnaireData;
|
20
js/chart.js
Normal file
20
js/chart.js
Normal file
File diff suppressed because one or more lines are too long
367
js/createQuestion.js
Normal file
367
js/createQuestion.js
Normal file
@ -0,0 +1,367 @@
|
|||||||
|
let questionCount = 0;
|
||||||
|
|
||||||
|
function toggleQueType() {
|
||||||
|
const queType = document.querySelector('.quetype');
|
||||||
|
const addButton = document.querySelector('.but');
|
||||||
|
|
||||||
|
if (queType.style.display === 'none') {
|
||||||
|
queType.style.display = 'flex';
|
||||||
|
addButton.style.marginTop = '0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加单选题
|
||||||
|
function addRadioQuestion() {
|
||||||
|
questionCount++;
|
||||||
|
const questionHtml = `
|
||||||
|
<div class="question-item" id="question-${questionCount}">
|
||||||
|
<div class="question-header">
|
||||||
|
<div class="question-title-area">
|
||||||
|
<span>${questionCount}. </span>
|
||||||
|
<input type="text" placeholder="请输入问题">
|
||||||
|
<button onclick="addOption(${questionCount})">添加选项</button>
|
||||||
|
<label style="margin-left: 20px;">
|
||||||
|
<input type="checkbox" class="required-checkbox"> 此题为必答题
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="question-content" id="options-${questionCount}">
|
||||||
|
<div class="option-item">
|
||||||
|
<input type="radio" name="question${questionCount}" disabled>
|
||||||
|
<input type="text" placeholder="选项内容">
|
||||||
|
<button class="delete-btn" onclick="deleteOption(this)">删除</button>
|
||||||
|
</div>
|
||||||
|
<div class="option-item">
|
||||||
|
<input type="radio" name="question${questionCount}" disabled>
|
||||||
|
<input type="text" placeholder="选项内容">
|
||||||
|
<button class="delete-btn" onclick="deleteOption(this)">删除</button>
|
||||||
|
</div>
|
||||||
|
<div class="option-item">
|
||||||
|
<input type="radio" name="question${questionCount}" disabled>
|
||||||
|
<input type="text" placeholder="选项内容">
|
||||||
|
<button class="delete-btn" onclick="deleteOption(this)">删除</button>
|
||||||
|
</div>
|
||||||
|
<div class="option-item">
|
||||||
|
<input type="radio" name="question${questionCount}" disabled>
|
||||||
|
<input type="text" placeholder="选项内容">
|
||||||
|
<button class="delete-btn" onclick="deleteOption(this)">删除</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="ctrl-btns">
|
||||||
|
<button onclick="moveUp(${questionCount})">上移</button>
|
||||||
|
<button onclick="moveDown(${questionCount})">下移</button>
|
||||||
|
<button onclick="copyQuestion(${questionCount})">复用</button>
|
||||||
|
<button class="delete-btn" onclick="deleteQuestion(${questionCount})">删除</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
document.querySelector('.quelist').insertAdjacentHTML('beforeend', questionHtml);
|
||||||
|
toggleQueType();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加选项
|
||||||
|
function addOption(questionId) {
|
||||||
|
const optionHtml = `
|
||||||
|
<div class="option-item">
|
||||||
|
<input type="radio" disabled>
|
||||||
|
<input type="text" placeholder="选项内容">
|
||||||
|
<button class="delete-btn" onclick="deleteOption(this)">删除</button>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
document.querySelector(`#options-${questionId}`).insertAdjacentHTML('beforeend', optionHtml);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除选项
|
||||||
|
function deleteOption(btn) {
|
||||||
|
btn.parentElement.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除问题
|
||||||
|
function deleteQuestion(questionId) {
|
||||||
|
document.querySelector(`#question-${questionId}`).remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 复用问题
|
||||||
|
function copyQuestion(questionId) {
|
||||||
|
const original = document.querySelector(`#question-${questionId}`);
|
||||||
|
const clone = original.cloneNode(true);
|
||||||
|
questionCount++;
|
||||||
|
clone.id = `question-${questionCount}`;
|
||||||
|
original.after(clone);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 上移问题
|
||||||
|
function moveUp(questionId) {
|
||||||
|
const question = document.querySelector(`#question-${questionId}`);
|
||||||
|
const prev = question.previousElementSibling;
|
||||||
|
if (prev) {
|
||||||
|
prev.before(question);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 下移问题
|
||||||
|
function moveDown(questionId) {
|
||||||
|
const question = document.querySelector(`#question-${questionId}`);
|
||||||
|
const next = question.nextElementSibling;
|
||||||
|
if (next) {
|
||||||
|
next.after(question);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加多选题
|
||||||
|
function addCheckboxQuestion() {
|
||||||
|
questionCount++;
|
||||||
|
const questionHtml = `
|
||||||
|
<div class="question-item" id="question-${questionCount}">
|
||||||
|
<div class="question-header">
|
||||||
|
<div class="question-title-area">
|
||||||
|
<span>${questionCount}. </span>
|
||||||
|
<input type="text" placeholder="请输入问题">
|
||||||
|
<button onclick="addCheckboxOption(${questionCount})">添加选项</button>
|
||||||
|
<label style="margin-left: 20px;">
|
||||||
|
<input type="checkbox" class="required-checkbox"> 此题为必答题
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="question-content" id="options-${questionCount}">
|
||||||
|
<div class="option-item">
|
||||||
|
<input type="checkbox" name="question${questionCount}" disabled>
|
||||||
|
<input type="text" placeholder="选项内容">
|
||||||
|
<button class="delete-btn" onclick="deleteOption(this)">删除</button>
|
||||||
|
</div>
|
||||||
|
<div class="option-item">
|
||||||
|
<input type="checkbox" name="question${questionCount}" disabled>
|
||||||
|
<input type="text" placeholder="选项内容">
|
||||||
|
<button class="delete-btn" onclick="deleteOption(this)">删除</button>
|
||||||
|
</div>
|
||||||
|
<div class="option-item">
|
||||||
|
<input type="checkbox" name="question${questionCount}" disabled>
|
||||||
|
<input type="text" placeholder="选项内容">
|
||||||
|
<button class="delete-btn" onclick="deleteOption(this)">删除</button>
|
||||||
|
</div>
|
||||||
|
<div class="option-item">
|
||||||
|
<input type="checkbox" name="question${questionCount}" disabled>
|
||||||
|
<input type="text" placeholder="选项内容">
|
||||||
|
<button class="delete-btn" onclick="deleteOption(this)">删除</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="ctrl-btns">
|
||||||
|
<button onclick="moveUp(${questionCount})">上移</button>
|
||||||
|
<button onclick="moveDown(${questionCount})">下移</button>
|
||||||
|
<button onclick="copyQuestion(${questionCount})">复用</button>
|
||||||
|
<button class="delete-btn" onclick="deleteQuestion(${questionCount})">删除</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
document.querySelector('.quelist').insertAdjacentHTML('beforeend', questionHtml);
|
||||||
|
toggleQueType();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加多选题选项
|
||||||
|
function addCheckboxOption(questionId) {
|
||||||
|
const optionHtml = `
|
||||||
|
<div class="option-item">
|
||||||
|
<input type="checkbox" disabled>
|
||||||
|
<input type="text" placeholder="选项内容">
|
||||||
|
<button class="delete-btn" onclick="deleteOption(this)">删除</button>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
document.querySelector(`#options-${questionId}`).insertAdjacentHTML('beforeend', optionHtml);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加文本题
|
||||||
|
function addTextQuestion() {
|
||||||
|
questionCount++;
|
||||||
|
const questionHtml = `
|
||||||
|
<div class="question-item" id="question-${questionCount}">
|
||||||
|
<div class="question-header">
|
||||||
|
<div class="question-title-area">
|
||||||
|
<span>${questionCount}. </span>
|
||||||
|
<input type="text" placeholder="请输入问题">
|
||||||
|
<label style="margin-left: 20px;">
|
||||||
|
<input type="checkbox" class="required-checkbox"> 此题为必答题
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="question-content" id="options-${questionCount}">
|
||||||
|
<textarea disabled placeholder="此处供填写者输入文本答案"
|
||||||
|
style="width: 100%; min-height: 100px; padding: 8px; margin-top: 10px; resize: vertical;"></textarea>
|
||||||
|
</div>
|
||||||
|
<div class="ctrl-btns">
|
||||||
|
<button onclick="moveUp(${questionCount})">上移</button>
|
||||||
|
<button onclick="moveDown(${questionCount})">下移</button>
|
||||||
|
<button onclick="copyQuestion(${questionCount})">复用</button>
|
||||||
|
<button class="delete-btn" onclick="deleteQuestion(${questionCount})">删除</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
document.querySelector('.quelist').insertAdjacentHTML('beforeend', questionHtml);
|
||||||
|
toggleQueType();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取问卷数据
|
||||||
|
function getQuestionnaireData(isPublished = false) {
|
||||||
|
const now = new Date().getTime();
|
||||||
|
const questionnaire = {
|
||||||
|
title: document.querySelector('.question-title').value,
|
||||||
|
createTime: now,
|
||||||
|
endTime: document.querySelector('#endtime').value,
|
||||||
|
publishTime: isPublished ? now : null,
|
||||||
|
status: isPublished ? '已发布' : '未发布',
|
||||||
|
questions: []
|
||||||
|
};
|
||||||
|
|
||||||
|
const questionItems = document.querySelectorAll('.question-item');
|
||||||
|
questionItems.forEach((item, index) => {
|
||||||
|
let questionType;
|
||||||
|
if (item.querySelector('.question-content textarea')) {
|
||||||
|
questionType = 'text';
|
||||||
|
} else if (item.querySelector('input[type="radio"]')) {
|
||||||
|
questionType = 'radio';
|
||||||
|
} else {
|
||||||
|
questionType = 'checkbox';
|
||||||
|
}
|
||||||
|
|
||||||
|
const question = {
|
||||||
|
id: index + 1,
|
||||||
|
type: questionType,
|
||||||
|
title: item.querySelector('.question-title-area input[type="text"]').value,
|
||||||
|
required: item.querySelector('.required-checkbox').checked,
|
||||||
|
options: []
|
||||||
|
};
|
||||||
|
|
||||||
|
if (questionType === 'radio' || questionType === 'checkbox') {
|
||||||
|
const options = item.querySelectorAll('.option-item input[type="text"]');
|
||||||
|
options.forEach((option, optionIndex) => {
|
||||||
|
question.options.push({
|
||||||
|
id: optionIndex + 1,
|
||||||
|
content: option.value
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
questionnaire.questions.push(question);
|
||||||
|
});
|
||||||
|
|
||||||
|
return questionnaire;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保存问卷到 localStorage
|
||||||
|
function saveQuestionnaire() {
|
||||||
|
// 验证问卷
|
||||||
|
if (!validateQuestionnaire()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const questionnaire = getQuestionnaireData(false);
|
||||||
|
const questionnaireId = `questionnaire_${questionnaire.createTime}`;
|
||||||
|
|
||||||
|
// 获取已有的问卷列表
|
||||||
|
let questionnaireList = JSON.parse(localStorage.getItem('questionnaireList') || '[]');
|
||||||
|
|
||||||
|
// 添加新问卷
|
||||||
|
questionnaireList.push({
|
||||||
|
id: questionnaireId,
|
||||||
|
title: questionnaire.title,
|
||||||
|
createTime: questionnaire.createTime,
|
||||||
|
publishTime: questionnaire.publishTime,
|
||||||
|
status: questionnaire.status,
|
||||||
|
data: questionnaire
|
||||||
|
});
|
||||||
|
|
||||||
|
// 保存更新后的问卷列表
|
||||||
|
localStorage.setItem('questionnaireList', JSON.stringify(questionnaireList));
|
||||||
|
|
||||||
|
alert('问卷保存成功!');
|
||||||
|
window.location.href = 'myQuestion.html'; // 添加返回功能
|
||||||
|
}
|
||||||
|
|
||||||
|
// 发布问卷
|
||||||
|
function publishQuestionnaire() {
|
||||||
|
// 验证问卷
|
||||||
|
if (!validateQuestionnaire()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const questionnaire = getQuestionnaireData(true);
|
||||||
|
const questionnaireId = `questionnaire_${questionnaire.createTime}`;
|
||||||
|
|
||||||
|
// 获取已有的问卷列表
|
||||||
|
let questionnaireList = JSON.parse(localStorage.getItem('questionnaireList') || '[]');
|
||||||
|
|
||||||
|
// 添加新问卷
|
||||||
|
questionnaireList.push({
|
||||||
|
id: questionnaireId,
|
||||||
|
title: questionnaire.title,
|
||||||
|
createTime: questionnaire.createTime,
|
||||||
|
publishTime: questionnaire.publishTime,
|
||||||
|
status: questionnaire.status,
|
||||||
|
data: questionnaire
|
||||||
|
});
|
||||||
|
|
||||||
|
// 保存更新后的问卷列表
|
||||||
|
localStorage.setItem('questionnaireList', JSON.stringify(questionnaireList));
|
||||||
|
|
||||||
|
alert('问卷发布成功!');
|
||||||
|
window.location.href = 'myQuestion.html'; // 添加返回功能
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加问卷验证函数
|
||||||
|
function validateQuestionnaire() {
|
||||||
|
const title = document.querySelector('.question-title').value.trim();
|
||||||
|
if (!title) {
|
||||||
|
alert('请输入问卷标题!');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const endTime = document.querySelector('#endtime').value;
|
||||||
|
if (!endTime) {
|
||||||
|
alert('请设置问卷截止日期!');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const questions = document.querySelectorAll('.question-item');
|
||||||
|
if (questions.length === 0) {
|
||||||
|
alert('请至少添加一个问题!');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let question of questions) {
|
||||||
|
const questionTitle = question.querySelector('.question-title-area input[type="text"]').value.trim();
|
||||||
|
if (!questionTitle) {
|
||||||
|
alert('请填写所有问题的标题!');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const questionType = question.querySelector('input[type="radio"]') ? 'radio' :
|
||||||
|
question.querySelector('input[type="checkbox"]') ? 'checkbox' : 'text';
|
||||||
|
|
||||||
|
if (questionType !== 'text') {
|
||||||
|
const options = question.querySelectorAll('.option-item input[type="text"]');
|
||||||
|
for (let option of options) {
|
||||||
|
if (!option.value.trim()) {
|
||||||
|
alert('请填写所有选项的内容!');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化页面
|
||||||
|
window.onload = function() {
|
||||||
|
document.querySelector('.but').style.marginTop = '20px';
|
||||||
|
|
||||||
|
// 为题型按钮添加点击事件
|
||||||
|
const buttons = document.querySelectorAll('.quetype button');
|
||||||
|
buttons[0].onclick = addRadioQuestion;
|
||||||
|
buttons[1].onclick = addCheckboxQuestion;
|
||||||
|
buttons[2].onclick = addTextQuestion;
|
||||||
|
|
||||||
|
// 为保存和发布按钮添加点击事件
|
||||||
|
const pushbutButtons = document.querySelectorAll('.pushbut button');
|
||||||
|
pushbutButtons[0].onclick = saveQuestionnaire; // 保存按钮
|
||||||
|
pushbutButtons[1].onclick = publishQuestionnaire; // 发布按钮
|
||||||
|
}
|
348
js/editQuestion.js
Normal file
348
js/editQuestion.js
Normal file
@ -0,0 +1,348 @@
|
|||||||
|
let questionCount = 0;
|
||||||
|
let currentQuestionnaireId = null;
|
||||||
|
|
||||||
|
function toggleQueType() {
|
||||||
|
const queType = document.querySelector('.quetype');
|
||||||
|
const addButton = document.querySelector('.but');
|
||||||
|
|
||||||
|
if (queType.style.display === 'none') {
|
||||||
|
queType.style.display = 'flex';
|
||||||
|
addButton.style.marginTop = '0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加单选题
|
||||||
|
function addRadioQuestion(existingQuestion = null) {
|
||||||
|
questionCount++;
|
||||||
|
const questionHtml = `
|
||||||
|
<div class="question-item" id="question-${questionCount}">
|
||||||
|
<div class="question-header">
|
||||||
|
<div class="question-title-area">
|
||||||
|
<span>${questionCount}. </span>
|
||||||
|
<input type="text" placeholder="请输入问题" value="${existingQuestion ? existingQuestion.title : ''}">
|
||||||
|
<button onclick="addOption(${questionCount})">添加选项</button>
|
||||||
|
<label style="margin-left: 20px;">
|
||||||
|
<input type="checkbox" class="required-checkbox" ${existingQuestion && existingQuestion.required ? 'checked' : ''}> 此题为必答题
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="question-content" id="options-${questionCount}">
|
||||||
|
${existingQuestion ?
|
||||||
|
existingQuestion.options.map(option => `
|
||||||
|
<div class="option-item">
|
||||||
|
<input type="radio" name="question${questionCount}" disabled>
|
||||||
|
<input type="text" placeholder="选项内容" value="${option.content}">
|
||||||
|
<button class="delete-btn" onclick="deleteOption(this)">删除</button>
|
||||||
|
</div>
|
||||||
|
`).join('') :
|
||||||
|
Array(4).fill(`
|
||||||
|
<div class="option-item">
|
||||||
|
<input type="radio" name="question${questionCount}" disabled>
|
||||||
|
<input type="text" placeholder="选项内容">
|
||||||
|
<button class="delete-btn" onclick="deleteOption(this)">删除</button>
|
||||||
|
</div>
|
||||||
|
`).join('')
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<div class="ctrl-btns">
|
||||||
|
<button onclick="moveUp(${questionCount})">上移</button>
|
||||||
|
<button onclick="moveDown(${questionCount})">下移</button>
|
||||||
|
<button onclick="copyQuestion(${questionCount})">复用</button>
|
||||||
|
<button class="delete-btn" onclick="deleteQuestion(${questionCount})">删除</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
document.querySelector('.quelist').insertAdjacentHTML('beforeend', questionHtml);
|
||||||
|
toggleQueType();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加多选题
|
||||||
|
function addCheckboxQuestion(existingQuestion = null) {
|
||||||
|
questionCount++;
|
||||||
|
const questionHtml = `
|
||||||
|
<div class="question-item" id="question-${questionCount}">
|
||||||
|
<div class="question-header">
|
||||||
|
<div class="question-title-area">
|
||||||
|
<span>${questionCount}. </span>
|
||||||
|
<input type="text" placeholder="请输入问题" value="${existingQuestion ? existingQuestion.title : ''}">
|
||||||
|
<button onclick="addCheckboxOption(${questionCount})">添加选项</button>
|
||||||
|
<label style="margin-left: 20px;">
|
||||||
|
<input type="checkbox" class="required-checkbox" ${existingQuestion && existingQuestion.required ? 'checked' : ''}> 此题为必答题
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="question-content" id="options-${questionCount}">
|
||||||
|
${existingQuestion ?
|
||||||
|
existingQuestion.options.map(option => `
|
||||||
|
<div class="option-item">
|
||||||
|
<input type="checkbox" name="question${questionCount}" disabled>
|
||||||
|
<input type="text" placeholder="选项内容" value="${option.content}">
|
||||||
|
<button class="delete-btn" onclick="deleteOption(this)">删除</button>
|
||||||
|
</div>
|
||||||
|
`).join('') :
|
||||||
|
Array(4).fill(`
|
||||||
|
<div class="option-item">
|
||||||
|
<input type="checkbox" name="question${questionCount}" disabled>
|
||||||
|
<input type="text" placeholder="选项内容">
|
||||||
|
<button class="delete-btn" onclick="deleteOption(this)">删除</button>
|
||||||
|
</div>
|
||||||
|
`).join('')
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<div class="ctrl-btns">
|
||||||
|
<button onclick="moveUp(${questionCount})">上移</button>
|
||||||
|
<button onclick="moveDown(${questionCount})">下移</button>
|
||||||
|
<button onclick="copyQuestion(${questionCount})">复用</button>
|
||||||
|
<button class="delete-btn" onclick="deleteQuestion(${questionCount})">删除</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
document.querySelector('.quelist').insertAdjacentHTML('beforeend', questionHtml);
|
||||||
|
toggleQueType();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加文本题
|
||||||
|
function addTextQuestion(existingQuestion = null) {
|
||||||
|
questionCount++;
|
||||||
|
const questionHtml = `
|
||||||
|
<div class="question-item" id="question-${questionCount}">
|
||||||
|
<div class="question-header">
|
||||||
|
<div class="question-title-area">
|
||||||
|
<span>${questionCount}. </span>
|
||||||
|
<input type="text" placeholder="请输入问题" value="${existingQuestion ? existingQuestion.title : ''}">
|
||||||
|
<label style="margin-left: 20px;">
|
||||||
|
<input type="checkbox" class="required-checkbox" ${existingQuestion && existingQuestion.required ? 'checked' : ''}> 此题为必答题
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="question-content" id="options-${questionCount}">
|
||||||
|
<textarea disabled placeholder="此处供填写者输入文本答案"
|
||||||
|
style="width: 100%; min-height: 100px; padding: 8px; margin-top: 10px; resize: vertical;"></textarea>
|
||||||
|
</div>
|
||||||
|
<div class="ctrl-btns">
|
||||||
|
<button onclick="moveUp(${questionCount})">上移</button>
|
||||||
|
<button onclick="moveDown(${questionCount})">下移</button>
|
||||||
|
<button onclick="copyQuestion(${questionCount})">复用</button>
|
||||||
|
<button class="delete-btn" onclick="deleteQuestion(${questionCount})">删除</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
document.querySelector('.quelist').insertAdjacentHTML('beforeend', questionHtml);
|
||||||
|
toggleQueType();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 其他辅助函数
|
||||||
|
function addOption(questionId) {
|
||||||
|
const optionHtml = `
|
||||||
|
<div class="option-item">
|
||||||
|
<input type="radio" name="question${questionId}" disabled>
|
||||||
|
<input type="text" placeholder="选项内容">
|
||||||
|
<button class="delete-btn" onclick="deleteOption(this)">删除</button>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
document.querySelector(`#options-${questionId}`).insertAdjacentHTML('beforeend', optionHtml);
|
||||||
|
}
|
||||||
|
|
||||||
|
function addCheckboxOption(questionId) {
|
||||||
|
const optionHtml = `
|
||||||
|
<div class="option-item">
|
||||||
|
<input type="checkbox" name="question${questionId}" disabled>
|
||||||
|
<input type="text" placeholder="选项内容">
|
||||||
|
<button class="delete-btn" onclick="deleteOption(this)">删除</button>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
document.querySelector(`#options-${questionId}`).insertAdjacentHTML('beforeend', optionHtml);
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteOption(btn) {
|
||||||
|
btn.parentElement.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteQuestion(questionId) {
|
||||||
|
document.querySelector(`#question-${questionId}`).remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
function copyQuestion(questionId) {
|
||||||
|
const original = document.querySelector(`#question-${questionId}`);
|
||||||
|
const clone = original.cloneNode(true);
|
||||||
|
questionCount++;
|
||||||
|
clone.id = `question-${questionCount}`;
|
||||||
|
original.after(clone);
|
||||||
|
}
|
||||||
|
|
||||||
|
function moveUp(questionId) {
|
||||||
|
const question = document.querySelector(`#question-${questionId}`);
|
||||||
|
const prev = question.previousElementSibling;
|
||||||
|
if (prev) {
|
||||||
|
prev.before(question);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function moveDown(questionId) {
|
||||||
|
const question = document.querySelector(`#question-${questionId}`);
|
||||||
|
const next = question.nextElementSibling;
|
||||||
|
if (next) {
|
||||||
|
next.after(question);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取问卷数据
|
||||||
|
function getQuestionnaireData(isPublished = false) {
|
||||||
|
const now = new Date().getTime();
|
||||||
|
const questionnaire = {
|
||||||
|
title: document.querySelector('.question-title').value,
|
||||||
|
createTime: now,
|
||||||
|
endTime: document.querySelector('#endtime').value,
|
||||||
|
publishTime: isPublished ? now : null,
|
||||||
|
status: isPublished ? '已发布' : '未发布',
|
||||||
|
questions: []
|
||||||
|
};
|
||||||
|
|
||||||
|
const questionItems = document.querySelectorAll('.question-item');
|
||||||
|
questionItems.forEach((item, index) => {
|
||||||
|
let questionType;
|
||||||
|
if (item.querySelector('.question-content textarea')) {
|
||||||
|
questionType = 'text';
|
||||||
|
} else if (item.querySelector('input[type="radio"]')) {
|
||||||
|
questionType = 'radio';
|
||||||
|
} else {
|
||||||
|
questionType = 'checkbox';
|
||||||
|
}
|
||||||
|
|
||||||
|
const question = {
|
||||||
|
id: index + 1,
|
||||||
|
type: questionType,
|
||||||
|
title: item.querySelector('.question-title-area input[type="text"]').value,
|
||||||
|
required: item.querySelector('.required-checkbox').checked,
|
||||||
|
options: []
|
||||||
|
};
|
||||||
|
|
||||||
|
if (questionType === 'radio' || questionType === 'checkbox') {
|
||||||
|
const options = item.querySelectorAll('.option-item input[type="text"]');
|
||||||
|
options.forEach((option, optionIndex) => {
|
||||||
|
question.options.push({
|
||||||
|
id: optionIndex + 1,
|
||||||
|
content: option.value
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
questionnaire.questions.push(question);
|
||||||
|
});
|
||||||
|
|
||||||
|
return questionnaire;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加载问卷数据
|
||||||
|
function loadQuestionnaireData() {
|
||||||
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
|
const questionnaireId = urlParams.get('id');
|
||||||
|
|
||||||
|
if (!questionnaireId) {
|
||||||
|
alert('问卷ID不存在!');
|
||||||
|
window.location.href = 'myQuestion.html';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentQuestionnaireId = questionnaireId;
|
||||||
|
const questionnaireList = JSON.parse(localStorage.getItem('questionnaireList') || '[]');
|
||||||
|
const questionnaire = questionnaireList.find(q => q.id === questionnaireId);
|
||||||
|
|
||||||
|
if (!questionnaire) {
|
||||||
|
alert('问卷不存在!');
|
||||||
|
window.location.href = 'myQuestion.html';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 填充问卷数据
|
||||||
|
document.querySelector('.question-title').value = questionnaire.title;
|
||||||
|
document.querySelector('#endtime').value = questionnaire.data.endTime;
|
||||||
|
|
||||||
|
// 渲染问题列表
|
||||||
|
questionnaire.data.questions.forEach(question => {
|
||||||
|
if (question.type === 'radio') {
|
||||||
|
addRadioQuestion(question);
|
||||||
|
} else if (question.type === 'checkbox') {
|
||||||
|
addCheckboxQuestion(question);
|
||||||
|
} else {
|
||||||
|
addTextQuestion(question);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新问卷
|
||||||
|
function updateQuestionnaire() {
|
||||||
|
if (!validateQuestionnaire()) return;
|
||||||
|
|
||||||
|
const questionnaireList = JSON.parse(localStorage.getItem('questionnaireList') || '[]');
|
||||||
|
const index = questionnaireList.findIndex(q => q.id === currentQuestionnaireId);
|
||||||
|
|
||||||
|
if (index === -1) {
|
||||||
|
alert('问卷不存在!');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const updatedData = getQuestionnaireData(false);
|
||||||
|
questionnaireList[index].title = updatedData.title;
|
||||||
|
questionnaireList[index].data = updatedData;
|
||||||
|
|
||||||
|
localStorage.setItem('questionnaireList', JSON.stringify(questionnaireList));
|
||||||
|
alert('问卷修改成功!');
|
||||||
|
window.location.href = 'myQuestion.html';
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证问卷
|
||||||
|
function validateQuestionnaire() {
|
||||||
|
const title = document.querySelector('.question-title').value.trim();
|
||||||
|
if (!title) {
|
||||||
|
alert('请输入问卷标题!');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const endTime = document.querySelector('#endtime').value;
|
||||||
|
if (!endTime) {
|
||||||
|
alert('请设置问卷截止日期!');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const questions = document.querySelectorAll('.question-item');
|
||||||
|
if (questions.length === 0) {
|
||||||
|
alert('请至少添加一个问题!');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let question of questions) {
|
||||||
|
const questionTitle = question.querySelector('.question-title-area input[type="text"]').value.trim();
|
||||||
|
if (!questionTitle) {
|
||||||
|
alert('请填写所有问题的标题!');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const questionType = question.querySelector('input[type="radio"]') ? 'radio' :
|
||||||
|
question.querySelector('input[type="checkbox"]') ? 'checkbox' : 'text';
|
||||||
|
|
||||||
|
if (questionType !== 'text') {
|
||||||
|
const options = question.querySelectorAll('.option-item input[type="text"]');
|
||||||
|
for (let option of options) {
|
||||||
|
if (!option.value.trim()) {
|
||||||
|
alert('请填写所有选项的内容!');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化页面
|
||||||
|
window.onload = function() {
|
||||||
|
// 为题型按钮添加点击事件
|
||||||
|
const buttons = document.querySelectorAll('.quetype button');
|
||||||
|
buttons[0].onclick = addRadioQuestion;
|
||||||
|
buttons[1].onclick = addCheckboxQuestion;
|
||||||
|
buttons[2].onclick = addTextQuestion;
|
||||||
|
|
||||||
|
// 加载问卷数据
|
||||||
|
loadQuestionnaireData();
|
||||||
|
}
|
145
js/fillQuestion.js
Normal file
145
js/fillQuestion.js
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
let currentQuestionnaire = null;
|
||||||
|
|
||||||
|
function formatDate(timestamp) {
|
||||||
|
if (!timestamp) return '-';
|
||||||
|
const date = new Date(timestamp);
|
||||||
|
return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderQuestion(question, index) {
|
||||||
|
const questionHtml = `
|
||||||
|
<div class="question-item">
|
||||||
|
<div class="question-item-title">
|
||||||
|
${index + 1}. ${question.title}
|
||||||
|
${question.required ? '<span style="color: red; margin-left: 5px;">*</span>' : ''}
|
||||||
|
</div>
|
||||||
|
${
|
||||||
|
question.type === 'text' ?
|
||||||
|
`<div class="question-content">
|
||||||
|
<textarea class="text-answer" name="question_${question.id}"
|
||||||
|
style="width: 100%; min-height: 100px; padding: 8px; margin-top: 10px; resize: vertical;"
|
||||||
|
placeholder="请在此输入您的答案"></textarea>
|
||||||
|
</div>` :
|
||||||
|
`<div class="options">
|
||||||
|
${question.options.map(option => `
|
||||||
|
<div class="option-item">
|
||||||
|
<input type="${question.type}"
|
||||||
|
id="option_${question.id}_${option.id}"
|
||||||
|
name="question_${question.id}"
|
||||||
|
value="${option.id}">
|
||||||
|
<label for="option_${question.id}_${option.id}">${option.content}</label>
|
||||||
|
</div>
|
||||||
|
`).join('')}
|
||||||
|
</div>`
|
||||||
|
}
|
||||||
|
<div class="error-message" id="error_${question.id}">此题为必答题</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
return questionHtml;
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadQuestionnaire() {
|
||||||
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
|
const questionnaireId = urlParams.get('id');
|
||||||
|
|
||||||
|
if (!questionnaireId) {
|
||||||
|
alert('问卷ID不存在!');
|
||||||
|
window.location.href = 'myQuestion.html';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const questionnaireList = JSON.parse(localStorage.getItem('questionnaireList') || '[]');
|
||||||
|
const questionnaire = questionnaireList.find(q => q.id === questionnaireId);
|
||||||
|
|
||||||
|
if (!questionnaire) {
|
||||||
|
alert('问卷不存在!');
|
||||||
|
window.location.href = 'myQuestion.html';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (questionnaire.status !== '已发布') {
|
||||||
|
alert('该问卷尚未发布!');
|
||||||
|
window.location.href = 'myQuestion.html';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentQuestionnaire = questionnaire;
|
||||||
|
|
||||||
|
// 填充问卷信息
|
||||||
|
document.querySelector('.question-title').textContent = questionnaire.title;
|
||||||
|
document.querySelector('.end-time').textContent = formatDate(questionnaire.data.endTime);
|
||||||
|
document.querySelector('.status').textContent = questionnaire.status;
|
||||||
|
|
||||||
|
// 渲染问题列表
|
||||||
|
const questionListHtml = questionnaire.data.questions
|
||||||
|
.map((question, index) => renderQuestion(question, index))
|
||||||
|
.join('');
|
||||||
|
document.querySelector('.question-list').innerHTML = questionListHtml;
|
||||||
|
}
|
||||||
|
|
||||||
|
function validateAnswers() {
|
||||||
|
let isValid = true;
|
||||||
|
currentQuestionnaire.data.questions.forEach(question => {
|
||||||
|
if (!question.required) return;
|
||||||
|
|
||||||
|
const errorElement = document.getElementById(`error_${question.id}`);
|
||||||
|
if (question.type === 'text') {
|
||||||
|
const answer = document.querySelector(`textarea[name="question_${question.id}"]`).value.trim();
|
||||||
|
if (!answer) {
|
||||||
|
errorElement.style.display = 'block';
|
||||||
|
isValid = false;
|
||||||
|
} else {
|
||||||
|
errorElement.style.display = 'none';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const checked = document.querySelector(`input[name="question_${question.id}"]:checked`);
|
||||||
|
if (!checked) {
|
||||||
|
errorElement.style.display = 'block';
|
||||||
|
isValid = false;
|
||||||
|
} else {
|
||||||
|
errorElement.style.display = 'none';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return isValid;
|
||||||
|
}
|
||||||
|
|
||||||
|
function submitQuestionnaire() {
|
||||||
|
if (!validateAnswers()) {
|
||||||
|
alert('请回答所有问题!');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const answers = {
|
||||||
|
questionnaireId: currentQuestionnaire.id,
|
||||||
|
submitTime: new Date().getTime(),
|
||||||
|
answers: currentQuestionnaire.data.questions.map(question => {
|
||||||
|
if (question.type === 'text') {
|
||||||
|
return {
|
||||||
|
questionId: question.id,
|
||||||
|
type: question.type,
|
||||||
|
answer: document.querySelector(`textarea[name="question_${question.id}"]`).value.trim()
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
const selectedOptions = Array.from(
|
||||||
|
document.querySelectorAll(`input[name="question_${question.id}"]:checked`)
|
||||||
|
).map(input => parseInt(input.value));
|
||||||
|
return {
|
||||||
|
questionId: question.id,
|
||||||
|
type: question.type,
|
||||||
|
answer: selectedOptions
|
||||||
|
};
|
||||||
|
}
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
// 保存答案到 localStorage
|
||||||
|
let answersList = JSON.parse(localStorage.getItem('questionnaireAnswers') || '[]');
|
||||||
|
answersList.push(answers);
|
||||||
|
localStorage.setItem('questionnaireAnswers', JSON.stringify(answersList));
|
||||||
|
|
||||||
|
alert('问卷提交成功!');
|
||||||
|
window.location.href = 'myQuestion.html';
|
||||||
|
}
|
||||||
|
|
||||||
|
window.onload = loadQuestionnaire;
|
191
js/myQuestion.js
Normal file
191
js/myQuestion.js
Normal file
@ -0,0 +1,191 @@
|
|||||||
|
// 格式化时间戳为日期字符串
|
||||||
|
function formatDate(timestamp) {
|
||||||
|
if (!timestamp) return '-';
|
||||||
|
const date = new Date(timestamp);
|
||||||
|
return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 渲染问卷列表
|
||||||
|
function renderQuestionnaireList() {
|
||||||
|
// 获取问卷列表数据
|
||||||
|
const questionnaireList = JSON.parse(localStorage.getItem('questionnaireList') || '[]');
|
||||||
|
const tableBody = document.querySelector('table');
|
||||||
|
|
||||||
|
// 保留表头
|
||||||
|
const tableHeader = tableBody.rows[0];
|
||||||
|
tableBody.innerHTML = '';
|
||||||
|
tableBody.appendChild(tableHeader);
|
||||||
|
|
||||||
|
// 渲染每个问卷
|
||||||
|
questionnaireList.forEach(questionnaire => {
|
||||||
|
const tr = document.createElement('tr');
|
||||||
|
tr.innerHTML = `
|
||||||
|
<td>
|
||||||
|
<div class="item-title">
|
||||||
|
<input type="checkbox" data-id="${questionnaire.id}">
|
||||||
|
<span>${questionnaire.title}</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div class="data-row">
|
||||||
|
<span class="data-item">${formatDate(questionnaire.createTime)}</span>
|
||||||
|
<span class="data-item">${formatDate(questionnaire.publishTime)}</span>
|
||||||
|
<span class="data-item">${formatDate(questionnaire.data.endTime)}</span>
|
||||||
|
<span class="data-item">${questionnaire.status}</span>
|
||||||
|
<div class="data-item">
|
||||||
|
<button onclick="publishQuestionnaire('${questionnaire.id}')"
|
||||||
|
${questionnaire.status !== '未发布' ? 'disabled style="opacity: 0.5; cursor: not-allowed;"' : ''}>
|
||||||
|
发布问卷
|
||||||
|
</button>
|
||||||
|
<button onclick="editQuestionnaire('${questionnaire.id}')"
|
||||||
|
${questionnaire.status === '已发布' ? 'disabled style="opacity: 0.5; cursor: not-allowed;"' : ''}>
|
||||||
|
编辑问卷
|
||||||
|
</button>
|
||||||
|
<button onclick="deleteQuestionnaire('${questionnaire.id}')">
|
||||||
|
删除问卷
|
||||||
|
</button>
|
||||||
|
<button onclick="viewQuestionnaire('${questionnaire.id}')">
|
||||||
|
查看问卷
|
||||||
|
</button>
|
||||||
|
<button onclick="fillQuestionnaire('${questionnaire.id}')"
|
||||||
|
${questionnaire.status !== '已发布' || new Date().getTime() > new Date(questionnaire.data.endTime).getTime() ?
|
||||||
|
'disabled style="opacity: 0.5; cursor: not-allowed;"' : ''}>
|
||||||
|
填写问卷
|
||||||
|
</button>
|
||||||
|
<button onclick="analyzeQuestionnaire('${questionnaire.id}')"
|
||||||
|
${questionnaire.status !== '已发布' ? 'disabled style="opacity: 0.5; cursor: not-allowed;"' : ''}>
|
||||||
|
分析问卷
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
`;
|
||||||
|
tableBody.appendChild(tr);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除问卷
|
||||||
|
function deleteQuestionnaire(id) {
|
||||||
|
if (!confirm('确定要删除这份问卷吗?')) return;
|
||||||
|
|
||||||
|
let questionnaireList = JSON.parse(localStorage.getItem('questionnaireList') || '[]');
|
||||||
|
questionnaireList = questionnaireList.filter(q => q.id !== id);
|
||||||
|
localStorage.setItem('questionnaireList', JSON.stringify(questionnaireList));
|
||||||
|
renderQuestionnaireList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 批量删除问卷
|
||||||
|
function batchDeleteQuestionnaires() {
|
||||||
|
const checkedBoxes = document.querySelectorAll('input[type="checkbox"]:checked');
|
||||||
|
if (checkedBoxes.length === 0) {
|
||||||
|
alert('请先选择要删除的问卷!');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!confirm(`确定要删除选中的 ${checkedBoxes.length} 份问卷吗?`)) return;
|
||||||
|
|
||||||
|
let questionnaireList = JSON.parse(localStorage.getItem('questionnaireList') || '[]');
|
||||||
|
const idsToDelete = Array.from(checkedBoxes).map(cb => cb.dataset.id);
|
||||||
|
questionnaireList = questionnaireList.filter(q => !idsToDelete.includes(q.id));
|
||||||
|
localStorage.setItem('questionnaireList', JSON.stringify(questionnaireList));
|
||||||
|
renderQuestionnaireList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 全选/取消全选
|
||||||
|
function toggleSelectAll() {
|
||||||
|
const selectAllCheckbox = document.querySelector('.ctrl-all input[type="checkbox"]');
|
||||||
|
const allCheckboxes = document.querySelectorAll('table input[type="checkbox"]');
|
||||||
|
allCheckboxes.forEach(cb => cb.checked = selectAllCheckbox.checked);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 发布问卷
|
||||||
|
function publishQuestionnaire(id) {
|
||||||
|
let questionnaireList = JSON.parse(localStorage.getItem('questionnaireList') || '[]');
|
||||||
|
const index = questionnaireList.findIndex(q => q.id === id);
|
||||||
|
if (index !== -1) {
|
||||||
|
const now = new Date().getTime();
|
||||||
|
questionnaireList[index].publishTime = now;
|
||||||
|
questionnaireList[index].status = '已发布';
|
||||||
|
questionnaireList[index].data.publishTime = now;
|
||||||
|
questionnaireList[index].data.status = '已发布';
|
||||||
|
localStorage.setItem('questionnaireList', JSON.stringify(questionnaireList));
|
||||||
|
renderQuestionnaireList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新建问卷
|
||||||
|
function createNewQuestionnaire() {
|
||||||
|
window.location.href = 'createQuestion.html';
|
||||||
|
}
|
||||||
|
|
||||||
|
window.onload = function() {
|
||||||
|
renderQuestionnaireList();
|
||||||
|
document.querySelector('.ctrl-all input[type="checkbox"]')
|
||||||
|
.addEventListener('change', toggleSelectAll);
|
||||||
|
document.querySelector('.ctrl-all button')
|
||||||
|
.addEventListener('click', batchDeleteQuestionnaires);
|
||||||
|
document.querySelector('.grid-item-add')
|
||||||
|
.addEventListener('click', createNewQuestionnaire);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 编辑问卷
|
||||||
|
function editQuestionnaire(id) {
|
||||||
|
window.location.href = `editQuestion.html?id=${id}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查看问卷
|
||||||
|
function viewQuestionnaire(id) {
|
||||||
|
window.location.href = `viewQuestion.html?id=${id}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 填写问卷
|
||||||
|
function fillQuestionnaire(id) {
|
||||||
|
// 检查问卷状态
|
||||||
|
const questionnaireList = JSON.parse(localStorage.getItem('questionnaireList') || '[]');
|
||||||
|
const questionnaire = questionnaireList.find(q => q.id === id);
|
||||||
|
|
||||||
|
if (!questionnaire) {
|
||||||
|
alert('问卷不存在!');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (questionnaire.status !== '已发布') {
|
||||||
|
alert('该问卷尚未发布,无法填写!');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const endTime = new Date(questionnaire.data.endTime).getTime();
|
||||||
|
const now = new Date().getTime();
|
||||||
|
if (now > endTime) {
|
||||||
|
alert('该问卷已过期!');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 跳转到填写问卷页面
|
||||||
|
window.location.href = `fillQuestion.html?id=${id}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 分析问卷
|
||||||
|
function analyzeQuestionnaire(id) {
|
||||||
|
const questionnaireList = JSON.parse(localStorage.getItem('questionnaireList') || '[]');
|
||||||
|
const questionnaire = questionnaireList.find(q => q.id === id);
|
||||||
|
|
||||||
|
if (!questionnaire) {
|
||||||
|
alert('问卷不存在!');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (questionnaire.status !== '已发布') {
|
||||||
|
alert('未发布的问卷无法查看分析结果!');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const answers = JSON.parse(localStorage.getItem('questionnaireAnswers') || '[]');
|
||||||
|
const hasAnswers = answers.some(a => a.questionnaireId === id);
|
||||||
|
|
||||||
|
if (!hasAnswers) {
|
||||||
|
alert('暂无人填写该问卷,无法查看分析结果!');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.location.href = `analyzeQuestion.html?id=${id}`;
|
||||||
|
}
|
68
js/viewQuestion.js
Normal file
68
js/viewQuestion.js
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
function formatDate(timestamp) {
|
||||||
|
if (!timestamp) return '-';
|
||||||
|
const date = new Date(timestamp);
|
||||||
|
return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderQuestion(question, index) {
|
||||||
|
const questionHtml = `
|
||||||
|
<div class="question-item">
|
||||||
|
<div class="question-item-title">
|
||||||
|
${index + 1}. ${question.title}
|
||||||
|
${question.required ? '<span style="color: red; margin-left: 5px;">*(必答题)</span>' : ''}
|
||||||
|
</div>
|
||||||
|
${
|
||||||
|
question.type === 'text' ?
|
||||||
|
`<div class="question-content">
|
||||||
|
<textarea class="text-answer" disabled
|
||||||
|
style="width: 100%; min-height: 100px; padding: 8px; margin-top: 10px; resize: vertical; background-color: #f5f5f5;"
|
||||||
|
placeholder="此处填写答案"></textarea>
|
||||||
|
</div>` :
|
||||||
|
`<div class="options">
|
||||||
|
${question.options.map(option => `
|
||||||
|
<div class="option-item">
|
||||||
|
<input type="${question.type}" name="question${index}" disabled>
|
||||||
|
<span>${option.content}</span>
|
||||||
|
</div>
|
||||||
|
`).join('')}
|
||||||
|
</div>`
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
return questionHtml;
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadQuestionnaire() {
|
||||||
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
|
const questionnaireId = urlParams.get('id');
|
||||||
|
|
||||||
|
if (!questionnaireId) {
|
||||||
|
alert('问卷ID不存在!');
|
||||||
|
window.location.href = 'myQuestion.html';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const questionnaireList = JSON.parse(localStorage.getItem('questionnaireList') || '[]');
|
||||||
|
const questionnaire = questionnaireList.find(q => q.id === questionnaireId);
|
||||||
|
|
||||||
|
if (!questionnaire) {
|
||||||
|
alert('问卷不存在!');
|
||||||
|
window.location.href = 'myQuestion.html';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 填充问卷信息
|
||||||
|
document.querySelector('.question-title').textContent = questionnaire.title;
|
||||||
|
document.querySelector('.create-time').textContent = formatDate(questionnaire.createTime);
|
||||||
|
document.querySelector('.publish-time').textContent = formatDate(questionnaire.publishTime);
|
||||||
|
document.querySelector('.end-time').textContent = formatDate(questionnaire.data.endTime);
|
||||||
|
document.querySelector('.status').textContent = questionnaire.status;
|
||||||
|
|
||||||
|
// 渲染问题列表
|
||||||
|
const questionListHtml = questionnaire.data.questions
|
||||||
|
.map((question, index) => renderQuestion(question, index))
|
||||||
|
.join('');
|
||||||
|
document.querySelector('.question-list').innerHTML = questionListHtml;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.onload = loadQuestionnaire;
|
@ -5,156 +5,9 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>问卷分析</title>
|
<title>问卷分析</title>
|
||||||
<!-- 引入 Chart.js -->
|
<!-- 引入 Chart.js -->
|
||||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
<script src="../js/chart.js"></script>
|
||||||
<style>
|
<link rel="stylesheet" href="../css/analyzeQuestion.css">
|
||||||
* {
|
<script src="../js/analyzeQuestion.js"></script>
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
body {
|
|
||||||
background: #C3C3C3;
|
|
||||||
}
|
|
||||||
header {
|
|
||||||
background-color: #CF9A30;
|
|
||||||
color: #EEE8E4;
|
|
||||||
text-align: start;
|
|
||||||
padding: 20px;
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
main {
|
|
||||||
padding: 30px 0;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
.box {
|
|
||||||
width: 90%;
|
|
||||||
padding: 14px;
|
|
||||||
background-color: #EBEBEB;
|
|
||||||
box-shadow: 1px 2px 2px rgba(0,0,0,0.4);
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
.quesen{
|
|
||||||
width: 32px;
|
|
||||||
height: 32px;
|
|
||||||
font-size: 28px;
|
|
||||||
font-weight: bold;
|
|
||||||
text-align: center;
|
|
||||||
line-height: 24px;
|
|
||||||
color: #CF9A30;
|
|
||||||
border-radius: 50px;
|
|
||||||
padding-top: 5px;
|
|
||||||
background-color: #EBEBEB;
|
|
||||||
position: absolute;
|
|
||||||
font-style: normal;
|
|
||||||
top: 14px;
|
|
||||||
left: 60px;
|
|
||||||
}
|
|
||||||
.title{
|
|
||||||
margin-left: 80px;
|
|
||||||
font-size: 24px;
|
|
||||||
line-height: 20px;
|
|
||||||
font-weight: bold;
|
|
||||||
margin-right: 60px;
|
|
||||||
}
|
|
||||||
.nav-bar a {
|
|
||||||
line-height: 20px;
|
|
||||||
font-size: 20px;
|
|
||||||
color: #EEE8E4;
|
|
||||||
border: 2px solid #c78501;
|
|
||||||
padding: 2px;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.question-title {
|
|
||||||
width: 100%;
|
|
||||||
padding: 20px;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 24px;
|
|
||||||
font-weight: bold;
|
|
||||||
background: #CEEACA;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
border-radius: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.question-info {
|
|
||||||
width: 100%;
|
|
||||||
padding: 10px;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-around;
|
|
||||||
background: #fff;
|
|
||||||
border-radius: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.question-item {
|
|
||||||
width: 100%;
|
|
||||||
margin: 10px 0;
|
|
||||||
padding: 20px;
|
|
||||||
background: #fff;
|
|
||||||
border-radius: 2px;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: flex-start;
|
|
||||||
}
|
|
||||||
|
|
||||||
.question-content {
|
|
||||||
flex: 1;
|
|
||||||
padding-right: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.question-item-title {
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: bold;
|
|
||||||
margin-bottom: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.option-item {
|
|
||||||
margin: 10px 0;
|
|
||||||
padding: 5px 0;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.option-item span {
|
|
||||||
margin-right: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chart-container {
|
|
||||||
width: 300px;
|
|
||||||
height: 300px;
|
|
||||||
margin-left: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.back-button {
|
|
||||||
margin-top: 20px;
|
|
||||||
padding: 8px 24px;
|
|
||||||
background: #CF9A30;
|
|
||||||
color: #fff;
|
|
||||||
border: none;
|
|
||||||
border-radius: 2px;
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.back-button:hover {
|
|
||||||
background: #c78501;
|
|
||||||
}
|
|
||||||
|
|
||||||
.total-responses {
|
|
||||||
margin-top: 10px;
|
|
||||||
font-size: 16px;
|
|
||||||
color: #666;
|
|
||||||
}
|
|
||||||
|
|
||||||
.question-list{
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header>
|
<header>
|
||||||
@ -178,198 +31,5 @@
|
|||||||
<button class="back-button" onclick="window.location.href='myQuestion.html'">返回列表</button>
|
<button class="back-button" onclick="window.location.href='myQuestion.html'">返回列表</button>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script>
|
|
||||||
let currentQuestionnaire = null;
|
|
||||||
let questionnaireAnswers = [];
|
|
||||||
|
|
||||||
function formatDate(timestamp) {
|
|
||||||
if (!timestamp) return '-';
|
|
||||||
const date = new Date(timestamp);
|
|
||||||
return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
function renderPieChart(containerId, labels, data) {
|
|
||||||
const ctx = document.getElementById(containerId).getContext('2d');
|
|
||||||
return new Chart(ctx, {
|
|
||||||
type: 'pie',
|
|
||||||
data: {
|
|
||||||
labels: labels,
|
|
||||||
datasets: [{
|
|
||||||
data: data,
|
|
||||||
backgroundColor: [
|
|
||||||
'#FF6384',
|
|
||||||
'#36A2EB',
|
|
||||||
'#FFCE56',
|
|
||||||
'#4BC0C0',
|
|
||||||
'#9966FF',
|
|
||||||
'#FF9F40'
|
|
||||||
]
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
options: {
|
|
||||||
responsive: true,
|
|
||||||
maintainAspectRatio: false
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function renderBarChart(containerId, validCount, invalidCount) {
|
|
||||||
const ctx = document.getElementById(containerId).getContext('2d');
|
|
||||||
return new Chart(ctx, {
|
|
||||||
type: 'bar',
|
|
||||||
data: {
|
|
||||||
labels: ['有效回答', '无效回答'],
|
|
||||||
datasets: [{
|
|
||||||
data: [validCount, invalidCount],
|
|
||||||
backgroundColor: ['#36A2EB', '#FF6384']
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
options: {
|
|
||||||
responsive: true,
|
|
||||||
maintainAspectRatio: false,
|
|
||||||
scales: {
|
|
||||||
y: {
|
|
||||||
beginAtZero: true,
|
|
||||||
ticks: {
|
|
||||||
stepSize: 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
plugins: {
|
|
||||||
legend: {
|
|
||||||
display: false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function analyzeAnswers(question) {
|
|
||||||
const answers = questionnaireAnswers.map(response =>
|
|
||||||
response.answers.find(a => a.questionId === question.id)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (question.type === 'text') {
|
|
||||||
const validCount = answers.filter(a => a && a.answer && a.answer.trim()).length;
|
|
||||||
const invalidCount = answers.length - validCount;
|
|
||||||
return { validCount, invalidCount };
|
|
||||||
} else {
|
|
||||||
const optionCounts = {};
|
|
||||||
question.options.forEach(opt => optionCounts[opt.id] = 0);
|
|
||||||
|
|
||||||
answers.forEach(answer => {
|
|
||||||
if (answer && answer.answer) {
|
|
||||||
const selectedOptions = Array.isArray(answer.answer) ? answer.answer : [answer.answer];
|
|
||||||
selectedOptions.forEach(optId => {
|
|
||||||
if (optionCounts[optId] !== undefined) {
|
|
||||||
optionCounts[optId]++;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return optionCounts;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function renderQuestion(question, index) {
|
|
||||||
const analysis = analyzeAnswers(question);
|
|
||||||
const chartId = `chart_${question.id}`;
|
|
||||||
|
|
||||||
let questionHtml = `
|
|
||||||
<div class="question-item">
|
|
||||||
<div class="question-content">
|
|
||||||
<div class="question-item-title">
|
|
||||||
${index + 1}. ${question.title}
|
|
||||||
${question.required ? '<span style="color: red; margin-left: 5px;">*(必答题)</span>' : ''}
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
|
|
||||||
if (question.type === 'text') {
|
|
||||||
questionHtml += `
|
|
||||||
<div class="text-analysis">
|
|
||||||
<div class="question-content">
|
|
||||||
<textarea class="text-answer" disabled
|
|
||||||
style="width: 100%; min-height: 100px; padding: 8px; margin-top: 10px; resize: vertical; background-color: #f5f5f5;"
|
|
||||||
placeholder="此处填写答案"></textarea>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="chart-container">
|
|
||||||
<canvas id="${chartId}"></canvas>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
|
|
||||||
setTimeout(() => renderBarChart(chartId, analysis.validCount, analysis.invalidCount), 0);
|
|
||||||
} else {
|
|
||||||
questionHtml += `
|
|
||||||
<div class="options">
|
|
||||||
${question.options.map(option => `
|
|
||||||
<div class="option-item">
|
|
||||||
<input type="${question.type}" disabled>
|
|
||||||
<label>${option.content}</label>
|
|
||||||
<span style="margin-left: 10px;"></span>
|
|
||||||
</div>
|
|
||||||
`).join('')}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="chart-container">
|
|
||||||
<canvas id="${chartId}"></canvas>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
|
|
||||||
setTimeout(() => renderPieChart(
|
|
||||||
chartId,
|
|
||||||
question.options.map(opt => opt.content),
|
|
||||||
question.options.map(opt => analysis[opt.id])
|
|
||||||
), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
questionHtml += `</div>`;
|
|
||||||
return questionHtml;
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadQuestionnaireData() {
|
|
||||||
const urlParams = new URLSearchParams(window.location.search);
|
|
||||||
const questionnaireId = urlParams.get('id');
|
|
||||||
|
|
||||||
if (!questionnaireId) {
|
|
||||||
alert('问卷ID不存在!');
|
|
||||||
window.location.href = 'myQuestion.html';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const questionnaireList = JSON.parse(localStorage.getItem('questionnaireList') || '[]');
|
|
||||||
const questionnaire = questionnaireList.find(q => q.id === questionnaireId);
|
|
||||||
|
|
||||||
if (!questionnaire) {
|
|
||||||
alert('问卷不存在!');
|
|
||||||
window.location.href = 'myQuestion.html';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
currentQuestionnaire = questionnaire;
|
|
||||||
|
|
||||||
// 获取问卷答案
|
|
||||||
const allAnswers = JSON.parse(localStorage.getItem('questionnaireAnswers') || '[]');
|
|
||||||
questionnaireAnswers = allAnswers.filter(a => a.questionnaireId === questionnaireId);
|
|
||||||
|
|
||||||
// 填充问卷信息
|
|
||||||
document.querySelector('.question-title').textContent = questionnaire.title;
|
|
||||||
document.querySelector('.create-time').textContent = formatDate(questionnaire.createTime);
|
|
||||||
document.querySelector('.publish-time').textContent = formatDate(questionnaire.publishTime);
|
|
||||||
document.querySelector('.end-time').textContent = formatDate(questionnaire.data.endTime);
|
|
||||||
document.querySelector('.status').textContent = questionnaire.status;
|
|
||||||
document.querySelector('.response-count').textContent = questionnaireAnswers.length;
|
|
||||||
|
|
||||||
// 渲染问题列表
|
|
||||||
const questionListHtml = questionnaire.data.questions
|
|
||||||
.map((question, index) => renderQuestion(question, index))
|
|
||||||
.join('');
|
|
||||||
document.querySelector('.question-list').innerHTML = questionListHtml;
|
|
||||||
}
|
|
||||||
|
|
||||||
window.onload = loadQuestionnaireData;
|
|
||||||
</script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
@ -4,208 +4,8 @@
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>创建问卷</title>
|
<title>创建问卷</title>
|
||||||
<style>
|
<link rel="stylesheet" href="../css/createQuestion.css">
|
||||||
* {
|
<script src="../js/createQuestion.js"></script>
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
body {
|
|
||||||
background: #C3C3C3;
|
|
||||||
}
|
|
||||||
header {
|
|
||||||
background-color: #CF9A30;
|
|
||||||
color: #EEE8E4;
|
|
||||||
text-align: start;
|
|
||||||
padding: 20px;
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
main {
|
|
||||||
padding: 30px 0;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
.box {
|
|
||||||
width: 90%;
|
|
||||||
padding: 14px;
|
|
||||||
background-color: #EBEBEB;
|
|
||||||
box-shadow: 1px 2px 2px rgba(0,0,0,0.4);
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
a{
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
.quesen{
|
|
||||||
width: 32px;
|
|
||||||
height: 32px;
|
|
||||||
font-size: 28px;
|
|
||||||
font-weight: bold;
|
|
||||||
text-align: center;
|
|
||||||
line-height: 24px;
|
|
||||||
color: #CF9A30;
|
|
||||||
border-radius: 50px;
|
|
||||||
padding-top: 5px;
|
|
||||||
background-color: #EBEBEB;
|
|
||||||
position: absolute;
|
|
||||||
font-style: normal;
|
|
||||||
top: 14px;
|
|
||||||
left: 60px;
|
|
||||||
}
|
|
||||||
.title{
|
|
||||||
margin-left: 80px;
|
|
||||||
font-size: 24px;
|
|
||||||
line-height: 20px;
|
|
||||||
font-weight: bold;
|
|
||||||
margin-right: 60px;
|
|
||||||
}
|
|
||||||
.nav-bar{
|
|
||||||
a{
|
|
||||||
line-height: 20px;
|
|
||||||
font-size: 20px;
|
|
||||||
color: #EEE8E4;
|
|
||||||
border: 2px solid #c78501;
|
|
||||||
padding: 2px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.question-title{
|
|
||||||
width: 100%;
|
|
||||||
height: 68px;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 24px;
|
|
||||||
font-weight: bold;
|
|
||||||
color: #000;
|
|
||||||
background: #CEEACA;
|
|
||||||
box-shadow: 1px 2px 2px rgba(0,0,0,0.4);
|
|
||||||
border-radius: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.question-title:hover{
|
|
||||||
background: #FCFF00;
|
|
||||||
}
|
|
||||||
.but{
|
|
||||||
width: 99%;
|
|
||||||
height: 40px;
|
|
||||||
background-color: #D3D3D3;
|
|
||||||
margin-bottom: 25px;
|
|
||||||
text-align: center;
|
|
||||||
line-height: 40px;
|
|
||||||
font-size: 20px;
|
|
||||||
font-weight: bold;
|
|
||||||
color: #000000;
|
|
||||||
padding: 10px 0 50px 0;
|
|
||||||
transition: margin-top 0.3s;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
hr{
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
.ctrl-bar{
|
|
||||||
width: 100%;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
margin: 20px 0;
|
|
||||||
}
|
|
||||||
.endtime{
|
|
||||||
margin-left: 20%;
|
|
||||||
span{
|
|
||||||
margin-right: 16px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.pushbut{
|
|
||||||
margin-right: 20%;
|
|
||||||
button{
|
|
||||||
margin-right: 10px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.quetype{
|
|
||||||
margin-top: 20px;
|
|
||||||
padding: 20px 20%;
|
|
||||||
width: 99%;
|
|
||||||
border: 1px solid #b3b3b3;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
button {
|
|
||||||
font-size: 16px;
|
|
||||||
line-height: 16px;
|
|
||||||
padding: 1px 25px;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
.question-item {
|
|
||||||
width: 99%;
|
|
||||||
margin: 20px 0;
|
|
||||||
padding: 20px;
|
|
||||||
background: #fff;
|
|
||||||
border: 1px solid #ddd;
|
|
||||||
box-shadow: 1px 2px 2px rgba(0,0,0,0.1);
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.question-header {
|
|
||||||
display: block;
|
|
||||||
margin-bottom: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.question-content input[type="text"] {
|
|
||||||
width: 100%;
|
|
||||||
padding: 8px;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
border: 1px solid #ddd;
|
|
||||||
}
|
|
||||||
|
|
||||||
.option-item {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
margin: 10px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.option-item input[type="text"] {
|
|
||||||
margin-left: 10px;
|
|
||||||
width: 80%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.delete-btn {
|
|
||||||
padding: 2px 8px;
|
|
||||||
background: #ff4d4f;
|
|
||||||
color: white;
|
|
||||||
border: none;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ctrl-btns {
|
|
||||||
display: none;
|
|
||||||
position: absolute;
|
|
||||||
bottom: 10px;
|
|
||||||
right: 10px;
|
|
||||||
gap: 10px;
|
|
||||||
background: rgba(255, 255, 255, 0.9);
|
|
||||||
padding: 5px;
|
|
||||||
border-radius: 4px;
|
|
||||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.ctrl-btns button {
|
|
||||||
padding: 2px 8px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.quelist{
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.question-item:hover .ctrl-btns {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
.question-content {
|
|
||||||
margin-bottom: 40px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header>
|
<header>
|
||||||
@ -220,9 +20,9 @@
|
|||||||
<input class="question-title" type="text" value="请在这里输入问卷的标题">
|
<input class="question-title" type="text" value="请在这里输入问卷的标题">
|
||||||
<div class="quelist"></div>
|
<div class="quelist"></div>
|
||||||
<div class="quetype" style="display: none;">
|
<div class="quetype" style="display: none;">
|
||||||
<button><img style="width: 16px; height: 16px;" src="/img/radio.svg" alt="">单选题</button>
|
<button><img style="width: 16px; height: 16px;" src="../img/radio.svg" alt="">单选题</button>
|
||||||
<button><img style="width: 16px; height: 16px;" src="/img/checkbox.svg" alt="">多选题</button>
|
<button><img style="width: 16px; height: 16px;" src="../img/checkbox.svg" alt="">多选题</button>
|
||||||
<button><img style="width: 16px; height: 16px;" src="/img/text.svg" alt="">文本题</button>
|
<button><img style="width: 16px; height: 16px;" src="../img/text.svg" alt="">文本题</button>
|
||||||
</div>
|
</div>
|
||||||
<a href="javascript:void(0)" class="but" onclick="toggleQueType()">+ 添加问题</a>
|
<a href="javascript:void(0)" class="but" onclick="toggleQueType()">+ 添加问题</a>
|
||||||
<hr>
|
<hr>
|
||||||
@ -238,378 +38,5 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
<script>
|
|
||||||
let questionCount = 0;
|
|
||||||
|
|
||||||
function toggleQueType() {
|
|
||||||
const queType = document.querySelector('.quetype');
|
|
||||||
const addButton = document.querySelector('.but');
|
|
||||||
|
|
||||||
if (queType.style.display === 'none') {
|
|
||||||
queType.style.display = 'flex';
|
|
||||||
addButton.style.marginTop = '0';
|
|
||||||
}
|
|
||||||
// else {
|
|
||||||
// queType.style.display = 'none';
|
|
||||||
// addButton.style.marginTop = '20px';
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
// 添加单选题
|
|
||||||
function addRadioQuestion() {
|
|
||||||
questionCount++;
|
|
||||||
const questionHtml = `
|
|
||||||
<div class="question-item" id="question-${questionCount}">
|
|
||||||
<div class="question-header">
|
|
||||||
<div class="question-title-area">
|
|
||||||
<span>${questionCount}. </span>
|
|
||||||
<input type="text" placeholder="请输入问题">
|
|
||||||
<button onclick="addOption(${questionCount})">添加选项</button>
|
|
||||||
<label style="margin-left: 20px;">
|
|
||||||
<input type="checkbox" class="required-checkbox"> 此题为必答题
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="question-content" id="options-${questionCount}">
|
|
||||||
<div class="option-item">
|
|
||||||
<input type="radio" name="question${questionCount}" disabled>
|
|
||||||
<input type="text" placeholder="选项内容">
|
|
||||||
<button class="delete-btn" onclick="deleteOption(this)">删除</button>
|
|
||||||
</div>
|
|
||||||
<div class="option-item">
|
|
||||||
<input type="radio" name="question${questionCount}" disabled>
|
|
||||||
<input type="text" placeholder="选项内容">
|
|
||||||
<button class="delete-btn" onclick="deleteOption(this)">删除</button>
|
|
||||||
</div>
|
|
||||||
<div class="option-item">
|
|
||||||
<input type="radio" name="question${questionCount}" disabled>
|
|
||||||
<input type="text" placeholder="选项内容">
|
|
||||||
<button class="delete-btn" onclick="deleteOption(this)">删除</button>
|
|
||||||
</div>
|
|
||||||
<div class="option-item">
|
|
||||||
<input type="radio" name="question${questionCount}" disabled>
|
|
||||||
<input type="text" placeholder="选项内容">
|
|
||||||
<button class="delete-btn" onclick="deleteOption(this)">删除</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="ctrl-btns">
|
|
||||||
<button onclick="moveUp(${questionCount})">上移</button>
|
|
||||||
<button onclick="moveDown(${questionCount})">下移</button>
|
|
||||||
<button onclick="copyQuestion(${questionCount})">复用</button>
|
|
||||||
<button class="delete-btn" onclick="deleteQuestion(${questionCount})">删除</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
document.querySelector('.quelist').insertAdjacentHTML('beforeend', questionHtml);
|
|
||||||
toggleQueType();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 添加选项
|
|
||||||
function addOption(questionId) {
|
|
||||||
const optionHtml = `
|
|
||||||
<div class="option-item">
|
|
||||||
<input type="radio" disabled>
|
|
||||||
<input type="text" placeholder="选项内容">
|
|
||||||
<button class="delete-btn" onclick="deleteOption(this)">删除</button>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
document.querySelector(`#options-${questionId}`).insertAdjacentHTML('beforeend', optionHtml);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 删除选项
|
|
||||||
function deleteOption(btn) {
|
|
||||||
btn.parentElement.remove();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 删除问题
|
|
||||||
function deleteQuestion(questionId) {
|
|
||||||
document.querySelector(`#question-${questionId}`).remove();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 复用问题
|
|
||||||
function copyQuestion(questionId) {
|
|
||||||
const original = document.querySelector(`#question-${questionId}`);
|
|
||||||
const clone = original.cloneNode(true);
|
|
||||||
questionCount++;
|
|
||||||
clone.id = `question-${questionCount}`;
|
|
||||||
original.after(clone);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 上移问题
|
|
||||||
function moveUp(questionId) {
|
|
||||||
const question = document.querySelector(`#question-${questionId}`);
|
|
||||||
const prev = question.previousElementSibling;
|
|
||||||
if (prev) {
|
|
||||||
prev.before(question);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 下移问题
|
|
||||||
function moveDown(questionId) {
|
|
||||||
const question = document.querySelector(`#question-${questionId}`);
|
|
||||||
const next = question.nextElementSibling;
|
|
||||||
if (next) {
|
|
||||||
next.after(question);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 添加多选题
|
|
||||||
function addCheckboxQuestion() {
|
|
||||||
questionCount++;
|
|
||||||
const questionHtml = `
|
|
||||||
<div class="question-item" id="question-${questionCount}">
|
|
||||||
<div class="question-header">
|
|
||||||
<div class="question-title-area">
|
|
||||||
<span>${questionCount}. </span>
|
|
||||||
<input type="text" placeholder="请输入问题">
|
|
||||||
<button onclick="addCheckboxOption(${questionCount})">添加选项</button>
|
|
||||||
<label style="margin-left: 20px;">
|
|
||||||
<input type="checkbox" class="required-checkbox"> 此题为必答题
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="question-content" id="options-${questionCount}">
|
|
||||||
<div class="option-item">
|
|
||||||
<input type="checkbox" name="question${questionCount}" disabled>
|
|
||||||
<input type="text" placeholder="选项内容">
|
|
||||||
<button class="delete-btn" onclick="deleteOption(this)">删除</button>
|
|
||||||
</div>
|
|
||||||
<div class="option-item">
|
|
||||||
<input type="checkbox" name="question${questionCount}" disabled>
|
|
||||||
<input type="text" placeholder="选项内容">
|
|
||||||
<button class="delete-btn" onclick="deleteOption(this)">删除</button>
|
|
||||||
</div>
|
|
||||||
<div class="option-item">
|
|
||||||
<input type="checkbox" name="question${questionCount}" disabled>
|
|
||||||
<input type="text" placeholder="选项内容">
|
|
||||||
<button class="delete-btn" onclick="deleteOption(this)">删除</button>
|
|
||||||
</div>
|
|
||||||
<div class="option-item">
|
|
||||||
<input type="checkbox" name="question${questionCount}" disabled>
|
|
||||||
<input type="text" placeholder="选项内容">
|
|
||||||
<button class="delete-btn" onclick="deleteOption(this)">删除</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="ctrl-btns">
|
|
||||||
<button onclick="moveUp(${questionCount})">上移</button>
|
|
||||||
<button onclick="moveDown(${questionCount})">下移</button>
|
|
||||||
<button onclick="copyQuestion(${questionCount})">复用</button>
|
|
||||||
<button class="delete-btn" onclick="deleteQuestion(${questionCount})">删除</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
document.querySelector('.quelist').insertAdjacentHTML('beforeend', questionHtml);
|
|
||||||
toggleQueType();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 添加多选题选项
|
|
||||||
function addCheckboxOption(questionId) {
|
|
||||||
const optionHtml = `
|
|
||||||
<div class="option-item">
|
|
||||||
<input type="checkbox" disabled>
|
|
||||||
<input type="text" placeholder="选项内容">
|
|
||||||
<button class="delete-btn" onclick="deleteOption(this)">删除</button>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
document.querySelector(`#options-${questionId}`).insertAdjacentHTML('beforeend', optionHtml);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 添加文本题
|
|
||||||
function addTextQuestion() {
|
|
||||||
questionCount++;
|
|
||||||
const questionHtml = `
|
|
||||||
<div class="question-item" id="question-${questionCount}">
|
|
||||||
<div class="question-header">
|
|
||||||
<div class="question-title-area">
|
|
||||||
<span>${questionCount}. </span>
|
|
||||||
<input type="text" placeholder="请输入问题">
|
|
||||||
<label style="margin-left: 20px;">
|
|
||||||
<input type="checkbox" class="required-checkbox"> 此题为必答题
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="question-content" id="options-${questionCount}">
|
|
||||||
<textarea disabled placeholder="此处供填写者输入文本答案"
|
|
||||||
style="width: 100%; min-height: 100px; padding: 8px; margin-top: 10px; resize: vertical;"></textarea>
|
|
||||||
</div>
|
|
||||||
<div class="ctrl-btns">
|
|
||||||
<button onclick="moveUp(${questionCount})">上移</button>
|
|
||||||
<button onclick="moveDown(${questionCount})">下移</button>
|
|
||||||
<button onclick="copyQuestion(${questionCount})">复用</button>
|
|
||||||
<button class="delete-btn" onclick="deleteQuestion(${questionCount})">删除</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
document.querySelector('.quelist').insertAdjacentHTML('beforeend', questionHtml);
|
|
||||||
toggleQueType();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取问卷数据
|
|
||||||
function getQuestionnaireData(isPublished = false) {
|
|
||||||
const now = new Date().getTime();
|
|
||||||
const questionnaire = {
|
|
||||||
title: document.querySelector('.question-title').value,
|
|
||||||
createTime: now,
|
|
||||||
endTime: document.querySelector('#endtime').value,
|
|
||||||
publishTime: isPublished ? now : null,
|
|
||||||
status: isPublished ? '已发布' : '未发布',
|
|
||||||
questions: []
|
|
||||||
};
|
|
||||||
|
|
||||||
const questionItems = document.querySelectorAll('.question-item');
|
|
||||||
questionItems.forEach((item, index) => {
|
|
||||||
let questionType;
|
|
||||||
if (item.querySelector('.question-content textarea')) {
|
|
||||||
questionType = 'text';
|
|
||||||
} else if (item.querySelector('input[type="radio"]')) {
|
|
||||||
questionType = 'radio';
|
|
||||||
} else {
|
|
||||||
questionType = 'checkbox';
|
|
||||||
}
|
|
||||||
|
|
||||||
const question = {
|
|
||||||
id: index + 1,
|
|
||||||
type: questionType,
|
|
||||||
title: item.querySelector('.question-title-area input[type="text"]').value,
|
|
||||||
required: item.querySelector('.required-checkbox').checked,
|
|
||||||
options: []
|
|
||||||
};
|
|
||||||
|
|
||||||
if (questionType === 'radio' || questionType === 'checkbox') {
|
|
||||||
const options = item.querySelectorAll('.option-item input[type="text"]');
|
|
||||||
options.forEach((option, optionIndex) => {
|
|
||||||
question.options.push({
|
|
||||||
id: optionIndex + 1,
|
|
||||||
content: option.value
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
questionnaire.questions.push(question);
|
|
||||||
});
|
|
||||||
|
|
||||||
return questionnaire;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 保存问卷到 localStorage
|
|
||||||
function saveQuestionnaire() {
|
|
||||||
// 验证问卷
|
|
||||||
if (!validateQuestionnaire()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const questionnaire = getQuestionnaireData(false);
|
|
||||||
const questionnaireId = `questionnaire_${questionnaire.createTime}`;
|
|
||||||
|
|
||||||
// 获取已有的问卷列表
|
|
||||||
let questionnaireList = JSON.parse(localStorage.getItem('questionnaireList') || '[]');
|
|
||||||
|
|
||||||
// 添加新问卷
|
|
||||||
questionnaireList.push({
|
|
||||||
id: questionnaireId,
|
|
||||||
title: questionnaire.title,
|
|
||||||
createTime: questionnaire.createTime,
|
|
||||||
publishTime: questionnaire.publishTime,
|
|
||||||
status: questionnaire.status,
|
|
||||||
data: questionnaire
|
|
||||||
});
|
|
||||||
|
|
||||||
// 保存更新后的问卷列表
|
|
||||||
localStorage.setItem('questionnaireList', JSON.stringify(questionnaireList));
|
|
||||||
|
|
||||||
alert('问卷保存成功!');
|
|
||||||
window.location.href = 'myQuestion.html'; // 添加返回功能
|
|
||||||
}
|
|
||||||
|
|
||||||
// 发布问卷
|
|
||||||
function publishQuestionnaire() {
|
|
||||||
// 验证问卷
|
|
||||||
if (!validateQuestionnaire()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const questionnaire = getQuestionnaireData(true);
|
|
||||||
const questionnaireId = `questionnaire_${questionnaire.createTime}`;
|
|
||||||
|
|
||||||
// 获取已有的问卷列表
|
|
||||||
let questionnaireList = JSON.parse(localStorage.getItem('questionnaireList') || '[]');
|
|
||||||
|
|
||||||
// 添加新问卷
|
|
||||||
questionnaireList.push({
|
|
||||||
id: questionnaireId,
|
|
||||||
title: questionnaire.title,
|
|
||||||
createTime: questionnaire.createTime,
|
|
||||||
publishTime: questionnaire.publishTime,
|
|
||||||
status: questionnaire.status,
|
|
||||||
data: questionnaire
|
|
||||||
});
|
|
||||||
|
|
||||||
// 保存更新后的问卷列表
|
|
||||||
localStorage.setItem('questionnaireList', JSON.stringify(questionnaireList));
|
|
||||||
|
|
||||||
alert('问卷发布成功!');
|
|
||||||
window.location.href = 'myQuestion.html'; // 添加返回功能
|
|
||||||
}
|
|
||||||
|
|
||||||
// 添加问卷验证函数
|
|
||||||
function validateQuestionnaire() {
|
|
||||||
const title = document.querySelector('.question-title').value.trim();
|
|
||||||
if (!title) {
|
|
||||||
alert('请输入问卷标题!');
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const endTime = document.querySelector('#endtime').value;
|
|
||||||
if (!endTime) {
|
|
||||||
alert('请设置问卷截止日期!');
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const questions = document.querySelectorAll('.question-item');
|
|
||||||
if (questions.length === 0) {
|
|
||||||
alert('请至少添加一个问题!');
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let question of questions) {
|
|
||||||
const questionTitle = question.querySelector('.question-title-area input[type="text"]').value.trim();
|
|
||||||
if (!questionTitle) {
|
|
||||||
alert('请填写所有问题的标题!');
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const questionType = question.querySelector('input[type="radio"]') ? 'radio' :
|
|
||||||
question.querySelector('input[type="checkbox"]') ? 'checkbox' : 'text';
|
|
||||||
|
|
||||||
if (questionType !== 'text') {
|
|
||||||
const options = question.querySelectorAll('.option-item input[type="text"]');
|
|
||||||
for (let option of options) {
|
|
||||||
if (!option.value.trim()) {
|
|
||||||
alert('请填写所有选项的内容!');
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 初始化页面
|
|
||||||
window.onload = function() {
|
|
||||||
document.querySelector('.but').style.marginTop = '20px';
|
|
||||||
|
|
||||||
// 为题型按钮添加点击事件
|
|
||||||
const buttons = document.querySelectorAll('.quetype button');
|
|
||||||
buttons[0].onclick = addRadioQuestion;
|
|
||||||
buttons[1].onclick = addCheckboxQuestion;
|
|
||||||
buttons[2].onclick = addTextQuestion;
|
|
||||||
|
|
||||||
// 为保存和发布按钮添加点击事件
|
|
||||||
const pushbutButtons = document.querySelectorAll('.pushbut button');
|
|
||||||
pushbutButtons[0].onclick = saveQuestionnaire; // 保存按钮
|
|
||||||
pushbutButtons[1].onclick = publishQuestionnaire; // 发布按钮
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
@ -4,208 +4,8 @@
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>编辑问卷</title>
|
<title>编辑问卷</title>
|
||||||
<style>
|
<link rel="stylesheet" href="../css/editQuestion.css">
|
||||||
* {
|
<script src="../js/editQuestion.js"></script>
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
body {
|
|
||||||
background: #C3C3C3;
|
|
||||||
}
|
|
||||||
header {
|
|
||||||
background-color: #CF9A30;
|
|
||||||
color: #EEE8E4;
|
|
||||||
text-align: start;
|
|
||||||
padding: 20px;
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
main {
|
|
||||||
padding: 30px 0;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
.box {
|
|
||||||
width: 90%;
|
|
||||||
padding: 14px;
|
|
||||||
background-color: #EBEBEB;
|
|
||||||
box-shadow: 1px 2px 2px rgba(0,0,0,0.4);
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
a{
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
.quesen{
|
|
||||||
width: 32px;
|
|
||||||
height: 32px;
|
|
||||||
font-size: 28px;
|
|
||||||
font-weight: bold;
|
|
||||||
text-align: center;
|
|
||||||
line-height: 24px;
|
|
||||||
color: #CF9A30;
|
|
||||||
border-radius: 50px;
|
|
||||||
padding-top: 5px;
|
|
||||||
background-color: #EBEBEB;
|
|
||||||
position: absolute;
|
|
||||||
font-style: normal;
|
|
||||||
top: 14px;
|
|
||||||
left: 60px;
|
|
||||||
}
|
|
||||||
.title{
|
|
||||||
margin-left: 80px;
|
|
||||||
font-size: 24px;
|
|
||||||
line-height: 20px;
|
|
||||||
font-weight: bold;
|
|
||||||
margin-right: 60px;
|
|
||||||
}
|
|
||||||
.nav-bar a {
|
|
||||||
line-height: 20px;
|
|
||||||
font-size: 20px;
|
|
||||||
color: #EEE8E4;
|
|
||||||
border: 2px solid #c78501;
|
|
||||||
padding: 2px;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.question-title{
|
|
||||||
width: 100%;
|
|
||||||
height: 68px;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 24px;
|
|
||||||
font-weight: bold;
|
|
||||||
color: #000;
|
|
||||||
background: #CEEACA;
|
|
||||||
box-shadow: 1px 2px 2px rgba(0,0,0,0.4);
|
|
||||||
border-radius: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.question-title:hover{
|
|
||||||
background: #FCFF00;
|
|
||||||
}
|
|
||||||
.but{
|
|
||||||
width: 99%;
|
|
||||||
height: 40px;
|
|
||||||
background-color: #D3D3D3;
|
|
||||||
margin-bottom: 25px;
|
|
||||||
text-align: center;
|
|
||||||
line-height: 40px;
|
|
||||||
font-size: 20px;
|
|
||||||
font-weight: bold;
|
|
||||||
color: #000000;
|
|
||||||
padding: 10px 0 50px 0;
|
|
||||||
transition: margin-top 0.3s;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
hr{
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
.ctrl-bar{
|
|
||||||
width: 100%;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
margin: 20px 0;
|
|
||||||
}
|
|
||||||
.endtime{
|
|
||||||
margin-left: 20%;
|
|
||||||
}
|
|
||||||
.endtime span{
|
|
||||||
margin-right: 16px;
|
|
||||||
}
|
|
||||||
.pushbut{
|
|
||||||
margin-right: 20%;
|
|
||||||
}
|
|
||||||
.pushbut button{
|
|
||||||
margin-right: 10px;
|
|
||||||
}
|
|
||||||
.quetype{
|
|
||||||
margin-top: 20px;
|
|
||||||
padding: 20px 20%;
|
|
||||||
width: 99%;
|
|
||||||
border: 1px solid #b3b3b3;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
.quetype button {
|
|
||||||
font-size: 16px;
|
|
||||||
line-height: 16px;
|
|
||||||
padding: 1px 25px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.question-item {
|
|
||||||
width: 99%;
|
|
||||||
margin: 20px 0;
|
|
||||||
padding: 20px;
|
|
||||||
background: #fff;
|
|
||||||
border: 1px solid #ddd;
|
|
||||||
box-shadow: 1px 2px 2px rgba(0,0,0,0.1);
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.question-header {
|
|
||||||
display: block;
|
|
||||||
margin-bottom: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.question-content input[type="text"] {
|
|
||||||
width: 100%;
|
|
||||||
padding: 8px;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
border: 1px solid #ddd;
|
|
||||||
}
|
|
||||||
|
|
||||||
.option-item {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
margin: 10px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.option-item input[type="text"] {
|
|
||||||
margin-left: 10px;
|
|
||||||
width: 80%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.delete-btn {
|
|
||||||
padding: 2px 8px;
|
|
||||||
background: #ff4d4f;
|
|
||||||
color: white;
|
|
||||||
border: none;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ctrl-btns {
|
|
||||||
display: none;
|
|
||||||
position: absolute;
|
|
||||||
bottom: 10px;
|
|
||||||
right: 10px;
|
|
||||||
gap: 10px;
|
|
||||||
background: rgba(255, 255, 255, 0.9);
|
|
||||||
padding: 5px;
|
|
||||||
border-radius: 4px;
|
|
||||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.ctrl-btns button {
|
|
||||||
padding: 2px 8px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.quelist{
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.question-item:hover .ctrl-btns {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
.question-content {
|
|
||||||
margin-bottom: 40px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header>
|
<header>
|
||||||
@ -220,9 +20,9 @@
|
|||||||
<input class="question-title" type="text" placeholder="请在这里输入问卷的标题">
|
<input class="question-title" type="text" placeholder="请在这里输入问卷的标题">
|
||||||
<div class="quelist"></div>
|
<div class="quelist"></div>
|
||||||
<div class="quetype" style="display: none;">
|
<div class="quetype" style="display: none;">
|
||||||
<button><img style="width: 16px; height: 16px;" src="/img/radio.svg" alt="">单选题</button>
|
<button><img style="width: 16px; height: 16px;" src="../img/radio.svg" alt="">单选题</button>
|
||||||
<button><img style="width: 16px; height: 16px;" src="/img/checkbox.svg" alt="">多选题</button>
|
<button><img style="width: 16px; height: 16px;" src="../img/checkbox.svg" alt="">多选题</button>
|
||||||
<button><img style="width: 16px; height: 16px;" src="/img/text.svg" alt="">文本题</button>
|
<button><img style="width: 16px; height: 16px;" src="../img/text.svg" alt="">文本题</button>
|
||||||
</div>
|
</div>
|
||||||
<a href="javascript:void(0)" class="but" onclick="toggleQueType()">+ 添加问题</a>
|
<a href="javascript:void(0)" class="but" onclick="toggleQueType()">+ 添加问题</a>
|
||||||
<hr>
|
<hr>
|
||||||
@ -238,356 +38,5 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script>
|
|
||||||
let questionCount = 0;
|
|
||||||
let currentQuestionnaireId = null;
|
|
||||||
|
|
||||||
function toggleQueType() {
|
|
||||||
const queType = document.querySelector('.quetype');
|
|
||||||
const addButton = document.querySelector('.but');
|
|
||||||
|
|
||||||
if (queType.style.display === 'none') {
|
|
||||||
queType.style.display = 'flex';
|
|
||||||
addButton.style.marginTop = '0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 添加单选题
|
|
||||||
function addRadioQuestion(existingQuestion = null) {
|
|
||||||
questionCount++;
|
|
||||||
const questionHtml = `
|
|
||||||
<div class="question-item" id="question-${questionCount}">
|
|
||||||
<div class="question-header">
|
|
||||||
<div class="question-title-area">
|
|
||||||
<span>${questionCount}. </span>
|
|
||||||
<input type="text" placeholder="请输入问题" value="${existingQuestion ? existingQuestion.title : ''}">
|
|
||||||
<button onclick="addOption(${questionCount})">添加选项</button>
|
|
||||||
<label style="margin-left: 20px;">
|
|
||||||
<input type="checkbox" class="required-checkbox" ${existingQuestion && existingQuestion.required ? 'checked' : ''}> 此题为必答题
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="question-content" id="options-${questionCount}">
|
|
||||||
${existingQuestion ?
|
|
||||||
existingQuestion.options.map(option => `
|
|
||||||
<div class="option-item">
|
|
||||||
<input type="radio" name="question${questionCount}" disabled>
|
|
||||||
<input type="text" placeholder="选项内容" value="${option.content}">
|
|
||||||
<button class="delete-btn" onclick="deleteOption(this)">删除</button>
|
|
||||||
</div>
|
|
||||||
`).join('') :
|
|
||||||
Array(4).fill(`
|
|
||||||
<div class="option-item">
|
|
||||||
<input type="radio" name="question${questionCount}" disabled>
|
|
||||||
<input type="text" placeholder="选项内容">
|
|
||||||
<button class="delete-btn" onclick="deleteOption(this)">删除</button>
|
|
||||||
</div>
|
|
||||||
`).join('')
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
<div class="ctrl-btns">
|
|
||||||
<button onclick="moveUp(${questionCount})">上移</button>
|
|
||||||
<button onclick="moveDown(${questionCount})">下移</button>
|
|
||||||
<button onclick="copyQuestion(${questionCount})">复用</button>
|
|
||||||
<button class="delete-btn" onclick="deleteQuestion(${questionCount})">删除</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
document.querySelector('.quelist').insertAdjacentHTML('beforeend', questionHtml);
|
|
||||||
toggleQueType();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 添加多选题
|
|
||||||
function addCheckboxQuestion(existingQuestion = null) {
|
|
||||||
questionCount++;
|
|
||||||
const questionHtml = `
|
|
||||||
<div class="question-item" id="question-${questionCount}">
|
|
||||||
<div class="question-header">
|
|
||||||
<div class="question-title-area">
|
|
||||||
<span>${questionCount}. </span>
|
|
||||||
<input type="text" placeholder="请输入问题" value="${existingQuestion ? existingQuestion.title : ''}">
|
|
||||||
<button onclick="addCheckboxOption(${questionCount})">添加选项</button>
|
|
||||||
<label style="margin-left: 20px;">
|
|
||||||
<input type="checkbox" class="required-checkbox" ${existingQuestion && existingQuestion.required ? 'checked' : ''}> 此题为必答题
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="question-content" id="options-${questionCount}">
|
|
||||||
${existingQuestion ?
|
|
||||||
existingQuestion.options.map(option => `
|
|
||||||
<div class="option-item">
|
|
||||||
<input type="checkbox" name="question${questionCount}" disabled>
|
|
||||||
<input type="text" placeholder="选项内容" value="${option.content}">
|
|
||||||
<button class="delete-btn" onclick="deleteOption(this)">删除</button>
|
|
||||||
</div>
|
|
||||||
`).join('') :
|
|
||||||
Array(4).fill(`
|
|
||||||
<div class="option-item">
|
|
||||||
<input type="checkbox" name="question${questionCount}" disabled>
|
|
||||||
<input type="text" placeholder="选项内容">
|
|
||||||
<button class="delete-btn" onclick="deleteOption(this)">删除</button>
|
|
||||||
</div>
|
|
||||||
`).join('')
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
<div class="ctrl-btns">
|
|
||||||
<button onclick="moveUp(${questionCount})">上移</button>
|
|
||||||
<button onclick="moveDown(${questionCount})">下移</button>
|
|
||||||
<button onclick="copyQuestion(${questionCount})">复用</button>
|
|
||||||
<button class="delete-btn" onclick="deleteQuestion(${questionCount})">删除</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
document.querySelector('.quelist').insertAdjacentHTML('beforeend', questionHtml);
|
|
||||||
toggleQueType();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 添加文本题
|
|
||||||
function addTextQuestion(existingQuestion = null) {
|
|
||||||
questionCount++;
|
|
||||||
const questionHtml = `
|
|
||||||
<div class="question-item" id="question-${questionCount}">
|
|
||||||
<div class="question-header">
|
|
||||||
<div class="question-title-area">
|
|
||||||
<span>${questionCount}. </span>
|
|
||||||
<input type="text" placeholder="请输入问题" value="${existingQuestion ? existingQuestion.title : ''}">
|
|
||||||
<label style="margin-left: 20px;">
|
|
||||||
<input type="checkbox" class="required-checkbox" ${existingQuestion && existingQuestion.required ? 'checked' : ''}> 此题为必答题
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="question-content" id="options-${questionCount}">
|
|
||||||
<textarea disabled placeholder="此处供填写者输入文本答案"
|
|
||||||
style="width: 100%; min-height: 100px; padding: 8px; margin-top: 10px; resize: vertical;"></textarea>
|
|
||||||
</div>
|
|
||||||
<div class="ctrl-btns">
|
|
||||||
<button onclick="moveUp(${questionCount})">上移</button>
|
|
||||||
<button onclick="moveDown(${questionCount})">下移</button>
|
|
||||||
<button onclick="copyQuestion(${questionCount})">复用</button>
|
|
||||||
<button class="delete-btn" onclick="deleteQuestion(${questionCount})">删除</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
document.querySelector('.quelist').insertAdjacentHTML('beforeend', questionHtml);
|
|
||||||
toggleQueType();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 其他辅助函数
|
|
||||||
function addOption(questionId) {
|
|
||||||
const optionHtml = `
|
|
||||||
<div class="option-item">
|
|
||||||
<input type="radio" name="question${questionId}" disabled>
|
|
||||||
<input type="text" placeholder="选项内容">
|
|
||||||
<button class="delete-btn" onclick="deleteOption(this)">删除</button>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
document.querySelector(`#options-${questionId}`).insertAdjacentHTML('beforeend', optionHtml);
|
|
||||||
}
|
|
||||||
|
|
||||||
function addCheckboxOption(questionId) {
|
|
||||||
const optionHtml = `
|
|
||||||
<div class="option-item">
|
|
||||||
<input type="checkbox" name="question${questionId}" disabled>
|
|
||||||
<input type="text" placeholder="选项内容">
|
|
||||||
<button class="delete-btn" onclick="deleteOption(this)">删除</button>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
document.querySelector(`#options-${questionId}`).insertAdjacentHTML('beforeend', optionHtml);
|
|
||||||
}
|
|
||||||
|
|
||||||
function deleteOption(btn) {
|
|
||||||
btn.parentElement.remove();
|
|
||||||
}
|
|
||||||
|
|
||||||
function deleteQuestion(questionId) {
|
|
||||||
document.querySelector(`#question-${questionId}`).remove();
|
|
||||||
}
|
|
||||||
|
|
||||||
function copyQuestion(questionId) {
|
|
||||||
const original = document.querySelector(`#question-${questionId}`);
|
|
||||||
const clone = original.cloneNode(true);
|
|
||||||
questionCount++;
|
|
||||||
clone.id = `question-${questionCount}`;
|
|
||||||
original.after(clone);
|
|
||||||
}
|
|
||||||
|
|
||||||
function moveUp(questionId) {
|
|
||||||
const question = document.querySelector(`#question-${questionId}`);
|
|
||||||
const prev = question.previousElementSibling;
|
|
||||||
if (prev) {
|
|
||||||
prev.before(question);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function moveDown(questionId) {
|
|
||||||
const question = document.querySelector(`#question-${questionId}`);
|
|
||||||
const next = question.nextElementSibling;
|
|
||||||
if (next) {
|
|
||||||
next.after(question);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取问卷数据
|
|
||||||
function getQuestionnaireData(isPublished = false) {
|
|
||||||
const now = new Date().getTime();
|
|
||||||
const questionnaire = {
|
|
||||||
title: document.querySelector('.question-title').value,
|
|
||||||
createTime: now,
|
|
||||||
endTime: document.querySelector('#endtime').value,
|
|
||||||
publishTime: isPublished ? now : null,
|
|
||||||
status: isPublished ? '已发布' : '未发布',
|
|
||||||
questions: []
|
|
||||||
};
|
|
||||||
|
|
||||||
const questionItems = document.querySelectorAll('.question-item');
|
|
||||||
questionItems.forEach((item, index) => {
|
|
||||||
let questionType;
|
|
||||||
if (item.querySelector('.question-content textarea')) {
|
|
||||||
questionType = 'text';
|
|
||||||
} else if (item.querySelector('input[type="radio"]')) {
|
|
||||||
questionType = 'radio';
|
|
||||||
} else {
|
|
||||||
questionType = 'checkbox';
|
|
||||||
}
|
|
||||||
|
|
||||||
const question = {
|
|
||||||
id: index + 1,
|
|
||||||
type: questionType,
|
|
||||||
title: item.querySelector('.question-title-area input[type="text"]').value,
|
|
||||||
required: item.querySelector('.required-checkbox').checked,
|
|
||||||
options: []
|
|
||||||
};
|
|
||||||
|
|
||||||
if (questionType === 'radio' || questionType === 'checkbox') {
|
|
||||||
const options = item.querySelectorAll('.option-item input[type="text"]');
|
|
||||||
options.forEach((option, optionIndex) => {
|
|
||||||
question.options.push({
|
|
||||||
id: optionIndex + 1,
|
|
||||||
content: option.value
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
questionnaire.questions.push(question);
|
|
||||||
});
|
|
||||||
|
|
||||||
return questionnaire;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 加载问卷数据
|
|
||||||
function loadQuestionnaireData() {
|
|
||||||
const urlParams = new URLSearchParams(window.location.search);
|
|
||||||
const questionnaireId = urlParams.get('id');
|
|
||||||
|
|
||||||
if (!questionnaireId) {
|
|
||||||
alert('问卷ID不存在!');
|
|
||||||
window.location.href = 'myQuestion.html';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
currentQuestionnaireId = questionnaireId;
|
|
||||||
const questionnaireList = JSON.parse(localStorage.getItem('questionnaireList') || '[]');
|
|
||||||
const questionnaire = questionnaireList.find(q => q.id === questionnaireId);
|
|
||||||
|
|
||||||
if (!questionnaire) {
|
|
||||||
alert('问卷不存在!');
|
|
||||||
window.location.href = 'myQuestion.html';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 填充问卷数据
|
|
||||||
document.querySelector('.question-title').value = questionnaire.title;
|
|
||||||
document.querySelector('#endtime').value = questionnaire.data.endTime;
|
|
||||||
|
|
||||||
// 渲染问题列表
|
|
||||||
questionnaire.data.questions.forEach(question => {
|
|
||||||
if (question.type === 'radio') {
|
|
||||||
addRadioQuestion(question);
|
|
||||||
} else if (question.type === 'checkbox') {
|
|
||||||
addCheckboxQuestion(question);
|
|
||||||
} else {
|
|
||||||
addTextQuestion(question);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// 更新问卷
|
|
||||||
function updateQuestionnaire() {
|
|
||||||
if (!validateQuestionnaire()) return;
|
|
||||||
|
|
||||||
const questionnaireList = JSON.parse(localStorage.getItem('questionnaireList') || '[]');
|
|
||||||
const index = questionnaireList.findIndex(q => q.id === currentQuestionnaireId);
|
|
||||||
|
|
||||||
if (index === -1) {
|
|
||||||
alert('问卷不存在!');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const updatedData = getQuestionnaireData(false);
|
|
||||||
questionnaireList[index].title = updatedData.title;
|
|
||||||
questionnaireList[index].data = updatedData;
|
|
||||||
|
|
||||||
localStorage.setItem('questionnaireList', JSON.stringify(questionnaireList));
|
|
||||||
alert('问卷修改成功!');
|
|
||||||
window.location.href = 'myQuestion.html';
|
|
||||||
}
|
|
||||||
|
|
||||||
// 验证问卷
|
|
||||||
function validateQuestionnaire() {
|
|
||||||
const title = document.querySelector('.question-title').value.trim();
|
|
||||||
if (!title) {
|
|
||||||
alert('请输入问卷标题!');
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const endTime = document.querySelector('#endtime').value;
|
|
||||||
if (!endTime) {
|
|
||||||
alert('请设置问卷截止日期!');
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const questions = document.querySelectorAll('.question-item');
|
|
||||||
if (questions.length === 0) {
|
|
||||||
alert('请至少添加一个问题!');
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let question of questions) {
|
|
||||||
const questionTitle = question.querySelector('.question-title-area input[type="text"]').value.trim();
|
|
||||||
if (!questionTitle) {
|
|
||||||
alert('请填写所有问题的标题!');
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const questionType = question.querySelector('input[type="radio"]') ? 'radio' :
|
|
||||||
question.querySelector('input[type="checkbox"]') ? 'checkbox' : 'text';
|
|
||||||
|
|
||||||
if (questionType !== 'text') {
|
|
||||||
const options = question.querySelectorAll('.option-item input[type="text"]');
|
|
||||||
for (let option of options) {
|
|
||||||
if (!option.value.trim()) {
|
|
||||||
alert('请填写所有选项的内容!');
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 初始化页面
|
|
||||||
window.onload = function() {
|
|
||||||
// 为题型按钮添加点击事件
|
|
||||||
const buttons = document.querySelectorAll('.quetype button');
|
|
||||||
buttons[0].onclick = addRadioQuestion;
|
|
||||||
buttons[1].onclick = addCheckboxQuestion;
|
|
||||||
buttons[2].onclick = addTextQuestion;
|
|
||||||
|
|
||||||
// 加载问卷数据
|
|
||||||
loadQuestionnaireData();
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
@ -4,157 +4,8 @@
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>填写问卷</title>
|
<title>填写问卷</title>
|
||||||
<style>
|
<link rel="stylesheet" href="../css/fillQuestion.css">
|
||||||
* {
|
<script src="../js/fillQuestion.js"></script>
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
body {
|
|
||||||
background: #C3C3C3;
|
|
||||||
}
|
|
||||||
header {
|
|
||||||
background-color: #CF9A30;
|
|
||||||
color: #EEE8E4;
|
|
||||||
text-align: start;
|
|
||||||
padding: 20px;
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
main {
|
|
||||||
padding: 30px 0;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
.box {
|
|
||||||
width: 90%;
|
|
||||||
padding: 14px;
|
|
||||||
background-color: #EBEBEB;
|
|
||||||
box-shadow: 1px 2px 2px rgba(0,0,0,0.4);
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
.quesen{
|
|
||||||
width: 32px;
|
|
||||||
height: 32px;
|
|
||||||
font-size: 28px;
|
|
||||||
font-weight: bold;
|
|
||||||
text-align: center;
|
|
||||||
line-height: 24px;
|
|
||||||
color: #CF9A30;
|
|
||||||
border-radius: 50px;
|
|
||||||
padding-top: 5px;
|
|
||||||
background-color: #EBEBEB;
|
|
||||||
position: absolute;
|
|
||||||
font-style: normal;
|
|
||||||
top: 14px;
|
|
||||||
left: 60px;
|
|
||||||
}
|
|
||||||
.title{
|
|
||||||
margin-left: 80px;
|
|
||||||
font-size: 24px;
|
|
||||||
line-height: 20px;
|
|
||||||
font-weight: bold;
|
|
||||||
margin-right: 60px;
|
|
||||||
}
|
|
||||||
.nav-bar a {
|
|
||||||
line-height: 20px;
|
|
||||||
font-size: 20px;
|
|
||||||
color: #EEE8E4;
|
|
||||||
border: 2px solid #c78501;
|
|
||||||
padding: 2px;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.question-title {
|
|
||||||
width: 100%;
|
|
||||||
padding: 20px;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 24px;
|
|
||||||
font-weight: bold;
|
|
||||||
background: #CEEACA;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
border-radius: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.question-info {
|
|
||||||
width: 100%;
|
|
||||||
padding: 10px;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-around;
|
|
||||||
background: #fff;
|
|
||||||
border-radius: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.question-item {
|
|
||||||
width: 100%;
|
|
||||||
margin: 10px 0;
|
|
||||||
padding: 20px;
|
|
||||||
background: #fff;
|
|
||||||
border-radius: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.question-item-title {
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: bold;
|
|
||||||
margin-bottom: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.option-item {
|
|
||||||
margin: 10px 0;
|
|
||||||
padding: 5px 0;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.option-item input[type="radio"],
|
|
||||||
.option-item input[type="checkbox"] {
|
|
||||||
margin-right: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.option-item label {
|
|
||||||
cursor: pointer;
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-answer {
|
|
||||||
width: 100%;
|
|
||||||
min-height: 100px;
|
|
||||||
padding: 10px;
|
|
||||||
margin-top: 10px;
|
|
||||||
border: 1px solid #ddd;
|
|
||||||
border-radius: 2px;
|
|
||||||
resize: vertical;
|
|
||||||
}
|
|
||||||
|
|
||||||
.submit-button {
|
|
||||||
margin-top: 20px;
|
|
||||||
padding: 8px 24px;
|
|
||||||
background: #CF9A30;
|
|
||||||
color: #fff;
|
|
||||||
border: none;
|
|
||||||
border-radius: 2px;
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.submit-button:hover {
|
|
||||||
background: #c78501;
|
|
||||||
}
|
|
||||||
|
|
||||||
.error-message {
|
|
||||||
color: #ff4d4f;
|
|
||||||
margin-top: 5px;
|
|
||||||
font-size: 14px;
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.question-list{
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header>
|
<header>
|
||||||
@ -175,153 +26,5 @@
|
|||||||
<button class="submit-button" onclick="submitQuestionnaire()">提交问卷</button>
|
<button class="submit-button" onclick="submitQuestionnaire()">提交问卷</button>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script>
|
|
||||||
let currentQuestionnaire = null;
|
|
||||||
|
|
||||||
function formatDate(timestamp) {
|
|
||||||
if (!timestamp) return '-';
|
|
||||||
const date = new Date(timestamp);
|
|
||||||
return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
function renderQuestion(question, index) {
|
|
||||||
const questionHtml = `
|
|
||||||
<div class="question-item">
|
|
||||||
<div class="question-item-title">
|
|
||||||
${index + 1}. ${question.title}
|
|
||||||
${question.required ? '<span style="color: red; margin-left: 5px;">*</span>' : ''}
|
|
||||||
</div>
|
|
||||||
${
|
|
||||||
question.type === 'text' ?
|
|
||||||
`<div class="question-content">
|
|
||||||
<textarea class="text-answer" name="question_${question.id}"
|
|
||||||
style="width: 100%; min-height: 100px; padding: 8px; margin-top: 10px; resize: vertical;"
|
|
||||||
placeholder="请在此输入您的答案"></textarea>
|
|
||||||
</div>` :
|
|
||||||
`<div class="options">
|
|
||||||
${question.options.map(option => `
|
|
||||||
<div class="option-item">
|
|
||||||
<input type="${question.type}"
|
|
||||||
id="option_${question.id}_${option.id}"
|
|
||||||
name="question_${question.id}"
|
|
||||||
value="${option.id}">
|
|
||||||
<label for="option_${question.id}_${option.id}">${option.content}</label>
|
|
||||||
</div>
|
|
||||||
`).join('')}
|
|
||||||
</div>`
|
|
||||||
}
|
|
||||||
<div class="error-message" id="error_${question.id}">此题为必答题</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
return questionHtml;
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadQuestionnaire() {
|
|
||||||
const urlParams = new URLSearchParams(window.location.search);
|
|
||||||
const questionnaireId = urlParams.get('id');
|
|
||||||
|
|
||||||
if (!questionnaireId) {
|
|
||||||
alert('问卷ID不存在!');
|
|
||||||
window.location.href = 'myQuestion.html';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const questionnaireList = JSON.parse(localStorage.getItem('questionnaireList') || '[]');
|
|
||||||
const questionnaire = questionnaireList.find(q => q.id === questionnaireId);
|
|
||||||
|
|
||||||
if (!questionnaire) {
|
|
||||||
alert('问卷不存在!');
|
|
||||||
window.location.href = 'myQuestion.html';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (questionnaire.status !== '已发布') {
|
|
||||||
alert('该问卷尚未发布!');
|
|
||||||
window.location.href = 'myQuestion.html';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
currentQuestionnaire = questionnaire;
|
|
||||||
|
|
||||||
// 填充问卷信息
|
|
||||||
document.querySelector('.question-title').textContent = questionnaire.title;
|
|
||||||
document.querySelector('.end-time').textContent = formatDate(questionnaire.data.endTime);
|
|
||||||
document.querySelector('.status').textContent = questionnaire.status;
|
|
||||||
|
|
||||||
// 渲染问题列表
|
|
||||||
const questionListHtml = questionnaire.data.questions
|
|
||||||
.map((question, index) => renderQuestion(question, index))
|
|
||||||
.join('');
|
|
||||||
document.querySelector('.question-list').innerHTML = questionListHtml;
|
|
||||||
}
|
|
||||||
|
|
||||||
function validateAnswers() {
|
|
||||||
let isValid = true;
|
|
||||||
currentQuestionnaire.data.questions.forEach(question => {
|
|
||||||
if (!question.required) return; // 如果不是必答题,跳过验证
|
|
||||||
|
|
||||||
const errorElement = document.getElementById(`error_${question.id}`);
|
|
||||||
if (question.type === 'text') {
|
|
||||||
const answer = document.querySelector(`textarea[name="question_${question.id}"]`).value.trim();
|
|
||||||
if (!answer) {
|
|
||||||
errorElement.style.display = 'block';
|
|
||||||
isValid = false;
|
|
||||||
} else {
|
|
||||||
errorElement.style.display = 'none';
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const checked = document.querySelector(`input[name="question_${question.id}"]:checked`);
|
|
||||||
if (!checked) {
|
|
||||||
errorElement.style.display = 'block';
|
|
||||||
isValid = false;
|
|
||||||
} else {
|
|
||||||
errorElement.style.display = 'none';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return isValid;
|
|
||||||
}
|
|
||||||
|
|
||||||
function submitQuestionnaire() {
|
|
||||||
if (!validateAnswers()) {
|
|
||||||
alert('请回答所有问题!');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const answers = {
|
|
||||||
questionnaireId: currentQuestionnaire.id,
|
|
||||||
submitTime: new Date().getTime(),
|
|
||||||
answers: currentQuestionnaire.data.questions.map(question => {
|
|
||||||
if (question.type === 'text') {
|
|
||||||
return {
|
|
||||||
questionId: question.id,
|
|
||||||
type: question.type,
|
|
||||||
answer: document.querySelector(`textarea[name="question_${question.id}"]`).value.trim()
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
const selectedOptions = Array.from(
|
|
||||||
document.querySelectorAll(`input[name="question_${question.id}"]:checked`)
|
|
||||||
).map(input => parseInt(input.value));
|
|
||||||
return {
|
|
||||||
questionId: question.id,
|
|
||||||
type: question.type,
|
|
||||||
answer: selectedOptions
|
|
||||||
};
|
|
||||||
}
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
// 保存答案到 localStorage
|
|
||||||
let answersList = JSON.parse(localStorage.getItem('questionnaireAnswers') || '[]');
|
|
||||||
answersList.push(answers);
|
|
||||||
localStorage.setItem('questionnaireAnswers', JSON.stringify(answersList));
|
|
||||||
|
|
||||||
alert('问卷提交成功!');
|
|
||||||
window.location.href = 'myQuestion.html';
|
|
||||||
}
|
|
||||||
|
|
||||||
window.onload = loadQuestionnaire;
|
|
||||||
</script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
@ -4,220 +4,8 @@
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>我的问卷</title>
|
<title>我的问卷</title>
|
||||||
<style>
|
<link rel="stylesheet" href="../css/myQuestion.css">
|
||||||
* {
|
<script src="../js/myQuestion.js"></script>
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
body {
|
|
||||||
background: #C3C3C3;
|
|
||||||
}
|
|
||||||
header {
|
|
||||||
background-color: #CF9A30;
|
|
||||||
color: #EEE8E4;
|
|
||||||
text-align: start;
|
|
||||||
padding: 20px;
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
main {
|
|
||||||
padding: 30px 0;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
.box {
|
|
||||||
width: 90%;
|
|
||||||
padding: 20px;
|
|
||||||
position: relative;
|
|
||||||
background-color: #EBEBEB;
|
|
||||||
box-shadow: 1px 2px 2px rgba(0,0,0,0.4);
|
|
||||||
}
|
|
||||||
a{
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
.quesen{
|
|
||||||
width: 32px;
|
|
||||||
height: 32px;
|
|
||||||
font-size: 28px;
|
|
||||||
font-weight: bold;
|
|
||||||
text-align: center;
|
|
||||||
line-height: 24px;
|
|
||||||
color: #CF9A30;
|
|
||||||
border-radius: 50px;
|
|
||||||
padding-top: 5px;
|
|
||||||
background-color: #EBEBEB;
|
|
||||||
position: absolute;
|
|
||||||
font-style: normal;
|
|
||||||
top: 14px;
|
|
||||||
left: 60px;
|
|
||||||
}
|
|
||||||
.title{
|
|
||||||
margin-left: 80px;
|
|
||||||
font-size: 24px;
|
|
||||||
line-height: 20px;
|
|
||||||
font-weight: bold;
|
|
||||||
margin-right: 60px;
|
|
||||||
}
|
|
||||||
.nav-bar{
|
|
||||||
a{
|
|
||||||
line-height: 20px;
|
|
||||||
font-size: 20px;
|
|
||||||
color: #EEE8E4;
|
|
||||||
border: 2px solid #c78501;
|
|
||||||
padding: 2px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.grid-bar{
|
|
||||||
width: 85%;
|
|
||||||
display: flex;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
.grid-item-title{
|
|
||||||
color: #2E276D;
|
|
||||||
font-weight: bold;
|
|
||||||
span{
|
|
||||||
margin: 0 8px;
|
|
||||||
}
|
|
||||||
padding-right: 20px;
|
|
||||||
}
|
|
||||||
.grid-item-add{
|
|
||||||
color: #EEE8E4;
|
|
||||||
background: #CF9A30;
|
|
||||||
font-weight: bold;
|
|
||||||
padding: 0 5px;
|
|
||||||
border: 2px solid #c78501;
|
|
||||||
border-radius: 2px;
|
|
||||||
position: absolute;
|
|
||||||
right: 40px;
|
|
||||||
top: 20px;
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
.list-item{
|
|
||||||
width: 100%;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
list-style: none;
|
|
||||||
}
|
|
||||||
.quelist{
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
.btn-group{
|
|
||||||
width: 33%;
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
.item-title{
|
|
||||||
/* width: 33%; */
|
|
||||||
float: left;
|
|
||||||
}
|
|
||||||
table {
|
|
||||||
width: 100%;
|
|
||||||
border-collapse: collapse;
|
|
||||||
background: transparent;
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
th, td {
|
|
||||||
padding: 10px;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.thtitle, .data-row {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
|
|
||||||
.thadd, .data-item {
|
|
||||||
flex: 0.8;
|
|
||||||
padding: 0 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-row {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
gap: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-row button {
|
|
||||||
padding: 2px 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.thtitle {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.thadd {
|
|
||||||
flex: 0.4;
|
|
||||||
padding: 0 5px;
|
|
||||||
white-space: nowrap;
|
|
||||||
text-align: left;
|
|
||||||
color: #2E276D;
|
|
||||||
}
|
|
||||||
|
|
||||||
.thadd:last-child {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.data-row {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.data-item {
|
|
||||||
flex: 0.4;
|
|
||||||
padding: 0 5px;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.data-item:last-child {
|
|
||||||
flex: 1;
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
gap: 5px;
|
|
||||||
justify-content: flex-start;
|
|
||||||
}
|
|
||||||
|
|
||||||
table th:first-child {
|
|
||||||
width: 35%;
|
|
||||||
}
|
|
||||||
|
|
||||||
table th:last-child {
|
|
||||||
width: 65%;
|
|
||||||
}
|
|
||||||
|
|
||||||
tr:not(:first-child) {
|
|
||||||
background-color: #EBEBEB;
|
|
||||||
box-shadow: 1px 2px 2px rgba(0,0,0,0.4);
|
|
||||||
margin-bottom: 10px;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
tr:not(:first-child) td {
|
|
||||||
padding: 15px 10px;
|
|
||||||
border-bottom: 1px solid #C3C3C3;
|
|
||||||
}
|
|
||||||
|
|
||||||
table {
|
|
||||||
background: transparent;
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.box {
|
|
||||||
background: transparent;
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 添加行悬停效果 */
|
|
||||||
tr:not(:first-child):hover {
|
|
||||||
background-color: #e0e0e0; /* 稍微深一点的灰色 */
|
|
||||||
transition: background-color 0.3s ease; /* 添加过渡效果 */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
</style>
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header>
|
<header>
|
||||||
@ -258,210 +46,5 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
<script>
|
|
||||||
// 格式化时间戳为日期字符串
|
|
||||||
function formatDate(timestamp) {
|
|
||||||
if (!timestamp) return '-';
|
|
||||||
const date = new Date(timestamp);
|
|
||||||
return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 渲染问卷列表
|
|
||||||
function renderQuestionnaireList() {
|
|
||||||
// 获取问卷列表数据
|
|
||||||
const questionnaireList = JSON.parse(localStorage.getItem('questionnaireList') || '[]');
|
|
||||||
const tableBody = document.querySelector('table');
|
|
||||||
|
|
||||||
// 保留表头
|
|
||||||
const tableHeader = tableBody.rows[0];
|
|
||||||
tableBody.innerHTML = '';
|
|
||||||
tableBody.appendChild(tableHeader);
|
|
||||||
|
|
||||||
// 渲染每个问卷
|
|
||||||
questionnaireList.forEach(questionnaire => {
|
|
||||||
const tr = document.createElement('tr');
|
|
||||||
tr.innerHTML = `
|
|
||||||
<td>
|
|
||||||
<div class="item-title">
|
|
||||||
<input type="checkbox" data-id="${questionnaire.id}">
|
|
||||||
<span>${questionnaire.title}</span>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div class="data-row">
|
|
||||||
<span class="data-item">${formatDate(questionnaire.createTime)}</span>
|
|
||||||
<span class="data-item">${formatDate(questionnaire.publishTime)}</span>
|
|
||||||
<span class="data-item">${formatDate(questionnaire.data.endTime)}</span>
|
|
||||||
<span class="data-item">${questionnaire.status}</span>
|
|
||||||
<div class="data-item">
|
|
||||||
<button onclick="publishQuestionnaire('${questionnaire.id}')"
|
|
||||||
${questionnaire.status !== '未发布' ? 'disabled style="opacity: 0.5; cursor: not-allowed;"' : ''}>
|
|
||||||
发布问卷
|
|
||||||
</button>
|
|
||||||
<button onclick="editQuestionnaire('${questionnaire.id}')"
|
|
||||||
${questionnaire.status === '已发布' ? 'disabled style="opacity: 0.5; cursor: not-allowed;"' : ''}>
|
|
||||||
编辑问卷
|
|
||||||
</button>
|
|
||||||
<button onclick="deleteQuestionnaire('${questionnaire.id}')">
|
|
||||||
删除问卷
|
|
||||||
</button>
|
|
||||||
<button onclick="viewQuestionnaire('${questionnaire.id}')">
|
|
||||||
查看问卷
|
|
||||||
</button>
|
|
||||||
<button onclick="fillQuestionnaire('${questionnaire.id}')"
|
|
||||||
${questionnaire.status !== '已发布' || new Date().getTime() > new Date(questionnaire.data.endTime).getTime() ?
|
|
||||||
'disabled style="opacity: 0.5; cursor: not-allowed;"' : ''}>
|
|
||||||
填写问卷
|
|
||||||
</button>
|
|
||||||
<button onclick="analyzeQuestionnaire('${questionnaire.id}')"
|
|
||||||
${questionnaire.status !== '已发布' ? 'disabled style="opacity: 0.5; cursor: not-allowed;"' : ''}>
|
|
||||||
分析问卷
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
`;
|
|
||||||
tableBody.appendChild(tr);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// 删除问卷
|
|
||||||
function deleteQuestionnaire(id) {
|
|
||||||
if (!confirm('确定要删除这份问卷吗?')) return;
|
|
||||||
|
|
||||||
let questionnaireList = JSON.parse(localStorage.getItem('questionnaireList') || '[]');
|
|
||||||
questionnaireList = questionnaireList.filter(q => q.id !== id);
|
|
||||||
localStorage.setItem('questionnaireList', JSON.stringify(questionnaireList));
|
|
||||||
renderQuestionnaireList();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 批量删除问卷
|
|
||||||
function batchDeleteQuestionnaires() {
|
|
||||||
const checkedBoxes = document.querySelectorAll('input[type="checkbox"]:checked');
|
|
||||||
if (checkedBoxes.length === 0) {
|
|
||||||
alert('请先选择要删除的问卷!');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!confirm(`确定要删除选中的 ${checkedBoxes.length} 份问卷吗?`)) return;
|
|
||||||
|
|
||||||
let questionnaireList = JSON.parse(localStorage.getItem('questionnaireList') || '[]');
|
|
||||||
const idsToDelete = Array.from(checkedBoxes).map(cb => cb.dataset.id);
|
|
||||||
questionnaireList = questionnaireList.filter(q => !idsToDelete.includes(q.id));
|
|
||||||
localStorage.setItem('questionnaireList', JSON.stringify(questionnaireList));
|
|
||||||
renderQuestionnaireList();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 全选/取消全选
|
|
||||||
function toggleSelectAll() {
|
|
||||||
const selectAllCheckbox = document.querySelector('.ctrl-all input[type="checkbox"]');
|
|
||||||
const allCheckboxes = document.querySelectorAll('table input[type="checkbox"]');
|
|
||||||
allCheckboxes.forEach(cb => cb.checked = selectAllCheckbox.checked);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 发布问卷
|
|
||||||
function publishQuestionnaire(id) {
|
|
||||||
let questionnaireList = JSON.parse(localStorage.getItem('questionnaireList') || '[]');
|
|
||||||
const index = questionnaireList.findIndex(q => q.id === id);
|
|
||||||
if (index !== -1) {
|
|
||||||
const now = new Date().getTime();
|
|
||||||
questionnaireList[index].publishTime = now;
|
|
||||||
questionnaireList[index].status = '已发布';
|
|
||||||
questionnaireList[index].data.publishTime = now;
|
|
||||||
questionnaireList[index].data.status = '已发布';
|
|
||||||
localStorage.setItem('questionnaireList', JSON.stringify(questionnaireList));
|
|
||||||
renderQuestionnaireList();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 新建问卷
|
|
||||||
function createNewQuestionnaire() {
|
|
||||||
window.location.href = 'createQuestion.html';
|
|
||||||
}
|
|
||||||
|
|
||||||
// 页面加载完成后执行
|
|
||||||
window.onload = function() {
|
|
||||||
renderQuestionnaireList();
|
|
||||||
|
|
||||||
// 添加全选事件监听
|
|
||||||
document.querySelector('.ctrl-all input[type="checkbox"]')
|
|
||||||
.addEventListener('change', toggleSelectAll);
|
|
||||||
|
|
||||||
// 添加批量删除事件监听
|
|
||||||
document.querySelector('.ctrl-all button')
|
|
||||||
.addEventListener('click', batchDeleteQuestionnaires);
|
|
||||||
|
|
||||||
// 添加新建问卷事件监听
|
|
||||||
document.querySelector('.grid-item-add')
|
|
||||||
.addEventListener('click', createNewQuestionnaire);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 编辑问卷
|
|
||||||
function editQuestionnaire(id) {
|
|
||||||
window.location.href = `editQuestion.html?id=${id}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查看问卷
|
|
||||||
function viewQuestionnaire(id) {
|
|
||||||
window.location.href = `viewQuestion.html?id=${id}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 填写问卷
|
|
||||||
function fillQuestionnaire(id) {
|
|
||||||
// 检查问卷状态
|
|
||||||
const questionnaireList = JSON.parse(localStorage.getItem('questionnaireList') || '[]');
|
|
||||||
const questionnaire = questionnaireList.find(q => q.id === id);
|
|
||||||
|
|
||||||
if (!questionnaire) {
|
|
||||||
alert('问卷不存在!');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (questionnaire.status !== '已发布') {
|
|
||||||
alert('该问卷尚未发布,无法填写!');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检查问卷是否过期
|
|
||||||
const endTime = new Date(questionnaire.data.endTime).getTime();
|
|
||||||
const now = new Date().getTime();
|
|
||||||
if (now > endTime) {
|
|
||||||
alert('该问卷已过期!');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 跳转到填写问卷页面
|
|
||||||
window.location.href = `fillQuestion.html?id=${id}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 分析问卷
|
|
||||||
function analyzeQuestionnaire(id) {
|
|
||||||
// 检查问卷状态
|
|
||||||
const questionnaireList = JSON.parse(localStorage.getItem('questionnaireList') || '[]');
|
|
||||||
const questionnaire = questionnaireList.find(q => q.id === id);
|
|
||||||
|
|
||||||
if (!questionnaire) {
|
|
||||||
alert('问卷不存在!');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (questionnaire.status !== '已发布') {
|
|
||||||
alert('未发布的问卷无法查看分析结果!');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检查是否有人填写过问卷
|
|
||||||
const answers = JSON.parse(localStorage.getItem('questionnaireAnswers') || '[]');
|
|
||||||
const hasAnswers = answers.some(a => a.questionnaireId === id);
|
|
||||||
|
|
||||||
if (!hasAnswers) {
|
|
||||||
alert('暂无人填写该问卷,无法查看分析结果!');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 跳转到问卷分析页面
|
|
||||||
window.location.href = `analyzeQuestion.html?id=${id}`;
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
@ -4,143 +4,8 @@
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>查看问卷</title>
|
<title>查看问卷</title>
|
||||||
<style>
|
<link rel="stylesheet" href="../css/viewQuestion.css">
|
||||||
* {
|
<script src="../js/viewQuestion.js"></script>
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
body {
|
|
||||||
background: #C3C3C3;
|
|
||||||
}
|
|
||||||
header {
|
|
||||||
background-color: #CF9A30;
|
|
||||||
color: #EEE8E4;
|
|
||||||
text-align: start;
|
|
||||||
padding: 20px;
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
main {
|
|
||||||
padding: 30px 0;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
.box {
|
|
||||||
width: 90%;
|
|
||||||
padding: 14px;
|
|
||||||
background-color: #EBEBEB;
|
|
||||||
box-shadow: 1px 2px 2px rgba(0,0,0,0.4);
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
.quesen{
|
|
||||||
width: 32px;
|
|
||||||
height: 32px;
|
|
||||||
font-size: 28px;
|
|
||||||
font-weight: bold;
|
|
||||||
text-align: center;
|
|
||||||
line-height: 24px;
|
|
||||||
color: #CF9A30;
|
|
||||||
border-radius: 50px;
|
|
||||||
padding-top: 5px;
|
|
||||||
background-color: #EBEBEB;
|
|
||||||
position: absolute;
|
|
||||||
font-style: normal;
|
|
||||||
top: 14px;
|
|
||||||
left: 60px;
|
|
||||||
}
|
|
||||||
.title{
|
|
||||||
margin-left: 80px;
|
|
||||||
font-size: 24px;
|
|
||||||
line-height: 20px;
|
|
||||||
font-weight: bold;
|
|
||||||
margin-right: 60px;
|
|
||||||
}
|
|
||||||
.nav-bar a {
|
|
||||||
line-height: 20px;
|
|
||||||
font-size: 20px;
|
|
||||||
color: #EEE8E4;
|
|
||||||
border: 2px solid #c78501;
|
|
||||||
padding: 2px;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.question-title {
|
|
||||||
width: 100%;
|
|
||||||
padding: 20px;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 24px;
|
|
||||||
font-weight: bold;
|
|
||||||
background: #CEEACA;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
border-radius: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.question-info {
|
|
||||||
width: 100%;
|
|
||||||
padding: 10px;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-around;
|
|
||||||
background: #fff;
|
|
||||||
border-radius: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.question-item {
|
|
||||||
width: 100%;
|
|
||||||
margin: 10px 0;
|
|
||||||
padding: 20px;
|
|
||||||
background: #fff;
|
|
||||||
border-radius: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.question-item-title {
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: bold;
|
|
||||||
margin-bottom: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.option-item {
|
|
||||||
margin: 10px 0;
|
|
||||||
padding: 5px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.option-item input[type="radio"],
|
|
||||||
.option-item input[type="checkbox"] {
|
|
||||||
margin-right: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-answer {
|
|
||||||
width: 100%;
|
|
||||||
min-height: 100px;
|
|
||||||
padding: 10px;
|
|
||||||
margin-top: 10px;
|
|
||||||
border: 1px solid #ddd;
|
|
||||||
border-radius: 2px;
|
|
||||||
resize: vertical;
|
|
||||||
}
|
|
||||||
|
|
||||||
.back-button {
|
|
||||||
margin-top: 20px;
|
|
||||||
padding: 5px 15px;
|
|
||||||
background: #CF9A30;
|
|
||||||
color: #fff;
|
|
||||||
border: none;
|
|
||||||
border-radius: 2px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.back-button:hover {
|
|
||||||
background: #c78501;
|
|
||||||
}
|
|
||||||
|
|
||||||
.question-list{
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header>
|
<header>
|
||||||
@ -163,76 +28,5 @@
|
|||||||
<button class="back-button" onclick="window.location.href='myQuestion.html'">返回列表</button>
|
<button class="back-button" onclick="window.location.href='myQuestion.html'">返回列表</button>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script>
|
|
||||||
function formatDate(timestamp) {
|
|
||||||
if (!timestamp) return '-';
|
|
||||||
const date = new Date(timestamp);
|
|
||||||
return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
function renderQuestion(question, index) {
|
|
||||||
const questionHtml = `
|
|
||||||
<div class="question-item">
|
|
||||||
<div class="question-item-title">
|
|
||||||
${index + 1}. ${question.title}
|
|
||||||
${question.required ? '<span style="color: red; margin-left: 5px;">*(必答题)</span>' : ''}
|
|
||||||
</div>
|
|
||||||
${
|
|
||||||
question.type === 'text' ?
|
|
||||||
`<div class="question-content">
|
|
||||||
<textarea class="text-answer" disabled
|
|
||||||
style="width: 100%; min-height: 100px; padding: 8px; margin-top: 10px; resize: vertical; background-color: #f5f5f5;"
|
|
||||||
placeholder="此处填写答案"></textarea>
|
|
||||||
</div>` :
|
|
||||||
`<div class="options">
|
|
||||||
${question.options.map(option => `
|
|
||||||
<div class="option-item">
|
|
||||||
<input type="${question.type}" name="question${index}" disabled>
|
|
||||||
<span>${option.content}</span>
|
|
||||||
</div>
|
|
||||||
`).join('')}
|
|
||||||
</div>`
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
return questionHtml;
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadQuestionnaire() {
|
|
||||||
const urlParams = new URLSearchParams(window.location.search);
|
|
||||||
const questionnaireId = urlParams.get('id');
|
|
||||||
|
|
||||||
if (!questionnaireId) {
|
|
||||||
alert('问卷ID不存在!');
|
|
||||||
window.location.href = 'myQuestion.html';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const questionnaireList = JSON.parse(localStorage.getItem('questionnaireList') || '[]');
|
|
||||||
const questionnaire = questionnaireList.find(q => q.id === questionnaireId);
|
|
||||||
|
|
||||||
if (!questionnaire) {
|
|
||||||
alert('问卷不存在!');
|
|
||||||
window.location.href = 'myQuestion.html';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 填充问卷信息
|
|
||||||
document.querySelector('.question-title').textContent = questionnaire.title;
|
|
||||||
document.querySelector('.create-time').textContent = formatDate(questionnaire.createTime);
|
|
||||||
document.querySelector('.publish-time').textContent = formatDate(questionnaire.publishTime);
|
|
||||||
document.querySelector('.end-time').textContent = formatDate(questionnaire.data.endTime);
|
|
||||||
document.querySelector('.status').textContent = questionnaire.status;
|
|
||||||
|
|
||||||
// 渲染问题列表
|
|
||||||
const questionListHtml = questionnaire.data.questions
|
|
||||||
.map((question, index) => renderQuestion(question, index))
|
|
||||||
.join('');
|
|
||||||
document.querySelector('.question-list').innerHTML = questionListHtml;
|
|
||||||
}
|
|
||||||
|
|
||||||
window.onload = loadQuestionnaire;
|
|
||||||
</script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
Loading…
x
Reference in New Issue
Block a user