2022-06-20 12:22:29 +01:00
|
|
|
const root = $('#editor-root')
|
2022-06-21 02:44:23 +01:00
|
|
|
Sortable.create(root.get(0), {handle: '.move-handle', onEnd: function(evt) {renumber_blocks()}})
|
2022-06-20 12:22:29 +01:00
|
|
|
|
2022-06-21 02:44:23 +01:00
|
|
|
var element_index = 0
|
|
|
|
var question_index = 0
|
2022-06-20 12:22:29 +01:00
|
|
|
|
2022-06-21 02:44:23 +01:00
|
|
|
root.on('click', '.panel-controls > a', function(event) {
|
|
|
|
event.preventDefault()
|
|
|
|
event.stopPropagation()
|
|
|
|
var action = $(this).data('action')
|
|
|
|
var element = $(this).closest('.accordion-item')
|
|
|
|
var root_container = $(this).closest('.accordion')
|
|
|
|
if (action == 'delete') {
|
|
|
|
element.remove()
|
|
|
|
console.log(root_container.get(0) == root.get(0))
|
|
|
|
if (root_container.get(0) != root.get(0) && root_container.children().length < 2 ) {
|
|
|
|
root_container.find('.panel-controls > a[data-action="delete"]').addClass('disabled')
|
|
|
|
}
|
|
|
|
} else if (action == 'add-question') {
|
|
|
|
var question = generate_single_question(root_container_id=`#${root_container.attr('id')}`)
|
|
|
|
$(question).insertBefore(element)
|
|
|
|
if (root_container.get(0) != root.get(0) && root_container.children().length > 1 ) {
|
|
|
|
root_container.find('.panel-controls > a[data-action="delete"]').removeClass('disabled')
|
|
|
|
}
|
|
|
|
} else if (action == 'add-block') {
|
|
|
|
var block = generate_block(root_container_id=`#${root_container.attr('id')}`)
|
|
|
|
$(block).insertBefore(element)
|
|
|
|
}
|
|
|
|
renumber_blocks()
|
|
|
|
})
|
|
|
|
|
|
|
|
root.on('change', '.form-select.question-type', function(event) {
|
|
|
|
event.preventDefault()
|
|
|
|
var type = $(this).val()
|
|
|
|
var options = $(this).closest('div.input-group').siblings('.options')
|
|
|
|
var option_controls = $(this).closest('div.input-group').siblings('.option-controls')
|
|
|
|
var correct = $(this).closest('div.input-group').siblings().find('.question-correct')
|
|
|
|
if (type == 'Yes/No') {
|
|
|
|
options.empty()
|
|
|
|
correct.empty()
|
|
|
|
var opt = `
|
|
|
|
<div class="input-group mb-3">
|
|
|
|
<span class="input-group-text">0</span>
|
|
|
|
<input type="text" class="form-control" value="Yes" disabled>
|
|
|
|
</div>
|
|
|
|
<div class="input-group mb-3">
|
|
|
|
<span class="input-group-text">1</span>
|
|
|
|
<input type="text" class="form-control" value="No" disabled>
|
|
|
|
</div>
|
|
|
|
`
|
|
|
|
options.append(opt)
|
|
|
|
option_controls.children('a').addClass('disabled')
|
|
|
|
var cor = `
|
|
|
|
<option value ="0" default>0</option>
|
|
|
|
<option value="1">1</option>
|
|
|
|
`
|
|
|
|
correct.append(cor)
|
|
|
|
} else {
|
|
|
|
option_controls.children('a').removeClass('disabled')
|
|
|
|
options.find('input').removeAttr('disabled')
|
|
|
|
if (options.children().length <= 2 ){
|
|
|
|
option_controls.children('a[data-action="delete"]').addClass('disabled')
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
root.on('click', '.option-controls > a', function(event) {
|
|
|
|
event.preventDefault()
|
|
|
|
var action = $(this).data('action')
|
|
|
|
var options = $(this).closest('div.option-controls').siblings('.options')
|
|
|
|
var length = options.children().length
|
|
|
|
var correct = $(this).closest('div.option-controls').siblings().find('.question-correct')
|
|
|
|
if (action == 'delete') {
|
|
|
|
if (length > 2) {
|
|
|
|
options.children().last().remove()
|
|
|
|
correct.children().last().remove()
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
var opt = `
|
|
|
|
<div class="input-group mb-3">
|
|
|
|
<span class="input-group-text">${length}</span>
|
|
|
|
<input type="text" class="form-control" value="Option ${length}">
|
|
|
|
</div>
|
|
|
|
`
|
|
|
|
options.append(opt)
|
|
|
|
var cor = `<option value="${length}">${length}</option>`
|
|
|
|
correct.append(cor)
|
|
|
|
}
|
|
|
|
length = options.children().length
|
|
|
|
if (length <= 2) {
|
|
|
|
$(this).closest('div.option-controls').children('a[data-action="delete"]').addClass('disabled')
|
|
|
|
} else {
|
|
|
|
$(this).closest('div.option-controls').children('a[data-action="delete"]').removeClass('disabled')
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$('.editor-controls > a').click(function(event){
|
|
|
|
event.preventDefault()
|
|
|
|
var action = $(this).data('action')
|
|
|
|
var root_accordion = $(this).closest('div').siblings('.accordion')
|
|
|
|
if (action == 'add-question') {
|
|
|
|
var obj = generate_single_question(root_container_id=`#${root_accordion.attr('id')}`)
|
|
|
|
root.append(obj)
|
|
|
|
} else if (action == 'add-block') {
|
|
|
|
var obj = generate_block(root_container_id=`#${root_accordion.attr('id')}`)
|
|
|
|
root.append(obj)
|
|
|
|
var block_container = $(`#element${element_index-1}`).children().find('.accordion')
|
|
|
|
Sortable.create(block_container.get(0), {handle: '.move-handle', onEnd: function(evt) {renumber_blocks()}})
|
|
|
|
var question = generate_single_question(root_container_id=`#${block_container.attr('id')}`)
|
|
|
|
block_container.append(question)
|
|
|
|
block_container.find('.panel-controls > a[data-action="delete"]').addClass('disabled')
|
|
|
|
} else if (action == 'done') {
|
|
|
|
parse_data(data)
|
|
|
|
}
|
|
|
|
renumber_blocks()
|
|
|
|
})
|
|
|
|
|
|
|
|
function parse_data(data) {
|
|
|
|
var block, obj, new_block, block_container, question, _question, new_question, options, correct, opt, tags
|
|
|
|
for (let c = 0; c < data.length; c++) {
|
|
|
|
block = data[c]
|
|
|
|
if (block['type'] == 'block') {
|
|
|
|
obj = generate_block(root_container_id=`#${root.attr('id')}`)
|
|
|
|
root.append(obj)
|
|
|
|
new_block = $(`#element${element_index-1}`)
|
|
|
|
new_block.find('.block-header-text').val(block['question_header']).trigger('change')
|
|
|
|
block_container = $(`#element${element_index-1}`).children().find('.accordion')
|
|
|
|
Sortable.create(block_container.get(0), {handle: '.move-handle', onEnd: function(evt) {renumber_blocks()}})
|
|
|
|
for (let _c = 0; _c < block['questions'].length; _c ++) {
|
|
|
|
question = block['questions'][_c]
|
|
|
|
_question = generate_single_question(root_container_id=`#${block_container.attr('id')}`)
|
|
|
|
block_container.append(_question)
|
|
|
|
if (block_container.children().length <= 1) {
|
|
|
|
block_container.find('.panel-controls > a[data-action="delete"]').addClass('disabled')
|
|
|
|
} else {
|
|
|
|
block_container.find('.panel-controls > a[data-action="delete"]').removeClass('disabled')
|
|
|
|
}
|
|
|
|
new_question = $(`#element${element_index-1}`)
|
|
|
|
new_question.find('.question-text').val(question['text']).trigger('change')
|
|
|
|
new_question.find('.question-type').val(question['q_type']).trigger('change')
|
|
|
|
correct = new_question.find('.question-correct')
|
|
|
|
if (question['q_type'] != 'Yes/No') {
|
|
|
|
options = new_question.find('.options')
|
|
|
|
options.empty()
|
|
|
|
correct.empty()
|
|
|
|
for ( var __c = 0; __c < question['options'].length; __c++) {
|
|
|
|
option = question['options'][__c]
|
|
|
|
opt = `
|
|
|
|
<div class="input-group mb-3">
|
|
|
|
<span class="input-group-text">${__c}</span>
|
|
|
|
<input type="text" class="form-control" value="${option}">
|
|
|
|
</div>
|
|
|
|
`
|
|
|
|
options.append(opt)
|
|
|
|
correct.append(`<option value="${__c}">${__c}</option>`)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
correct.val(String(question['correct']))
|
|
|
|
tags = question['tags'].join('\r\n')
|
|
|
|
new_question.find('.question-tags').val(tags)
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
question = block
|
|
|
|
obj = generate_single_question(root_container_id=`#${root.attr('id')}`)
|
|
|
|
root.append(obj)
|
|
|
|
new_question = $(`#element${element_index-1}`)
|
|
|
|
new_question.find('.question-text').val(question['text']).trigger('change')
|
|
|
|
new_question.find('.question-type').val(question['q_type']).trigger('change')
|
|
|
|
correct = new_question.find('.question-correct')
|
|
|
|
if (question['q_type'] != 'Yes/No') {
|
|
|
|
options = new_question.find('.options')
|
|
|
|
options.empty()
|
|
|
|
correct.empty()
|
|
|
|
for ( var _c = 0; _c < question['options'].length; _c++) {
|
|
|
|
option = question['options'][_c]
|
|
|
|
opt = `
|
|
|
|
<div class="input-group mb-3">
|
|
|
|
<span class="input-group-text">${_c}</span>
|
|
|
|
<input type="text" class="form-control" value="${option}">
|
|
|
|
</div>
|
|
|
|
`
|
|
|
|
options.append(opt)
|
|
|
|
correct.append(`<option value="${_c}">${_c}</option>`)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
correct.val(String(question['correct']))
|
|
|
|
tags = question['tags'].join('\r\n')
|
|
|
|
new_question.find('.question-tags').val(tags)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
renumber_blocks()
|
|
|
|
}
|
|
|
|
|
|
|
|
root.on('click', '.block-controls > a', function(event){
|
|
|
|
event.preventDefault()
|
|
|
|
var action = $(this).data('action')
|
|
|
|
var root_accordion = $(this).closest('div').siblings('.accordion')
|
|
|
|
if (action == 'add-question') {
|
|
|
|
var question = generate_single_question(root_container_id=`#${root_accordion.attr('id')}`)
|
|
|
|
root_accordion.append(question)
|
|
|
|
if (root_accordion.children().length > 1 ) {
|
|
|
|
root_accordion.find('.panel-controls > a[data-action="delete"]').removeClass('disabled')
|
|
|
|
} else {
|
|
|
|
root_accordion.find('.panel-controls > a[data-action="delete"]').addClass('disabled')
|
|
|
|
}
|
|
|
|
renumber_blocks()
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
function generate_single_question(root_container_id) {
|
|
|
|
if (root_container_id == `#${root.attr('id')}`) {
|
|
|
|
var block_button = `
|
|
|
|
<a href="javascript:void(0)" class="btn btn-primary" data-action="add-block" title="Add Block Above" aria-title="Add Block Above" data-bs-toggle="collapse" data-bs-target>
|
|
|
|
<i class="bi bi-folder-plus"></i>
|
|
|
|
</a>
|
|
|
|
`
|
|
|
|
} else {
|
|
|
|
var block_button = ''
|
|
|
|
}
|
|
|
|
var question = `
|
|
|
|
<div class="accordion-item" id="element${element_index}">
|
|
|
|
<h2 class="accordion-header" id="element${element_index}-header">
|
|
|
|
<div class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#element${element_index}-content" aria-expanded="true" aria-controls="element${element_index}-content">
|
|
|
|
<div class="float-start">
|
|
|
|
<div class="accordion-caption">
|
|
|
|
<span class="block-number"></span>.
|
|
|
|
Question
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="panel-controls float-end">
|
|
|
|
<a href="javascript:void(0)" class="btn btn-success move-handle" data-action="move-question" title="Move Question" aria-title="Move Question" data-bs-toggle="collapse" data-bs-target>
|
|
|
|
<i class="bi bi-arrows-move"></i>
|
|
|
|
</a>
|
|
|
|
${block_button}
|
|
|
|
<a href="javascript:void(0)" class="btn btn-primary" data-action="add-question" title="Add Question Above" aria-title="Add Question Above" data-bs-toggle="collapse" data-bs-target>
|
|
|
|
<i class="bi bi-file-plus-fill"></i>
|
|
|
|
</a>
|
|
|
|
<a href="javascript:void(0)" class="btn btn-danger" data-action="delete" title="Delete Block" aria-title="Delete Block" data-bs-toggle="collapse" data-bs-target>
|
|
|
|
<i class="bi bi-x-square-fill"></i>
|
|
|
|
</a>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</h2>
|
|
|
|
<div id="element${element_index}-content" class="accordion-collapse collapse" aria-labelledby="element${element_index}-header" data-bs-parent="${root_container_id}">
|
|
|
|
<div class="accordion-body">
|
|
|
|
<div class="input-group mb-3">
|
|
|
|
<span class="input-group-text">Question</span>
|
|
|
|
<textarea type="text" class="form-control question-text">Enter question here.</textarea>
|
|
|
|
</div>
|
|
|
|
<div class="input-group mb-3">
|
|
|
|
<span class="input-group-text">Question Type</span>
|
|
|
|
<select class="form-select question-type">
|
|
|
|
<option value ="Multiple Choice" default>Multiple Choice</option>
|
|
|
|
<option value="Yes/No">Yes/No</option>
|
|
|
|
<option value="List">Ordered List</option>
|
|
|
|
</select>
|
2022-06-20 12:22:29 +01:00
|
|
|
</div>
|
2022-06-21 02:44:23 +01:00
|
|
|
<label class="form-label">Options</label>
|
|
|
|
<ul class="options">
|
|
|
|
<div class="input-group mb-3">
|
|
|
|
<span class="input-group-text">0</span>
|
|
|
|
<input type="text" class="form-control" value="Option 0">
|
2022-06-20 12:22:29 +01:00
|
|
|
</div>
|
2022-06-21 02:44:23 +01:00
|
|
|
<div class="input-group mb-3">
|
|
|
|
<span class="input-group-text">1</span>
|
|
|
|
<input type="text" class="form-control" value="Option 1">
|
|
|
|
</div>
|
|
|
|
</ul>
|
|
|
|
<div class="option-controls">
|
|
|
|
<a href="javascript:void(0)" class="btn btn-danger disabled" data-action="delete" title="Delete Question" aria-title="Delete Question">
|
|
|
|
<i class="bi bi-patch-minus-fill"></i>
|
|
|
|
Delete
|
|
|
|
</a>
|
|
|
|
<a href="javascript:void(0)" class="btn btn-success" data-action="add" title="Add Question" aria-title="Add Question">
|
|
|
|
<i class="bi bi-patch-plus-fill"></i>
|
|
|
|
Add
|
|
|
|
</a>
|
|
|
|
</div>
|
|
|
|
<div class="input-group mb-3">
|
|
|
|
<span class="input-group-text">Correct</span>
|
|
|
|
<select class="form-select question-correct">
|
|
|
|
<option value ="0" default>0</option>
|
|
|
|
<option value="1">1</option>
|
|
|
|
</select>
|
|
|
|
</div>
|
|
|
|
<div class="input-group mb-3">
|
|
|
|
<span class="input-group-text">Tags</span>
|
|
|
|
<textarea type="text" class="form-control question-tags"></textarea>
|
2022-06-20 12:22:29 +01:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
2022-06-21 02:44:23 +01:00
|
|
|
</div>
|
|
|
|
`
|
|
|
|
element_index ++
|
|
|
|
return question
|
2022-06-20 12:22:29 +01:00
|
|
|
}
|
|
|
|
|
2022-06-21 02:44:23 +01:00
|
|
|
function generate_block(root_container_id) {
|
|
|
|
var block = `
|
|
|
|
<div class="accordion-item" id="element${element_index}">
|
|
|
|
<h2 class="accordion-header" id="element${element_index}-header">
|
|
|
|
<div class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#element${element_index}-content" aria-expanded="true" aria-controls="element${element_index}-content">
|
|
|
|
<div class="float-start">
|
|
|
|
<div class="accordion-caption">
|
|
|
|
<span class="block-number"></span>.
|
|
|
|
Block
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="panel-controls float-end">
|
|
|
|
<a href="javascript:void(0)" class="btn btn-success move-handle" data-action="move-question" title="Move Question" aria-title="Move Question" data-bs-toggle="collapse" data-bs-target>
|
|
|
|
<i class="bi bi-arrows-move"></i>
|
|
|
|
</a>
|
|
|
|
<a href="javascript:void(0)" class="btn btn-primary" data-action="add-block" title="Add Block Above" aria-title="Add Block Above" data-bs-toggle="collapse" data-bs-target>
|
|
|
|
<i class="bi bi-folder-plus"></i>
|
|
|
|
</a>
|
|
|
|
<a href="javascript:void(0)" class="btn btn-primary" data-action="add-question" title="Add Question Above" aria-title="Add Question Above" data-bs-toggle="collapse" data-bs-target>
|
|
|
|
<i class="bi bi-file-plus-fill"></i>
|
|
|
|
</a>
|
|
|
|
<a href="javascript:void(0)" class="btn btn-danger" data-action="delete" title="Delete Block" aria-title="Delete Block" data-bs-toggle="collapse" data-bs-target>
|
|
|
|
<i class="bi bi-x-square-fill"></i>
|
|
|
|
</a>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</h2>
|
|
|
|
<div id="element${element_index}-content" class="accordion-collapse collapse" aria-labelledby="element${element_index}-header" data-bs-parent="${root_container_id}">
|
|
|
|
<div class="accordion-body">
|
|
|
|
<div class="input-group mb-3">
|
|
|
|
<span class="input-group-text">Block Header</span>
|
|
|
|
<textarea type="text" class="form-control block-header-text">Enter the header text for this block of questions.</textarea>
|
|
|
|
</div>
|
|
|
|
<div class="accordion" id="element${element_index}-questions">
|
|
|
|
</div>
|
|
|
|
<div class="block-controls">
|
|
|
|
<a href="javascript:void(0)" class="btn btn-success" data-action="add-question" title="Add Question" aria-title="Add Question">
|
|
|
|
<i class="bi bi-file-plus-fill"></i>
|
|
|
|
Add Question
|
|
|
|
</a>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
`
|
|
|
|
element_index ++
|
|
|
|
return block
|
|
|
|
}
|
|
|
|
|
|
|
|
var myArray = [
|
|
|
|
"Apples",
|
|
|
|
"Bananas",
|
|
|
|
"Pears"
|
|
|
|
];
|
|
|
|
|
|
|
|
function renumber_blocks () {
|
|
|
|
$( ".block-number" ).each(function(index) {
|
|
|
|
$( this ).text($( this ).closest('.accordion-item').index())
|
|
|
|
})
|
|
|
|
}
|