Files
myPostMortem/resources/views/admin/surveys/create.blade.php

343 lines
16 KiB
PHP
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
@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