Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
T
Team6CMT313_Assessment2
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Requirements
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Wen-Hsuan Hu
Team6CMT313_Assessment2
Commits
9c4fdf22
Commit
9c4fdf22
authored
4 months ago
by
yazSpaz
Browse files
Options
Downloads
Patches
Plain Diff
added option to filter out students without test attempt
parent
95c92150
Branches
Branches containing commit
No related tags found
No related merge requests found
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
app/routes.py
+1
-0
1 addition, 0 deletions
app/routes.py
app/static/js/script.js
+234
-175
234 additions, 175 deletions
app/static/js/script.js
app/templates/reviewResults.html
+18
-9
18 additions, 9 deletions
app/templates/reviewResults.html
with
253 additions
and
184 deletions
app/routes.py
+
1
−
0
View file @
9c4fdf22
...
...
@@ -194,6 +194,7 @@ def getTestDetails():
mcq_questions
=
TestDAO
.
getMCQQuestionsByTest
(
test_id
,
db
)
fib_questions
=
TestDAO
.
getFIBQuestionsByTest
(
test_id
,
db
)
students
=
TestDAO
.
getStudentsByTest
(
test_id
,
db
)
test_attempts
=
TestDAO
.
getAttemptsByTest
(
test_id
,
db
)
...
...
This diff is collapsed.
Click to expand it.
app/static/js/script.js
+
234
−
175
View file @
9c4fdf22
...
...
@@ -122,6 +122,8 @@ $(document).ready(function () {
studentResultTable
.
clear
().
draw
();
$
(
"
#difficulty
"
).
prop
(
"
disabled
"
,
true
);
$
(
"
#objective
"
).
prop
(
"
disabled
"
,
true
);
$
(
"
#onlyAttempts
"
).
prop
(
"
disabled
"
,
true
);
$
(
"
#onlyAttempts
"
).
prop
(
"
checked
"
,
false
);
$
(
"
#score
"
).
text
(
"
N/A
"
);
// Reset Score
$
(
"
#timetaken
"
).
text
(
"
N/A
"
);
// Reset Time Taken
...
...
@@ -161,6 +163,8 @@ $(document).ready(function () {
studentResultTable
.
clear
().
draw
();
$
(
"
#difficulty
"
).
prop
(
"
disabled
"
,
true
);
$
(
"
#objective
"
).
prop
(
"
disabled
"
,
true
);
$
(
"
#onlyAttempts
"
).
prop
(
"
disabled
"
,
true
);
$
(
"
#onlyAttempts
"
).
prop
(
"
checked
"
,
false
);
$
(
"
#score
"
).
text
(
"
N/A
"
);
// Reset Score
$
(
"
#timetaken
"
).
text
(
"
N/A
"
);
// Reset Time Taken
...
...
@@ -193,8 +197,11 @@ $(document).ready(function () {
// Reset questions dropdown
questionsDropdown
.
prop
(
"
disabled
"
,
true
).
html
(
'
<option value="" disabled selected>No Questions Available</option>
'
);
studentsDropdown
.
prop
(
"
disabled
"
,
true
).
html
(
'
<option value="" disabled selected>No Students Available</option>
'
);
$
(
"
#onlyAttempts
"
).
prop
(
"
disabled
"
,
true
);
$
(
"
#onlyAttempts
"
).
prop
(
"
checked
"
,
false
);
$
(
"
#difficulty
"
).
prop
(
"
disabled
"
,
true
);
$
(
"
#objective
"
).
prop
(
"
disabled
"
,
true
);
$
(
"
.selectpicker
"
).
selectpicker
(
'
refresh
'
);
// **CLEAR TABLE ENTRIES** before loading new data
studentResultTable
.
clear
().
draw
();
...
...
@@ -282,6 +289,7 @@ $(document).ready(function () {
studentsDropdown
.
prop
(
"
disabled
"
,
false
);
$
(
"
#difficulty
"
).
prop
(
"
disabled
"
,
false
);
$
(
"
#objective
"
).
prop
(
"
disabled
"
,
false
);
$
(
"
#onlyAttempts
"
).
prop
(
"
disabled
"
,
false
);
$
(
"
.selectpicker
"
).
selectpicker
(
'
refresh
'
);
$
(
"
.selectpicker
"
).
selectpicker
(
'
selectAll
'
);
...
...
@@ -442,200 +450,251 @@ $(document).ready(function () {
// Function to check if DataTable is empty and enable/disable Export Button
function
toggleExportButton
()
{
exportButton
.
prop
(
"
disabled
"
,
studentResultTable
.
rows
().
count
()
===
0
);
exportButton
.
prop
(
"
disabled
"
,
studentResultTable
.
rows
().
count
()
===
0
);
}
// Call the function whenever the DataTable is updated
studentResultTable
.
on
(
'
draw
'
,
toggleExportButton
);
exportButton
.
click
(
function
(
event
)
{
event
.
preventDefault
();
let
selectedQuestions
=
[];
// Get selected questions and their IDs
questionsDropdown
.
find
(
'
option:selected
'
).
each
(
function
()
{
selectedQuestions
.
push
({
id
:
$
(
this
).
val
(),
question
:
$
(
this
).
text
(),
type
:
$
(
this
).
data
(
'
qtype
'
),
});
event
.
preventDefault
();
let
selectedQuestions
=
[];
// Get selected questions and their IDs
questionsDropdown
.
find
(
'
option:selected
'
).
each
(
function
()
{
selectedQuestions
.
push
({
id
:
$
(
this
).
val
(),
question
:
$
(
this
).
text
(),
type
:
$
(
this
).
data
(
'
qtype
'
),
});
let
studentData
=
[];
// Col
le
c
t
data from the DataTable
studentResultTable
.
rows
().
every
(
function
()
{
let
rowData
=
this
.
data
();
studentData
.
push
({
student
_id
:
rowData
.
student_id
,
forename
:
rowData
.
forename
,
sur
name
:
rowData
.
sur
name
,
scor
e
:
rowData
.
s
cor
e
,
time_taken
:
rowData
.
time_taken
,
attempt_date
:
rowData
.
attempt_date
,
answers
:
{}
// Initialize answers as an empty object
});
});
let
studentData
=
[];
// Collect data from the DataTable
studentResultTable
.
rows
().
every
(
function
()
{
let
rowData
=
this
.
data
();
student
Data
.
push
({
student_id
:
rowData
.
student_id
,
fore
name
:
rowData
.
fore
name
,
surnam
e
:
rowData
.
s
urnam
e
,
score
:
rowData
.
score
,
time_taken
:
rowData
.
time_taken
,
attempt_date
:
rowData
.
attempt_date
,
answers
:
{}
// Initialize answers as an empty object
});
let
testId
=
testDropdown
.
val
();
// Fetch test details
$
.
ajax
({
url
:
"
/getTestDetails
"
,
type
:
"
POST
"
,
contentType
:
"
application/json
"
,
data
:
JSON
.
stringify
({
test_id
:
testId
})
}).
done
(
function
(
response
)
{
let
ajaxCalls
=
[];
response
.
students
.
forEach
(
studentAnswer
=>
{
let
attempt
=
response
.
test_attempts
.
find
(
attempt
=>
attempt
.
student_id
===
studentAnswer
.
id
);
if
(
attempt
)
{
// Store AJAX calls in an array
let
ajaxCall
=
$
.
ajax
({
url
:
"
/getStudentQuestions
"
,
type
:
"
POST
"
,
contentType
:
"
application/json
"
,
data
:
JSON
.
stringify
({
test_attempt_id
:
attempt
.
id
,
test_id
:
testId
})
}).
done
(
function
(
response
)
{
response
.
question_attempts
.
forEach
(
question
=>
{
let
student
=
studentData
.
find
(
s
=>
s
.
student_id
==
studentAnswer
.
id
);
if
(
student
)
{
let
answerKey
=
`
${
question
.
id
}
_
${
question
.
question_type
}
`
;
student
.
answers
[
answerKey
]
=
{
student_answer
:
question
.
student_answer
,
correct_answer
:
question
.
correct_answer
};
}
});
});
ajaxCalls
.
push
(
ajaxCall
);
});
let
testId
=
testDropdown
.
val
();
// Fetch test details
$
.
ajax
({
url
:
"
/getTestDetails
"
,
type
:
"
POST
"
,
contentType
:
"
application/json
"
,
data
:
JSON
.
stringify
({
test_id
:
testId
})
}).
done
(
function
(
response
)
{
let
ajaxCalls
=
[];
response
.
students
.
forEach
(
studentAnswer
=>
{
let
attempt
=
response
.
test_attempts
.
find
(
attempt
=>
attempt
.
student_id
===
studentAnswer
.
id
);
if
(
attempt
)
{
// Store AJAX calls in an array
let
ajaxCall
=
$
.
ajax
({
url
:
"
/getStudentQuestions
"
,
type
:
"
POST
"
,
contentType
:
"
application/json
"
,
data
:
JSON
.
stringify
({
test_attempt_id
:
attempt
.
id
,
test_id
:
testId
})
}).
done
(
function
(
response
)
{
response
.
question_attempts
.
forEach
(
question
=>
{
let
student
=
studentData
.
find
(
s
=>
s
.
student_id
==
studentAnswer
.
id
);
if
(
student
)
{
let
answerKey
=
`
${
question
.
id
}
_
${
question
.
question_type
}
`
;
student
.
answers
[
answerKey
]
=
{
student_answer
:
question
.
student_answer
,
correct_answer
:
question
.
correct_answer
};
}
});
});
// Wait for all AJAX calls to finish before calling generateExcel
$
.
when
.
apply
(
$
,
ajaxCalls
).
done
(
function
()
{
generateExcel
(
studentData
,
selectedQuestions
);
});
ajaxCalls
.
push
(
ajaxCall
);
}
});
// Wait for all AJAX calls to finish before calling generateExcel
$
.
when
.
apply
(
$
,
ajaxCalls
).
done
(
function
()
{
generateExcel
(
studentData
,
selectedQuestions
);
});
});
});
function
generateExcel
(
studentData
,
selectedQuestions
)
{
let
wb
=
XLSX
.
utils
.
book_new
();
let
wsData
=
[];
let
wb
=
XLSX
.
utils
.
book_new
();
let
wsData
=
[];
// Header Row
let
headers
=
[
"
Student ID
"
,
"
Forename
"
,
"
Surname
"
,
"
Score
"
,
"
Time Taken
"
,
"
Attempt Date
"
];
selectedQuestions
.
forEach
(
q
=>
{
headers
.
push
(
q
.
question
,
"
Correct Answer
"
);
});
wsData
.
push
(
headers
);
// Data Rows
studentData
.
forEach
(
student
=>
{
let
row
=
[
student
.
student_id
,
student
.
forename
,
student
.
surname
,
student
.
score
,
student
.
time_taken
,
student
.
attempt_date
];
selectedQuestions
.
forEach
(
q
=>
{
let
answerKey
=
`
${
q
.
id
}
_
${
q
.
type
}
`
;
let
answerData
=
student
.
answers
[
answerKey
]
||
{
student_answer
:
"
N/A
"
,
correct_answer
:
"
N/A
"
};
row
.
push
(
answerData
.
student_answer
,
answerData
.
correct_answer
);
});
wsData
.
push
(
row
);
});
// Header Row
let
headers
=
[
"
Student ID
"
,
"
Forename
"
,
"
Surname
"
,
"
Score
"
,
"
Time Taken
"
,
"
Attempt Date
"
];
selectedQuestions
.
forEach
(
q
=>
{
headers
.
push
(
q
.
question
,
"
Correct Answer
"
);
});
wsData
.
push
(
headers
);
// Data Rows
studentData
.
forEach
(
student
=>
{
let
row
=
[
student
.
student_id
,
student
.
forename
,
student
.
surname
,
student
.
score
,
student
.
time_taken
,
student
.
attempt_date
];
selectedQuestions
.
forEach
(
q
=>
{
let
answerKey
=
`
${
q
.
id
}
_
${
q
.
type
}
`
;
let
answerData
=
student
.
answers
[
answerKey
]
||
{
student_answer
:
"
N/A
"
,
correct_answer
:
"
N/A
"
};
row
.
push
(
answerData
.
student_answer
,
answerData
.
correct_answer
);
});
wsData
.
push
(
row
);
});
// Create worksheet from wsData
let
ws
=
XLSX
.
utils
.
aoa_to_sheet
(
wsData
);
// Create worksheet from wsData
let
ws
=
XLSX
.
utils
.
aoa_to_sheet
(
wsData
);
// Apply cell formatting
// Apply cell formatting
// 1. Set column widths (make question columns wider)
let
colWidths
=
[
{
wpx
:
100
},
// Student ID
{
wpx
:
120
},
// Forename
{
wpx
:
120
},
// Surname
{
wpx
:
60
},
// Score
{
wpx
:
90
},
// Time Taken
{
wpx
:
120
},
// Attempt Date
];
// 1. Set column widths (make question columns wider)
let
colWidths
=
[
{
wpx
:
100
},
// Student ID
{
wpx
:
120
},
// Forename
{
wpx
:
120
},
// Surname
{
wpx
:
60
},
// Score
{
wpx
:
90
},
// Time Taken
{
wpx
:
120
},
// Attempt Date
];
selectedQuestions
.
forEach
(()
=>
{
colWidths
.
push
({
wpx
:
250
});
// Question column (width for questions)
colWidths
.
push
({
wpx
:
150
});
// Correct Answer column (width for correct answers)
});
selectedQuestions
.
forEach
(()
=>
{
colWidths
.
push
({
wpx
:
250
});
// Question column (width for questions)
colWidths
.
push
({
wpx
:
150
});
// Correct Answer column (width for correct answers)
});
ws
[
'
!cols
'
]
=
colWidths
;
// Apply column widths to the worksheet
// 2. Apply borders to all cells and middle alignment
const
range
=
XLSX
.
utils
.
decode_range
(
ws
[
'
!ref
'
]);
// Get the range of the worksheet
for
(
let
row
=
range
.
s
.
r
;
row
<=
range
.
e
.
r
;
row
++
)
{
for
(
let
col
=
range
.
s
.
c
;
col
<=
range
.
e
.
c
;
col
++
)
{
let
cellAddress
=
{
r
:
row
,
c
:
col
};
let
cellRef
=
XLSX
.
utils
.
encode_cell
(
cellAddress
);
if
(
!
ws
[
cellRef
])
ws
[
cellRef
]
=
{};
// Ensure cell exists
// Apply border to the cell
ws
[
cellRef
].
s
=
{
border
:
{
top
:
{
style
:
'
thin
'
,
color
:
{
rgb
:
"
000000
"
}
},
left
:
{
style
:
'
thin
'
,
color
:
{
rgb
:
"
000000
"
}
},
bottom
:
{
style
:
'
thin
'
,
color
:
{
rgb
:
"
000000
"
}
},
right
:
{
style
:
'
thin
'
,
color
:
{
rgb
:
"
000000
"
}
},
},
alignment
:
{
vertical
:
'
center
'
,
// Middle align vertically
horizontal
:
'
center
'
,
// Center align horizontally
wrapText
:
true
// Enable text wrapping
}
};
}
}
// 3. Apply text wrapping and reduce row height
for
(
let
row
=
range
.
s
.
r
;
row
<=
range
.
e
.
r
;
row
++
)
{
let
rowRef
=
XLSX
.
utils
.
encode_row
(
row
);
// Get row reference
if
(
!
ws
[
'
!rows
'
])
ws
[
'
!rows
'
]
=
[];
ws
[
'
!rows
'
][
row
]
=
{
hpx
:
24
};
// Reduced row height (adjust as needed)
}
// 4. Add a bottom border to the question and correct answer headers
selectedQuestions
.
forEach
((
q
,
idx
)
=>
{
let
questionColIndex
=
6
+
idx
*
2
;
// Column index for "Question"
let
correctAnswerColIndex
=
7
+
idx
*
2
;
// Column index for "Correct Answer"
// Add bottom border to the "Question" and "Correct Answer" header cells
let
questionCellRef
=
XLSX
.
utils
.
encode_cell
({
r
:
0
,
c
:
questionColIndex
});
let
correctAnswerCellRef
=
XLSX
.
utils
.
encode_cell
({
r
:
0
,
c
:
correctAnswerColIndex
});
if
(
!
ws
[
questionCellRef
])
ws
[
questionCellRef
]
=
{};
// Ensure cell exists
if
(
!
ws
[
correctAnswerCellRef
])
ws
[
correctAnswerCellRef
]
=
{};
// Ensure cell exists
// Apply bottom border to the header cells
ws
[
questionCellRef
].
s
=
{
border
:
{
bottom
:
{
style
:
'
thin
'
,
color
:
{
rgb
:
"
000000
"
}
}
}
};
ws
[
correctAnswerCellRef
].
s
=
{
border
:
{
bottom
:
{
style
:
'
thin
'
,
color
:
{
rgb
:
"
000000
"
}
}
}
};
});
// 5. Set the sheet name
XLSX
.
utils
.
book_append_sheet
(
wb
,
ws
,
"
Student Results
"
);
ws
[
'
!cols
'
]
=
colWidths
;
// Apply column widths to the worksheet
// 2. Apply borders to all cells and middle alignment
const
range
=
XLSX
.
utils
.
decode_range
(
ws
[
'
!ref
'
]);
// Get the range of the worksheet
for
(
let
row
=
range
.
s
.
r
;
row
<=
range
.
e
.
r
;
row
++
)
{
for
(
let
col
=
range
.
s
.
c
;
col
<=
range
.
e
.
c
;
col
++
)
{
let
cellAddress
=
{
r
:
row
,
c
:
col
};
let
cellRef
=
XLSX
.
utils
.
encode_cell
(
cellAddress
);
if
(
!
ws
[
cellRef
])
ws
[
cellRef
]
=
{};
// Ensure cell exists
// Apply border to the cell
ws
[
cellRef
].
s
=
{
border
:
{
top
:
{
style
:
'
thin
'
,
color
:
{
rgb
:
"
000000
"
}
},
left
:
{
style
:
'
thin
'
,
color
:
{
rgb
:
"
000000
"
}
},
bottom
:
{
style
:
'
thin
'
,
color
:
{
rgb
:
"
000000
"
}
},
right
:
{
style
:
'
thin
'
,
color
:
{
rgb
:
"
000000
"
}
},
},
alignment
:
{
vertical
:
'
center
'
,
// Middle align vertically
horizontal
:
'
center
'
,
// Center align horizontally
wrapText
:
true
// Enable text wrapping
}
};
// Export file
XLSX
.
writeFile
(
wb
,
"
Student_Results.xlsx
"
);
}
$
(
"
#onlyAttempts
"
).
change
(
function
()
{
if
(
$
(
this
).
is
(
"
:checked
"
))
{
filterStudentsWithAttempts
(
true
);
}
else
{
filterStudentsWithAttempts
(
false
);
}
}
// 3. Apply text wrapping and reduce row height
for
(
let
row
=
range
.
s
.
r
;
row
<=
range
.
e
.
r
;
row
++
)
{
let
rowRef
=
XLSX
.
utils
.
encode_row
(
row
);
// Get row reference
if
(
!
ws
[
'
!rows
'
])
ws
[
'
!rows
'
]
=
[];
ws
[
'
!rows
'
][
row
]
=
{
hpx
:
24
};
// Reduced row height (adjust as needed)
}
// 4. Add a bottom border to the question and correct answer headers
selectedQuestions
.
forEach
((
q
,
idx
)
=>
{
let
questionColIndex
=
6
+
idx
*
2
;
// Column index for "Question"
let
correctAnswerColIndex
=
7
+
idx
*
2
;
// Column index for "Correct Answer"
// Add bottom border to the "Question" and "Correct Answer" header cells
let
questionCellRef
=
XLSX
.
utils
.
encode_cell
({
r
:
0
,
c
:
questionColIndex
});
let
correctAnswerCellRef
=
XLSX
.
utils
.
encode_cell
({
r
:
0
,
c
:
correctAnswerColIndex
});
if
(
!
ws
[
questionCellRef
])
ws
[
questionCellRef
]
=
{};
// Ensure cell exists
if
(
!
ws
[
correctAnswerCellRef
])
ws
[
correctAnswerCellRef
]
=
{};
// Ensure cell exists
// Apply bottom border to the header cells
ws
[
questionCellRef
].
s
=
{
border
:
{
bottom
:
{
style
:
'
thin
'
,
color
:
{
rgb
:
"
000000
"
}
}
}
};
ws
[
correctAnswerCellRef
].
s
=
{
border
:
{
bottom
:
{
style
:
'
thin
'
,
color
:
{
rgb
:
"
000000
"
}
}
}
};
});
// 5. Set the sheet name
XLSX
.
utils
.
book_append_sheet
(
wb
,
ws
,
"
Student Results
"
);
// Export file
XLSX
.
writeFile
(
wb
,
"
Student_Results.xlsx
"
);
}
function
filterStudentsWithAttempts
(
checked
)
{
let
studentsWithAttempt
=
[];
let
testId
=
testDropdown
.
val
();
$
.
ajax
({
url
:
"
/getTestDetails
"
,
type
:
"
POST
"
,
contentType
:
"
application/json
"
,
data
:
JSON
.
stringify
({
test_id
:
testId
}),
success
:
function
(
response
)
{
response
.
students
.
forEach
(
student
=>
{
response
.
test_attempts
.
forEach
(
attempt
=>
{
if
(
student
.
id
===
attempt
.
student_id
)
{
studentsWithAttempt
.
push
(
student
.
id
.
toString
());
}
})
})
if
(
checked
)
{
studentsDropdown
.
find
(
'
option
'
).
each
(
function
()
{
let
studentId
=
$
(
this
).
val
();
if
(
!
studentsWithAttempt
.
includes
(
studentId
.
toString
()))
{
$
(
this
).
hide
();
$
(
this
).
prop
(
'
selected
'
,
false
);
$
(
"
.selectpicker
"
).
selectpicker
(
'
refresh
'
);
}
})
recalculateScores
();
}
else
{
studentsDropdown
.
find
(
'
option
'
).
each
(
function
()
{
$
(
this
).
show
();
$
(
this
).
prop
(
'
selected
'
,
true
);
$
(
"
.selectpicker
"
).
selectpicker
(
'
refresh
'
);
})
recalculateScores
();
}
}
})
}
});
\ No newline at end of file
This diff is collapsed.
Click to expand it.
app/templates/reviewResults.html
+
18
−
9
View file @
9c4fdf22
...
...
@@ -54,7 +54,8 @@
<!-- Filter Question Difficulty -->
<div
class=
"form-group mb-3 col-md-2"
>
<label
for=
"difficulty-select"
class=
"form-label"
>
Difficulty
</label>
<select
id=
"difficulty"
type=
"text"
name=
"difficulty-select"
class=
"form-control selectpicker"
multiple
required
disabled
>
<select
id=
"difficulty"
type=
"text"
name=
"difficulty-select"
class=
"form-control selectpicker"
multiple
required
disabled
>
<option
value=
"Difficulty.Easy"
>
Easy
</option>
<option
value=
"Difficulty.Intermediate"
>
Intermediate
</option>
<option
value=
"Difficulty.Hard"
>
Hard
</option>
...
...
@@ -64,7 +65,8 @@
<!-- Filter Question Learning Objective -->
<div
class=
"form-group mb-3 col-md-2"
>
<label
for=
"objective-select"
class=
"form-label"
>
Learning Objective
</label>
<select
id=
"objective"
type=
"text"
name=
"objective-select"
class=
"form-control selectpicker"
multiple
required
disabled
>
<select
id=
"objective"
type=
"text"
name=
"objective-select"
class=
"form-control selectpicker"
multiple
required
disabled
>
<option
value=
"LearningObjective.Remember"
>
Remember
</option>
<option
value=
"LearningObjective.Understand"
>
Understand
</option>
<option
value=
"LearningObjective.Apply"
>
Apply
</option>
...
...
@@ -88,13 +90,20 @@
<h3
id=
"timetaken"
>
N/A
</h3>
</div>
<!-- Choose Students -->
<div
class=
"form-group mb-3 col-md-3"
>
<label
for=
"s-select"
class=
"form-label"
>
Students
</label>
<!-- Dynamically update for questions that are included / for what test is selected -->
<select
id=
"students"
type=
"text"
name=
"s-select"
class=
"form-control selectpicker"
multiple
required
data-live-search=
"true"
disabled
>
</select>
<!-- Choose Students -->
<div
class=
"form-group mb-3 col-md-3"
>
<label
for=
"s-select"
class=
"form-label"
>
Students
</label>
<!-- Dynamically update for questions that are included / for what test is selected -->
<select
id=
"students"
type=
"text"
name=
"s-select"
class=
"form-control selectpicker"
multiple
required
data-live-search=
"true"
disabled
>
</select>
</div>
<div
class=
"form-group mb-3 col-md-3"
style=
"padding-left:15px"
>
<label
for=
"f-check"
class=
"form-label"
>
Only Show Students with Attempts
</label>
<div
class=
"form-check form-check-inline"
style=
"padding-left:100px"
>
<input
id=
"onlyAttempts"
class=
"form-check-input"
type=
"checkbox"
id=
"inlineCheckbox1"
value=
"option1"
disabled
>
</div>
</div>
<!-- Show Students -->
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment