{{-- Shared "create exam" builder JS — included wherever the create-exam modal (_create_modal.blade.php) appears. --}} {{-- The including page may define window.onExamPublished(res) before this include to react to a successful publish. --}} var examQCount = 0; function examOptionLetter(idx){ return String.fromCharCode(65 + idx); } function markExamOptionCorrect(radio){ var row = radio.closest('.opt-row'); var wrap = row.parentElement; wrap.querySelectorAll('.opt-row').forEach(function(r){ r.classList.remove('is-correct'); }); row.classList.add('is-correct'); } function examOptionRowHtml(qId, idx, canRemove){ return '
' + '' + '' + examOptionLetter(idx) + '' + '' + '' + '
'; } function examTfRowHtml(qId, idx, label){ return '
' + '' + '' + label + '' + '' + '
'; } function renderExamOptions(qId, type){ var wrap = document.getElementById('opts-' + qId); var addBtn = document.getElementById('addOptBtn-' + qId); if (!wrap) return; if (type === 'true_false') { wrap.innerHTML = examTfRowHtml(qId, 0, "{{ trans('admin.True') }}") + examTfRowHtml(qId, 1, "{{ trans('admin.False') }}"); if (addBtn) addBtn.style.display = 'none'; } else { var html = ''; for (var i = 0; i < 4; i++) { html += examOptionRowHtml(qId, i, true); } wrap.innerHTML = html; if (addBtn) addBtn.style.display = ''; reindexExamOptions(qId); } } function reindexExamOptions(qId){ var wrap = document.getElementById('opts-' + qId); if (!wrap) return; var rows = wrap.querySelectorAll('.opt-row'); var hasChecked = false; rows.forEach(function(row, i){ var radio = row.querySelector('input[type=radio]'); radio.value = i; if (radio.checked) hasChecked = true; var letter = row.querySelector('.opt-letter'); if (letter) letter.textContent = examOptionLetter(i); var removeBtn = row.querySelector('.opt-remove'); if (removeBtn) removeBtn.disabled = rows.length <= 2; }); if (!hasChecked && rows.length) { rows[0].querySelector('input[type=radio]').checked = true; } rows.forEach(function(row){ row.classList.toggle('is-correct', row.querySelector('input[type=radio]').checked); }); } function addExamOption(qId){ var wrap = document.getElementById('opts-' + qId); if (!wrap) return; var idx = wrap.querySelectorAll('.opt-row').length; wrap.insertAdjacentHTML('beforeend', examOptionRowHtml(qId, idx, true)); reindexExamOptions(qId); } function removeExamOption(qId, btn){ var wrap = document.getElementById('opts-' + qId); if (!wrap || wrap.querySelectorAll('.opt-row').length <= 2) return; btn.closest('.opt-row').remove(); reindexExamOptions(qId); } function changeExamQuestionType(qId, select){ renderExamOptions(qId, select.value); } var EXAM_ATTACHMENT_ACCEPT = 'image/*,.pdf,.doc,.docx,.xls,.xlsx'; function examAttachmentBoxHtml(qId){ return '
' + '' + '
' + '' + '
' + '{{ trans('admin.Click to upload or drag and drop') }}' + '{{ trans('admin.Attachment types hint') }}' + '
' + '
' + '' + '
'; } function examAttachmentChanged(qId){ var input = document.getElementById('attachFile-' + qId); var label = document.getElementById('attachLabel-' + qId); label.textContent = input.files.length ? input.files[0].name : "{{ trans('admin.Click to upload or drag and drop') }}"; } function addExamQuestion(){ examQCount++; var n = examQCount; var id = 'q' + n; var wrap = document.getElementById('examQuestions'); var div = document.createElement('div'); div.className = 'q-card'; div.id = id; div.innerHTML = '
{{ trans('admin.Question') }} ' + n + '
' + '
' + '
' + '
' + '' + '
{{ trans('admin.Select the correct answer hint') }}
' + examAttachmentBoxHtml(n); wrap.appendChild(div); renderExamOptions(n, 'multiple_choice'); } function openExamBuilder(){ $('#examForm')[0].reset(); $('#examCourseSelect').trigger('reset-combo'); $('#examQuestions').html(''); examQCount = 0; addExamQuestion(); $('#examErrors').html(''); openModal('examModal'); } function publishExam(status){ $('#examErrors').html(''); var formEl = document.getElementById('examForm'); if (!$('#examQuestions').children().length) { $('#examErrors').html("{{ trans('admin.minimum questions required') }}"); return; } if (!formEl.reportValidity()) { return; } $('#examPublishBtn, #examSaveDraftBtn').prop('disabled', true); var formData = new FormData(formEl); formData.append('status', status); $.ajax({ url: "{{ route('dashboard.exams.store') }}", method: 'POST', data: formData, processData: false, contentType: false, success: function(res){ closeModal('examModal'); dashToast('✓', "{{ trans('admin.success') }}"); if (typeof onExamPublished === 'function') onExamPublished(res); }, error: function(xhr){ if (xhr.status === 422) { var errors = xhr.responseJSON.errors; var html = ''; $.each(errors, function(key, val){ html += val[0] + '
'; }); $('#examErrors').html(html); } else { var msg = (xhr.responseJSON && xhr.responseJSON.message) || "{{ trans('admin.faild') }}"; dashToast('✕', msg); } }, complete: function(){ $('#examPublishBtn, #examSaveDraftBtn').prop('disabled', false); } }); } (function(){ var field = $('#examCourseCombo'); var select = $('#examCourseSelect'); if (!field.length) return; var trigger = $(''); var panel = $('
'); var search = panel.find('.combo-search'); var list = panel.find('.combo-list'); select.before(trigger); field.append(panel); function renderTrigger(){ trigger.text(select.find('option:selected').text()); } function renderList(term){ term = (term || '').toLowerCase(); list.empty(); select.find('option').each(function(){ if (!this.value) return; var text = $(this).text(); if (term && text.toLowerCase().indexOf(term) === -1) return; var li = $('
  • ').text(text).attr('data-value', this.value); if (this.value === select.val()) li.addClass('sel'); list.append(li); }); if (!list.children().length) list.append($('
  • ').text("{{ __('admin.no_result') }}")); } function close(){ field.removeClass('open'); } trigger.on('click', function(){ var opening = !field.hasClass('open'); field.toggleClass('open', opening); if (opening) { search.val(''); renderList(''); setTimeout(function(){ search.trigger('focus'); }, 0); } }); search.on('input', function(){ renderList(this.value); }); search.on('keydown', function(e){ if (e.key === 'Escape') { e.stopPropagation(); close(); trigger.trigger('focus'); } if (e.key === 'Enter') { e.preventDefault(); list.find('li').not('.empty').first().trigger('click'); } }); list.on('click', 'li:not(.empty)', function(){ select.val($(this).attr('data-value')).trigger('change'); renderTrigger(); close(); }); $(document).on('click', function(e){ if (!field.is(e.target) && !field.has(e.target).length) close(); }); renderTrigger(); select.on('reset-combo', function(){ renderTrigger(); close(); }); })();