{{extend 'admin/instructors.html'}}
{{ block tabcontent }}
<script type="text/javascript">
// Avoid problems with quoting single quotes via `XML <http://web2py.com/books/default/chapter/29/05/the-views#XML>`_.
eBookConfig.toc = {{=XML(toc)}};
</script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/css/select2.min.css" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/js/select2.min.js">
</script>
<link href="{{=URL('static', 'jquery.datetimepicker.min.css')}}" rel="stylesheet" type="text/css">
<script src="{{=URL('static', 'js/jquery.datetimepicker.full.min.js')}}">
</script>
<link href="{{=URL('static', 'js/jstree_themes/proton/style.min.css')}}" rel="stylesheet">
<script src="{{=URL('static', 'js/jstree.min.js')}}">
</script>
<link href="{{=URL('static', 'js/bootstrap-table/bootstrap-table.min.css')}}" rel="stylesheet">
<link href="{{=URL('static', 'js/bootstrap-table/bootstrap-editable/css/bootstrap-editable.css')}}" rel="stylesheet">
<link href="{{=URL('static', 'js/bootstrap-table/bootstrap-table-reorder-rows.css')}}" rel="stylesheet">
<script src="{{=URL('static', 'js/bootstrap-table/bootstrap-table.min.js')}}">
</script>
<script src="{{=URL('static', 'js/bootstrap-table/bootstrap-table-en-US.min.js')}}">
</script>
<script src="{{=URL('static', 'js/bootstrap-table/bootstrap-table-editable.min.js')}}">
</script>
<script src="{{=URL('static', 'js/bootstrap-table/bootstrap-editable/js/bootstrap-editable.js')}}">
</script>
<script src="{{=URL('static', 'js/bootstrap-table/jquery.tablednd.js')}}">
</script>
<script src="{{=URL('static', 'js/bootstrap-table/bootstrap-table-reorder-rows.js')}}">
</script>
<div class="row">
<div class="col-md-2"></div>
<div class="col-md-8">
<h4 style="text-align: center;">Assignment</h4>
<select class="form-control" id="assignlist" onchange="assignmentInfo();">
{{ for assignmentid in assignments: }}
<option value="{{=assignmentid}}">{{=assignments[assignmentid]}}</option>
{{ pass }}
</select>
<button class="btn" data-target="#addAssignment" data-toggle="modal" style="margin-top: 12px;">Add</button>
<button class="btn" onclick="remove_assignment();" style="margin-top: 12px;">Delete</button>
<button class="btn" data-target="#renameAssignment" data-toggle="modal" onclick="fillinAssignmentName('renameName');" style="margin-top: 12px;">Rename</button>
<fieldset>
<legend>Assignment properties</legend>
<span id="totalPoints" style="margin-bottom: 10px;"></span><br>
<form id="assignment-form">
<label for="datetimepicker">Due Date: </label>
<input id="datetimepicker" class="form-control" name="due" type="text"><br>
<div class="form-group form-check">
<label for="assign_visible" class="form-check-label">Visible to Students</label>
<input id="assign_visible" class="form-check-input" type="checkbox" name="visible" value="T"><br>
</div>
<div class="form-group form-check">
<label for="assign_is_timed" class="form-check-label">Show as Timed Assessment</label>
<input id="assign_is_timed" class="form-check-input" type="checkbox" name="is_timed" value="T"> (Use this to make quizzes or exams - <strong>Beta!</strong>)<br>
<label for="timelimit" class="form-check-label">Time Limit</label>
<input id="timelimit" name="timelimit" type="number" min="5" max="125" value=""> Leave blank for no limit --
<label for="nofeedback" class="form-check-label">No Feedback</label>
<input id="nofeedback" name="nofeedback" type="checkbox">
<label for="nopause" class="form-check-label">No Pause</label>
<input id="nopause" name="nopause" type="checkbox">
<span id="simulatorbuttonspan" style="margin-left: 10px;"></span>
</div>
<label for="assignment_description">Description: </label>
<input class="form-control" id="assignment_description" name="description" type="text"><br>
<input class="btn btn-default" onclick="window.open('../assignments/doAssignment?assignment_id=' + document.getElementById('assignlist').options[document.getElementById('assignlist').selectedIndex].value);" type="button" value="Preview">
<input class="btn btn-default" onclick="update_assignment(this.form)" type="button" value="Save">
</form>
</fieldset>
{{ if settings.lti_interface: }}
<div><p>LTI Link: <code><span id="ltilink"></span></code>
<span class="clipcopy" onclick="copyElementToClipboard('ltilink')" style="cursor: pointer">📋copy</span>
</p></div>
{{ pass }}
</div>
<div class="col-md-2"></div>
</div>
Modal: Add
<div aria-hidden="true" aria-labelledby="myAddModalLabel" class="modal fade" id="addAssignment" role="dialog" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
Modal Header
<div class="modal-header">
<button class="close" data-dismiss="modal" type="button"><span aria-hidden="true">×</span> <span class="sr-only">Close</span></button>
<h4 class="modal-title" id="myAddModalLabel">Create Assignment</h4>
</div><!-- Modal Body -->
<div class="modal-body">
<form role="form">
<div class="form-group">
<label for="name">Assignment Name</label> <input class="form-control" id="name" placeholder="Enter assignment name" type="text">
</div>
<input class="btn btn-default" data-dismiss="modal" onclick="createAssignment(this.form)" type="button" value="Create">
</form>
</div><!-- Modal Footer -->
<div class="modal-footer">
<button class="btn btn-default" data-dismiss="modal" type="button">Cancel</button>
</div>
</div>
</div>
</div>
Modal: Rename
<div aria-hidden="true" aria-labelledby="myRenameModalLabel" class="modal fade" id="renameAssignment" role="dialog" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
Modal Header
<div class="modal-header">
<button class="close" data-dismiss="modal" type="button"><span aria-hidden="true">×</span> <span class="sr-only">Close</span></button>
<h4 class="modal-title" id="myRenameModalLabel">Rename Assignment</h4>
</div><!-- Modal Body -->
<div class="modal-body">
<form role="form">
<div class="form-group">
<label for="rename-name">Enter the new name for assignment "<span id="renameName"></span>"</label> <input class="form-control" id="rename-name" placeholder="Enter assignment name" type="text">
</div>
<input class="btn btn-default" data-dismiss="modal" onclick="renameAssignment(this.form)" type="button" value="Rename">
</form>
</div><!-- Modal Footer -->
<div class="modal-footer">
<button class="btn btn-default" data-dismiss="modal" type="button">Cancel</button>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12" id="leftpanel2" style="visibility: hidden">
<div class="panel-group">
<div class="panel panel-default">
Readings collapsible section
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" href="#readings-collapse">Readings</a>
</h4>
</div>
<div id="readings-collapse" class="panel-collapse collapse">
<div class="panel-body">
<p>Define the readings students must complete by selecting chapters and subchapters of the textbook.</p>
<table id="readingsTable" style="width:100%;">
</table>
<input id="search-tree-readings-picker" type="text">
<div id="tree-readings-picker"></div>
</div>
</div>
Problems collapsible section
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" href="#problems-collapse">Problems</a>
</h4>
</div>
<div id="problems-collapse" class="panel-collapse collapse">
<div class="panel-body">
<p>Select the problems which compose this assignment.</p>
<table id="questionTable" style="width:100%;"></table>
<div class="container">
<div class="col-md-6">
<a class="btn btn-default" data-toggle="tab" href="#qbrowse" id="browse-button">Browse</a>
<a class="btn btn-default" data-toggle="tab" href="#qbank">Search</a>
<a class="btn btn-default" data-toggle="tab" href="#qwrite">Write</a>
</div>
<div class="col-md-6">
<p>Legend:</p>
<table>
<tr><td>📘</td><td>Question written by author</td></tr>
<tr><td>🏫</td><td>Community Contributed question</td></tr>
<tr><td>✓</td><td>Question is autograded</td></tr>
</table>
</div>
<div class="tab-content col-md-6">
Browse tab
<div class="form-group tab-pane fade" id="qbrowse" style="margin-bottom: 30px">
<input id="search-tree-question-picker" type="text">
<div id="tree-question-picker"></div>
</div>
Search tab
<div class="form-group tab-pane fade" id="qbank" style="margin-bottom: 30px">
<h5 style="text-align: center">Search Question Bank</h5>
<form id="qbankform" name="qbankform" role="form">
<div class="form-group">
<label for="term">Free Text Search of question</label> <input class="form-control" id="term" placeholder="Term" type="text">
</div>
<div class="form-group">
<label>Constrain search to this course
<input type="checkbox" name="constrainbc" value="T" checked>
(normally leave checked)
</label>
</div>
<div class="form-group">
<label for="chapter">Chapter</label>
<select class="form-control" id="chapter">
<option selected="selected" label="select chapter" value=""></option>
{{ for chapter in chapters: }}
<option value="{{=chapter}}">{{=chapter}}</option>
{{ pass }}
</select>
</div>
<div class="form-group">
<label for="author">Author (First Last)</label>
<input class="form-control" id="author" placeholder="Author" type="text">
</div>
<div class="form-group">
<label for="difficultyselector">Difficulty (1.0 -- 5.0)</label>
<div id="difficultyselector">
<label>Minimum
<input type="text" name="min_diff" placeholder="1.0">
</label>
<label>Maximum
<input type="text" name="max_diff" placeholder="5.0">
</label>
</div>
</div>
<div class="form-group">
<label for="competencyselector">Competency</label>
<div id="competencyselector">
<input name="competency" type="text">
<label for="cisprimary">Is Primary</label>
<input name="isprim" type=checkbox>
</div>
</div>
- <div class=”form-group”>
<label for=”tags”>Tags</label> <select class=”js-example-basic-multiple” id=”tags” multiple=”multiple” style=”width:100%”>
{{ for tag in tags: }} <option value=”{{=tag}}”>{{ =tag }}</option> {{ pass }}
</select>
</div>
<input class="btn btn-default" data-dismiss="modal" onclick="questionBank(this.form)" type="button" value="Search">
</form>
<div class="col-md-12" style="margin-top: 40px; margin-bottom:40px; text-align: center">
<select class="list-group-item-text;" id="qbankselect" size="10" style="text-align: center; visibility: hidden">
</select>
<form id="questionform" name="questionform" style="visibility: hidden">
<label for="points">Points</label>
<input id="points" name="points" type="number">
<label for="timed">Timed</label>
<input id="timed" name="timed" type="checkbox" value="true">
<input class="btn btn-default" data-dismiss="modal" onclick="addToAssignment(this.form)" type="button" value="Add to Assignment">
</form>
</div>
<div class="col-md-12">
<div class="list-group" id="questionInfo" style="width:100%; visibility: hidden;">
<div class="list-group" style="margin-top: 20px">
<div class="list-group-item">
<div id="q_author"></div>
<div id="q_difficulty"></div>
<div id="q_tags"></div>
</div>
</div>
</div>
</div>
</div>
Write tab
<div class="form-group tab-pane fade" id="qwrite">
<form id="newqform" name="newqform">
<div class="col-md-12">
<label for="template">Template:</label><select id="template">
<option value="activecode">
activecode
</option>
<option value="mchoice">
multiple choice
</option>
<option value="clickablearea">
clickable area
</option>
<option value="codelens">
codelens
</option>
<option value="dragndrop">
drag and drop
</option>
<option value="parsonsprob">
parsons
</option>
<option value="fillintheblank">
fill in the blank
</option>
<option value="poll">
poll
</option>
<option value="reveal">
reveal
</option>
<option value="shortanswer">
short answer
</option>
<option value="datafile">
Data File
</option>
<option value="selectquestion">
Select Question
</option>
</select> <input class="btn" onclick="display_write();" type="button" value="Go">
</div>
<div id="hiddenwrite" style="visibility: hidden">
<div class="col-md-12">
<label for="qcode"></label>
<textarea cols="65" form="newqform" id="qcode" name="editRST" rows="12"></textarea>
<p>You are writing in <a href="https://www.sphinx-doc.org/en/latest/usage/restructuredtext/basics.html">restructuredText</a>, indentation matters.</p>
</div>
<div class="col-md-12">
<p id="qnameerror" style="color: red"></p>
</div>
<div class="col-md-12">
<label>Difficulty:</label> 1<input checked="checked" id="difficulty1" name="difficulty" type="radio" value="1"> <input id="difficulty2" name="difficulty" type="radio" value="2"> <input id="difficulty3" name="difficulty" type="radio" value="3"> <input id="difficulty4" name="difficulty" type="radio" value="4"> <input id="difficulty5" name="difficulty" type="radio" value="5">5
</div>
<div class="col-md-12">
<label for="qtags">Tags:</label> <input id="qtags" type="text">
</div>
<div class="col-md-12">
<label>Location:</label><select id="qchapter">
<option>
Chapter
</option>
</select>
</div>
<div class="col-md-12">
<label for="isprivate">Private</label><input id="isprivate" type="checkbox">
</div>
<div class="col-md-12">
<label for="createpoints">Points</label> <input id="createpoints" name="points" type="number" value="1"> <label for="createtimed">Timed</label> <input id="createtimed" name="timed" type="checkbox" value="true">
</div>
<input type="hidden" id="qrawhtml" name="qrawhtml" value="">
<div class="col-md-12">
<input class="btn btn-default" onclick="preview_question(this.form);" type="button" value="Generate/View HTML">
<input class="btn btn-default" onclick="create_question(this.form);" type="button" value="Save and Add">
</div>
</div>
</form>
</div>
</div>
<div id="component-preview" class="col-md-6">
</div>
General purpose dialog for editing a question aria-labelledby=”EditQuestion”
{{include "_qeditor.html"}}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script type="text/javascript">
var question_picker = $('#tree-question-picker');
var readings_picker = $('#tree-readings-picker');
var question_table = $('#questionTable');
var readings_table = $('#readingsTable');
// Do all config after the DOM is `ready <https://api.jquery.com/ready/>`_.
$(function () {
$("#tags").select2();
$("#addTags").select2();
$(".dashboardnav").removeClass("active");
$("#assignmentstab").addClass("active");
$('#datetimepicker').datetimepicker();
configure_tree_picker(question_picker, eBookConfig.toc.question_picker, $('#search-tree-question-picker'), 3,
// TODO: Remember last user selections for points, autograde, and which_to_grade, instead of hard-coding them here.
// Called when a node is checked.
async function (node) {
let autograde = 'pct_correct';
let whichto = 'best_answer';
if (node.text.indexOf("✓") === -1) {
autograde = 'manual';
whichto = '';
}
let resp = await updateAssignmentRaw(node.id, 1, autograde, whichto);
return resp;
},
// Called when a node is unchecked. - node.id is the question.name
function (node) { remove_question(node.id); }
);
question_picker.on('ready.jstree', function(event, data) {
// Display the first assignment and the browser after the tree is ready. If triggered before, the tree can't find nodes, check boxes, etc.
assignmentInfo();
$('#browse-button').click();
});
// Ask for `events <https://www.jstree.com/docs/events/>`_ when an item is `selected <https://www.jstree.com/api/#/?q=.jstree Event&f=select_node.jstree>`_.
question_picker.on('select_node.jstree', function(event, data) {
// If this is a question (a leaf node), then preview it.
if (jstree_node_depth(data.instance, data.node) == 3) {
preview_question_id(data.node.id);
}
});
configure_tree_picker(readings_picker, eBookConfig.toc.reading_picker, $('#search-tree-readings-picker'), 2,
// Called when a node is checked.
async function (node) { let res = await updateReading(node.id, -1, 1, 'interact', 'best_answer'); return res },
// Called when a node is unchecked.
function (node) { remove_reading(node.id); }
);
// This is a `bootstrap table <http://bootstrap-table.wenzhixin.net.cn>`_. Configuration:
question_table.bootstrapTable({
// Select the ``question`` column as a unique id, per the `bootstrap docs <http://bootstrap-table.wenzhixin.net.cn/documentation/>`_.
uniqueId: 'question_id',
// Make the `rows reorderable <https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/reorder-rows>`_.
reorderableRows: true,
// Give names for each column, so they can be added via JavaScript, per the `bootstrap docs`_.
columns : [
{
field: 'question',
title: 'Question',
}, {
field: 'question_id',
visible: false,
}, {
field: 'points',
title: 'Points',
// Make the points value editable.
editable: true,
}, {
field: 'autograde',
title: 'Auto-grade',
// Specify that the ``autograde`` column should be edited by a select drop-down. See `type <http://vitalets.github.io/x-editable/docs.html#editable>`_, and `source <http://vitalets.github.io/x-editable/docs.html#select>`_ attributes.
//
// A bit of a hack: editable is normally a Boolean, but is used to initialized the editable object, so I'm providing an Object instead which produces custom menus for each cell.
editable: {
source: function () {
return menu_from_editable(this, {manual: 'Manual', all_or_nothing: 'All or nothing', pct_correct: '% correct', interact: 'Interaction'}, 'autograde_possible_values', question_table);
},
},
editableType: 'select',
}, {
field: 'autograde_possible_values',
visible: false,
}, {
field: 'which_to_grade',
title: 'Which to grade',
editable: {
source: function () {
// Update the menu for this item.
return menu_from_editable(this, {first_answer: 'First answer', last_answer: 'Last answer', best_answer: 'Best answer'}, 'which_to_grade_possible_values', question_table);
}
},
editableType: 'select',
}, {
field: 'which_to_grade_possible_values',
visible: false,
}, {
// Add a delete column with a button.
field: 'delete',
title: 'Delete',
formatter: function (value, row, index) {
// Copied from ``operateFormatter`` in an `example <https://github.com/wenzhixin/bootstrap-table-examples/blob/master/welcome.html>`_.
return [
'<a class="question_table_remove" href="javascript:void(0)" title="Remove">',
'<i class="glyphicon glyphicon-remove"><\/i>',
'<\/a>'
].join('');
},
events: {
// Copied from ``operateEvents`` in an example_.
'click .question_table_remove': function (e, value, row, index) {
// Unchecking the question in the tree picker also deletes it from the database and table.
if (question_picker.jstree(true).get_node(row['question_id'])) {
question_picker.jstree(true).uncheck_node(row['question_id']);
} else {
// sometimes questions get moved or go private and may be in an old assignment, but no longer
// part of the jstree. In that case removal should not fail, but we may have to do it directly.
remove_question(row["question_id"]);
}
},
},
},
],
// Configure `events <http://bootstrap-table.wenzhixin.net.cn/documentation/#events>`_.
// See `onEditableSave <https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/editable#oneditablesaveeditable-savebstable>`_.
onEditableSave : async function(field, row, oldValue, html_element) {
let resp = await updateAssignmentRaw(row['question_id'], row['points'], row['autograde'], row['which_to_grade']);
add_to_qtable(resp);
},
// This function produces no useful output -- the ``dragRow`` and ``droppedAfterRow`` vars sometimes have no relationship to the actual event. I left it here in case for future development.
///onReorderRow : function(rows) {
/// var [dragRow, droppedAfterRow] = rows;
/// console.log(dragRow);
/// console.log(droppedAfterRow);
/// var data = question_table.bootstrapTable('getData');
///},
// This will be called multiple times. Record the beginning row of the drag.
onReorderRowsDrag: function(table, row) {
table.dragRowIndex = $(row).attr('data-index');
table.dragRowId = $(table).bootstrapTable('getData')[table.dragRowIndex]['question_id'];
},
onReorderRowsDrop: function(table, row) {
dropRowIndex = $(row).attr('data-index');
// Create an array of question names in the order they appear in the table.
var question_array = [];
for (let value of $(table).bootstrapTable('getData')) {
question_array.push(value['question_id']);
}
// Send it to the server.
$.getJSON('reorder_assignment_questions', {
assignment_id: getAssignmentId(),
names: question_array,
}).fail(function() {
alert("Failed to Save your reordered question");
});
},
});
// This is a `bootstrap table`_. Configuration:
readings_table.bootstrapTable({
// Select the ``subchapter_id`` column as a unique id, per the `bootstrap docs <http://bootstrap-table.wenzhixin.net.cn/documentation/>`_.
uniqueId: 'subchapter_id',
// Make the `rows reorderable <https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/reorder-rows>`_.
reorderableRows: true,
// Give names for each column, so they can be added via JavaScript, per the `bootstrap docs`_.
columns : [
{
field: 'chapter',
title: 'Chapter',
}, {
field: 'subchapter',
title: 'Subchapter',
}, {
// Hide the subchapter ID.
field: 'subchapter_id',
visible: false,
}, {
field: 'activity_count',
title: 'Activity count',
}, {
field: 'activities_required',
title: '# required',
// The hack_ again.
editable: {
// TODO: Validate that this is <= activity_count. See validate at http://vitalets.github.io/x-editable/docs.html#editable.
validate: function(value) {
var row = row_from_editable(this, readings_table);
// See `isNaN use <https://stackoverflow.com/a/175787>`_.
if (isNaN(value) || value < 0) {
return '# required must be a non-negative number.'
}
if (value > row['activity_count']) {
return '# required must not exceed the activity count.';
}
},
},
}, {
field: 'points',
title: 'Points',
// Make the points value editable.
editable: true,
}, {
field: 'autograde',
title: 'Auto-grade',
// Specify that the ``autograde`` column should be edited by a select drop-down. See `type <http://vitalets.github.io/x-editable/docs.html#editable>`_, and `source <http://vitalets.github.io/x-editable/docs.html#select>`_ attributes.
//
// A bit of a _`hack`: editable is normally a Boolean, but is used to initialized the editable object, so I'm providing an Object instead which produces custom menus for each cell.
editable: {
source: function () {
return menu_from_editable(this, {interact: 'Interaction', correct_answer: 'Correct answer',}, 'autograde_possible_values', readings_table);
},
},
editableType: 'select',
}, {
field: 'autograde_possible_values',
visible: false,
}, {
field: 'which_to_grade',
title: 'Which to grade',
editable: {
source: function () {
// Update the menu for this item.
return menu_from_editable(this, {first_answer: 'First answer', last_answer: 'Last answer', best_answer: 'Best answer', any: 'Any'}, 'which_to_grade_possible_values', readings_table);
}
},
editableType: 'select',
}, {
field: 'which_to_grade_possible_values',
visible: false,
}, {
// Add a delete column with a button.
field: 'delete',
title: 'Delete',
formatter: function (value, row, index) {
// Copied from ``operateFormatter`` in an `example <https://github.com/wenzhixin/bootstrap-table-examples/blob/master/welcome.html>`_.
return [
'<a class="readings_table_remove" href="javascript:void(0)" title="Remove">',
'<i class="glyphicon glyphicon-remove"><\/i>',
'<\/a>'
].join('');
},
events: {
// Copied from ``operateEvents`` in an example_.
'click .readings_table_remove': function (e, value, row, index) {
// Unchecking the question in the tree picker also deletes it from the database and table.
readings_picker.jstree(true).uncheck_node(row['subchapter_id']);
},
},
},
],
// Configure `events <http://bootstrap-table.wenzhixin.net.cn/documentation/#events>`_.
//
// See `onEditableSave <https://github.com/wenzhixin/bootstrap-table/tree/master/src/extensions/editable#oneditablesaveeditable-savebstable>`_.
onEditableSave : async function(field, row, oldValue, html_element) {
let resp = await updateReading(row['subchapter_id'], row['activities_required'], row['points'], row['autograde'], row['which_to_grade']);
add_to_table(resp);
},
//
// This will be called multiple times. Record the beginning row of the drag.
onReorderRowsDrag: function(table, row) {
table.dragRowIndex = $(row).attr('data-index');
table.dragRowId = $(table).bootstrapTable('getData')[table.dragRowIndex]['subchapter_id'];
},
onReorderRowsDrop: function(table, row) {
dropRowIndex = $(row).attr('data-index');
// For debug if needed later.
///console.log('drag', table.dragRowId, 'from row', table.dragRowIndex, 'to row', dropRowIndex);
// Create an array of question names in the order they appear in the table.
var question_array = [];
for (let value of $(table).bootstrapTable('getData')) {
question_array.push(value['subchapter_id']);
}
// Send it to the server.
$.getJSON('reorder_assignment_questions', {
assignment_id: getAssignmentId(),
names: question_array,
}).fail(function() {
alert("Failed to save your reordered question");
})
},
});
});
</script>
{{ end }}