343 lines
16 KiB
PHP
343 lines
16 KiB
PHP
@extends('layouts.app')
|
||
|
||
@push('styles')
|
||
<link rel="stylesheet" href="{{ asset('css/adminHeader.css') }}">
|
||
@endpush
|
||
|
||
@section('content')
|
||
|
||
@if ($errors->any())
|
||
<div class="alert alert-danger">
|
||
<strong>Ralat! Sila semak input anda:</strong>
|
||
<ul>
|
||
@foreach ($errors->all() as $error)
|
||
<li>{{ $error }}</li>
|
||
@endforeach
|
||
</ul>
|
||
</div>
|
||
@endif
|
||
|
||
<div class="container">
|
||
<div class="admin-header-box mb-4">
|
||
<div>
|
||
<h4>Daftar Soal Selidik</h4>
|
||
<p>Sila isi maklumat borang di bawah.</p>
|
||
</div>
|
||
</div>
|
||
|
||
@if (session('error'))
|
||
<div class="alert alert-danger alert-dismissible fade show" role="alert">
|
||
<strong>Ralat Sistem:</strong> {{ session('error') }}
|
||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||
</div>
|
||
@endif
|
||
|
||
<form method="POST" action="{{ route('admin.surveys.store') }}" id="survey-builder-form">
|
||
@csrf
|
||
<div class="card shadow-sm mb-4">
|
||
<div class="card-body p-4">
|
||
<div class="row">
|
||
<div class="col-md-8 mb-3">
|
||
<label for="title" class="form-label fw-bold">Tajuk Soal Selidik</label>
|
||
<input type="text" name="title" id="title" class="form-control" placeholder="eg: Sambutan Maulidur Rasul" value="{{ old('title') }}" required>
|
||
</div>
|
||
<div class="col-md-4 mb-3">
|
||
<label for="date" class="form-label fw-bold">Tarikh</label>
|
||
<input type="date" name="date" id="date" class="form-control" value="{{ old('date') }}" required>
|
||
</div>
|
||
<div class="col-md-12 mb-3">
|
||
<label for="perincian" class="form-label fw-bold">Perincian</label>
|
||
<textarea name="perincian" id="perincian" class="form-control" rows="3" placeholder="Terangkan tujuan borang ini (Pilihan)">{{ old('perincian') }}</textarea>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="sections-container"></div>
|
||
|
||
<button type="button" class="btn btn-outline-primary" id="add-section-btn">+ Tambah Bahagian</button>
|
||
|
||
<div class="text-end mt-4">
|
||
<a href="{{ route('admin.surveys.index') }}" class="btn btn-secondary btn-lg">Batal</a>
|
||
<button type="submit" class="btn btn-success btn-lg">Daftar</button>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
|
||
<template id="section-template">
|
||
<div class="card shadow-sm mb-4 section-block">
|
||
<div class="card-header bg-light d-flex justify-content-between align-items-center">
|
||
<h5 class="mb-0 section-title">Bahagian</h5>
|
||
<button type="button" class="btn btn-sm btn-outline-danger remove-section-btn">Hapus Bahagian</button>
|
||
</div>
|
||
<div class="card-body p-4">
|
||
<div class="row">
|
||
<div class="col-md-6 mb-3">
|
||
<input type="text" name="sections[0][title]" class="form-control section-title-input" placeholder="Tajuk Bahagian (cth: Maklumat Peribadi)" required>
|
||
</div>
|
||
<div class="col-md-6 mb-3">
|
||
<input type="text" name="sections[0][description]" class="form-control" placeholder="Keterangan (Pilihan)">
|
||
</div>
|
||
</div>
|
||
|
||
<div class="questions-container"></div>
|
||
|
||
<button type="button" class="btn btn-sm btn-info add-question-btn">+ Tambah soalan</button>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<template id="question-template">
|
||
<div class="border rounded p-3 mb-3 question-block bg-white">
|
||
<div class="d-flex justify-content-between align-items-center mb-2">
|
||
<label class="form-label fw-bold question-title">Soalan 1</label>
|
||
<div>
|
||
<div class="btn-group btn-group-sm" role="group">
|
||
<button type="button" class="btn btn-outline-secondary type-selector" data-type="radio">Radio</button>
|
||
<button type="button" class="btn btn-outline-secondary type-selector" data-type="text">Text</button>
|
||
<button type="button" class="btn btn-outline-secondary type-selector" data-type="checkbox">Checkbox</button>
|
||
</div>
|
||
<input type="hidden" name="sections[0][questions][0][type]" class="question-type-input" value="radio">
|
||
<button type="button" class="btn btn-sm btn-outline-danger ms-2 remove-question-btn">Hapus</button>
|
||
</div>
|
||
</div>
|
||
|
||
<input type="text" name="sections[0][questions][0][text]" class="form-control mb-3 question-text-input" placeholder="Isi soalan di sini" required>
|
||
|
||
<div class="form-check allow-other-container mb-3" data-allowed-types="radio,checkbox">
|
||
<input class="form-check-input allow-other-option-checkbox" type="checkbox"
|
||
value="1"
|
||
name="sections[0][questions][0][allow_other_option]">
|
||
<label class="form-check-label" for="flexCheckDefault">
|
||
Lain-lain
|
||
</label>
|
||
</div>
|
||
|
||
<div class="options-container">
|
||
<label class="form-label">Jawapan Pilihan</label>
|
||
<button type="button" class="btn btn-sm btn-link add-option-btn p-0">+ Tambah pilihan</button>
|
||
</div>
|
||
|
||
<div class="text-placeholder-container" style="display:none;">
|
||
<input type="text" class="form-control bg-light" placeholder="Ruang responden menjawab" disabled>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<template id="option-template">
|
||
<div class="input-group mb-2 option-group">
|
||
<input type="text" name="sections[0][questions][0][options][]" class="form-control option-input" placeholder="Pilihan jawapan" required>
|
||
<button type="button" class="btn btn-outline-danger remove-option-btn">Hapus</button>
|
||
</div>
|
||
</template>
|
||
|
||
@endsection
|
||
|
||
@push('scripts')
|
||
<script>
|
||
document.addEventListener('DOMContentLoaded', function () {
|
||
const sectionsContainer = document.getElementById('sections-container');
|
||
const addSectionBtn = document.getElementById('add-section-btn');
|
||
|
||
const sectionTemplate = document.getElementById('section-template');
|
||
const questionTemplate = document.getElementById('question-template');
|
||
const optionTemplate = document.getElementById('option-template');
|
||
|
||
let sectionCounter = 0;
|
||
|
||
function addSection() {
|
||
const sectionIndex = sectionCounter++;
|
||
const newSection = sectionTemplate.content.cloneNode(true).firstElementChild;
|
||
|
||
newSection.dataset.sectionIndex = sectionIndex;
|
||
newSection.querySelector('.section-title').textContent = `Bahagian`;
|
||
|
||
|
||
newSection.querySelectorAll('[name]').forEach(input => {
|
||
input.name = input.name.replace('sections[0]', `sections[${sectionIndex}]`);
|
||
});
|
||
|
||
addQuestion(newSection.querySelector('.questions-container'), sectionIndex);
|
||
|
||
sectionsContainer.appendChild(newSection);
|
||
reindexQuestions();
|
||
}
|
||
|
||
function addQuestion(questionsContainer, sectionIndex) {
|
||
const questionIndex = questionsContainer.querySelectorAll('.question-block').length;
|
||
const newQuestion = questionTemplate.content.cloneNode(true).firstElementChild;
|
||
|
||
newQuestion.dataset.questionIndex = questionIndex;
|
||
newQuestion.querySelector('.question-title').textContent = `Soalan ${questionIndex + 1}`;
|
||
|
||
newQuestion.querySelectorAll('[name]').forEach(input => {
|
||
input.name = input.name
|
||
.replace('sections[0]', `sections[${sectionIndex}]`)
|
||
.replace('[questions][0]', `[questions][${questionIndex}]`);
|
||
});
|
||
|
||
newQuestion.querySelector('.type-selector[data-type="radio"]').classList.add('active', 'btn-primary');
|
||
newQuestion.querySelector('.question-type-input').value = 'radio';
|
||
|
||
const otherCheckbox = newQuestion.querySelector('.allow-other-option-checkbox');
|
||
otherCheckbox.name = `sections[${sectionIndex}][questions][${questionIndex}][allow_other_option]`;
|
||
otherCheckbox.checked = false; // Pastikan bermula sebagai tidak dicentang
|
||
otherCheckbox.removeAttribute('checked')
|
||
|
||
const optionsContainer = newQuestion.querySelector('.options-container');
|
||
addOption(optionsContainer, sectionIndex, questionIndex);
|
||
addOption(optionsContainer, sectionIndex, questionIndex);
|
||
|
||
questionsContainer.appendChild(newQuestion);
|
||
reindexQuestions();
|
||
}
|
||
|
||
function addOption(optionsContainer, sectionIndex, questionIndex) {
|
||
const newOption = optionTemplate.content.cloneNode(true).firstElementChild;
|
||
newOption.querySelector('.option-input').name = `sections[${sectionIndex}][questions][${questionIndex}][options][]`;
|
||
|
||
const addBtn = optionsContainer.querySelector('.add-option-btn');
|
||
optionsContainer.insertBefore(newOption, addBtn);
|
||
}
|
||
|
||
function reindexQuestions() {
|
||
sectionsContainer.querySelectorAll('.section-block').forEach((section, sIdx) => {
|
||
section.dataset.sectionIndex = sIdx;
|
||
section.querySelectorAll('.section-title-input').forEach(input => {
|
||
input.name = input.name.replace(/sections\[\d+\]/, `sections[${sIdx}]`);
|
||
});
|
||
|
||
section.querySelectorAll('.question-block').forEach((q, qIdx) => {
|
||
q.dataset.questionIndex = qIdx;
|
||
q.querySelector('.question-title').textContent = `Soalan ${qIdx + 1}`;
|
||
q.querySelectorAll('[name]').forEach(input => {
|
||
input.name = input.name
|
||
.replace(/sections\[\d+\]/, `sections[${sIdx}]`)
|
||
.replace(/questions\[\d+\]/, `questions[${qIdx}]`);
|
||
});
|
||
|
||
const type = q.querySelector('.question-type-input').value;
|
||
const optionsContainer = q.querySelector('.options-container');
|
||
const textPlaceholder = q.querySelector('.text-placeholder-container');
|
||
const otherContainer = q.querySelector('.allow-other-container');
|
||
|
||
if (type === 'text') {
|
||
optionsContainer.style.display = 'none';
|
||
textPlaceholder.style.display = 'block';
|
||
otherContainer.style.display = 'none'; // Sembunyikan untuk jenis 'text'
|
||
q.querySelector('.allow-other-option-checkbox').checked = false;
|
||
q.querySelector('.allow-other-option-checkbox').removeAttribute('checked');
|
||
|
||
// Buang input options supaya tidak dihantar jika jenis 'text'
|
||
// Ini penting, jika tidak, validation akan gagal
|
||
q.querySelectorAll('.option-group').forEach(group => group.remove());
|
||
|
||
} else {
|
||
optionsContainer.style.display = 'block';
|
||
textPlaceholder.style.display = 'none';
|
||
otherContainer.style.display = 'block'; // Tunjukkan untuk jenis 'radio'/'checkbox'
|
||
}
|
||
});
|
||
});
|
||
}
|
||
|
||
addSectionBtn.addEventListener('click', addSection);
|
||
|
||
sectionsContainer.addEventListener('click', function (e) {
|
||
if (e.target.classList.contains('add-question-btn')) {
|
||
const questionsContainer = e.target.closest('.card-body').querySelector('.questions-container');
|
||
const sectionIndex = parseInt(e.target.closest('.section-block').dataset.sectionIndex);
|
||
addQuestion(questionsContainer, sectionIndex);
|
||
}
|
||
|
||
if (e.target.classList.contains('add-option-btn')) {
|
||
const optionsContainer = e.target.closest('.options-container');
|
||
const questionBlock = e.target.closest('.question-block');
|
||
const sectionIndex = parseInt(e.target.closest('.section-block').dataset.sectionIndex);
|
||
const questionIndex = parseInt(questionBlock.dataset.questionIndex);
|
||
addOption(optionsContainer, sectionIndex, questionIndex);
|
||
}
|
||
|
||
if (e.target.classList.contains('type-selector')) {
|
||
const type = e.target.dataset.type;
|
||
const questionBlock = e.target.closest('.question-block');
|
||
|
||
questionBlock.querySelectorAll('.type-selector').forEach(btn => btn.classList.remove('active', 'btn-primary'));
|
||
e.target.classList.add('active', 'btn-primary');
|
||
|
||
questionBlock.querySelector('.question-type-input').value = type;
|
||
|
||
const optionsContainer = questionBlock.querySelector('.options-container');
|
||
const textPlaceholder = questionBlock.querySelector('.text-placeholder-container');
|
||
// BARU: Dapatkan container untuk checkbox 'Lain-lain'
|
||
const allowOtherContainer = questionBlock.querySelector('.allow-other-container');
|
||
|
||
if (type === 'text') {
|
||
optionsContainer.style.display = 'none';
|
||
textPlaceholder.style.display = 'block';
|
||
// BARU: Sembunyikan checkbox 'Lain-lain' untuk jenis 'text'
|
||
allowOtherContainer.style.display = 'none';
|
||
questionBlock.querySelector('.allow-other-option-checkbox').checked = false;
|
||
|
||
// Remove options
|
||
optionsContainer.querySelectorAll('.option-group').forEach(group => group.remove());
|
||
|
||
} else {
|
||
optionsContainer.style.display = 'block';
|
||
textPlaceholder.style.display = 'none';
|
||
// BARU: Tunjukkan checkbox 'Lain-lain' untuk jenis 'radio'/'checkbox'
|
||
allowOtherContainer.style.display = 'block';
|
||
|
||
// Tambah 2 pilihan jika tiada pilihan (bila tukar dari 'text')
|
||
if (optionsContainer.querySelectorAll('.option-group').length === 0) {
|
||
const sectionIndex = parseInt(e.target.closest('.section-block').dataset.sectionIndex);
|
||
const questionIndex = parseInt(questionBlock.dataset.questionIndex);
|
||
addOption(optionsContainer, sectionIndex, questionIndex);
|
||
addOption(optionsContainer, sectionIndex, questionIndex);
|
||
}
|
||
}
|
||
reindexQuestions();
|
||
}
|
||
|
||
if (e.target.closest('.remove-section-btn')) {
|
||
e.target.closest('.section-block').remove();
|
||
reindexQuestions();
|
||
}
|
||
if (e.target.closest('.remove-question-btn')) {
|
||
e.target.closest('.question-block').remove();
|
||
reindexQuestions();
|
||
}
|
||
if (e.target.closest('.remove-option-btn')) {
|
||
e.target.closest('.option-group').remove();
|
||
reindexQuestions();
|
||
}
|
||
});
|
||
|
||
document.getElementById('survey-builder-form').addEventListener('submit', function (e) {
|
||
sectionsContainer.querySelectorAll('.question-block').forEach(q => {
|
||
const isText = q.querySelector('.question-type-input').value === 'text';
|
||
|
||
// 1. Logik untuk soalan 'text' (buang options)
|
||
if (isText) {
|
||
q.querySelectorAll('.option-group').forEach(group => group.remove());
|
||
}
|
||
|
||
// 2. Logik untuk checkbox 'allow_other_option'
|
||
const otherCheckbox = q.querySelector('.allow-other-option-checkbox');
|
||
if (otherCheckbox) {
|
||
if (otherCheckbox.checked) {
|
||
otherCheckbox.value = '1';
|
||
otherCheckbox.setAttribute('checked', 'checked'); // Pastikan dihantar
|
||
} else {
|
||
otherCheckbox.removeAttribute('name');
|
||
otherCheckbox.removeAttribute('checked');
|
||
}
|
||
}
|
||
});
|
||
});
|
||
|
||
addSection();
|
||
});
|
||
</script>
|
||
@endpush
|