Fixed: Duplicating question while creating form, UI changes

This commit is contained in:
yash 2024-07-19 16:38:05 +05:30
parent eedc2668da
commit 2f7529ce2e
10 changed files with 178 additions and 198 deletions

View File

@ -10,14 +10,23 @@ use App\Models\Response;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Session;
use Illuminate\Validation\Rules\Unique;
class FormController extends Controller
{
public function index()
{
// Get forms belonging to the authenticated user
$totalForms = Form::count();
$publishedForms = Form::where('is_published', true)->count();
$totalResponses = Response::count();
$forms = Form::where('user_id', Auth::id())->get();
return view('forms.index', compact('forms'));
return view('forms.index', [
'forms' => $forms,
'totalForms' => $totalForms,
'publishedForms' => $publishedForms,
'totalResponses' => $totalResponses,
]);
}
public function create()
@ -36,13 +45,11 @@ class FormController extends Controller
public function edit(Form $form)
{
// Questions are already fetched with their options cast to array due to the casts property
$questions = $form->questions;
foreach ($questions as $question) {
$question->options = json_decode($question->options, true);
}
// Pass the questions to the view
return view('forms.edit', compact('form', 'questions'));
}
@ -61,6 +68,7 @@ class FormController extends Controller
'questions.*.required' => 'nullable|boolean',
]);
$form = new Form();
$form->title = $validatedData['title'];
$form->description = $validatedData['description'];
@ -78,6 +86,8 @@ class FormController extends Controller
$question->save();
}
return response()->json(['success' => true, 'form_id' => $form->id]);
} catch (\Exception $e) {
Log::error('Error saving form: ' . $e->getMessage(), ['exception' => $e]);
@ -145,7 +155,6 @@ class FormController extends Controller
$existingQuestionIds[] = $question->id;
}
// Delete questions that were removed
$form->questions()->whereNotIn('id', $existingQuestionIds)->delete();
Log::info('Remaining questions: ', $form->questions()->get()->toArray());

View File

@ -85,7 +85,7 @@ public function viewResponses(Form $form)
}
}
return view('responses.viewResponses', compact('form', 'responses', 'statistics'));
return view('responses.viewResponses', compact('form', 'responses', 'statistics', 'questions'));
}

16
package-lock.json generated
View File

@ -5,7 +5,8 @@
"packages": {
"": {
"dependencies": {
"sweetalert": "^2.1.2"
"sweetalert": "^2.1.2",
"toastr": "^2.1.4"
},
"devDependencies": {
"@popperjs/core": "^2.11.6",
@ -889,6 +890,11 @@
"node": ">=0.12.0"
}
},
"node_modules/jquery": {
"version": "3.7.1",
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz",
"integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg=="
},
"node_modules/laravel-vite-plugin": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/laravel-vite-plugin/-/laravel-vite-plugin-1.0.5.tgz",
@ -1107,6 +1113,14 @@
"node": ">=8.0"
}
},
"node_modules/toastr": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/toastr/-/toastr-2.1.4.tgz",
"integrity": "sha512-LIy77F5n+sz4tefMmFOntcJ6HL0Fv3k1TDnNmFZ0bU/GcvIIfy6eG2v7zQmMiYgaalAiUv75ttFrPn5s0gyqlA==",
"dependencies": {
"jquery": ">=1.12.0"
}
},
"node_modules/vite": {
"version": "5.3.3",
"resolved": "https://registry.npmjs.org/vite/-/vite-5.3.3.tgz",

View File

@ -14,6 +14,7 @@
"vite": "^5.0.0"
},
"dependencies": {
"sweetalert": "^2.1.2"
"sweetalert": "^2.1.2",
"toastr": "^2.1.4"
}
}

View File

@ -47,7 +47,7 @@ document.addEventListener("DOMContentLoaded", function () {
function addNewQuestion() {
const newQuestionDiv = document.createElement("div");
newQuestionDiv.className = "question";
// newQuestionDiv.className = "question";
newQuestionDiv.innerHTML = `
<div class="question mb-4 p-4 border rounded bg-white">
<select class="form-control question_type mb-1" onchange="changeQuestionType(this)">
@ -59,7 +59,7 @@ document.addEventListener("DOMContentLoaded", function () {
</select>
<input type="text" name="question" class="form-control question-input mb-3" placeholder="Type your question here" />
<div class="options-container mb-3">
<!-- Options or text input will be dynamically added here -->
</div>
<button class="btn btn-secondary add-option-btn" onclick="addOption(this)">
Add Option
@ -119,6 +119,8 @@ document.addEventListener("DOMContentLoaded", function () {
const questions = document.querySelectorAll(".question");
let formData = [];
console.log(questions);
questions.forEach((question) => {
const questionType = question.querySelector("select").value;
const questionText = question.querySelector(".question-input").value;
@ -135,6 +137,13 @@ document.addEventListener("DOMContentLoaded", function () {
options: options,
required: isRequired
});
console.log({
type: questionType,
text: questionText,
options: options,
required: isRequired
});
});
const csrfTokenMeta = document.querySelector('meta[name="csrf-token"]');
@ -152,6 +161,8 @@ document.addEventListener("DOMContentLoaded", function () {
questions: formData
};
console.log(data);
fetch("/forms", {
method: "POST",
@ -195,6 +206,8 @@ document.addEventListener("DOMContentLoaded", function () {
window.addNewQuestion = addNewQuestion;
window.deleteQuestion = deleteQuestion;
window.addOption = addOption;
@ -202,34 +215,7 @@ document.addEventListener("DOMContentLoaded", function () {
window.changeQuestionType = changeQuestionType;
window.saveForm = saveForm;
window.previewForm = function (formId) {
const formTitle = document.getElementById("form-title").value;
const formDescription = document.getElementById("form-description").value;
const questions = document.querySelectorAll(".question");
let formData = [];
questions.forEach((question) => {
const questionType = question.querySelector("select").value;
const questionText = question.querySelector(".question-input").value;
const options = Array.from(question.querySelectorAll(".option-input")).map((input) => input.value);
formData.push({
type: questionType,
text: questionText,
options: options,
});
});
const formParams = new URLSearchParams({
title: formTitle,
description: formDescription,
data: JSON.stringify(formData),
});
window.location.href = '/forms/' + formId + '/preview';
};
// Assuming there's a button with id "add-question-button"
document.getElementById("add-question-button").addEventListener("click", addNewQuestion);
// document.getElementById("add-question-button").addEventListener("click", addNewQuestion);
document.getElementById("questions_section").addEventListener("DOMNodeInserted", updateAddButtonPosition);
document.getElementById("questions_section").addEventListener("DOMNodeRemoved", updateAddButtonPosition);

View File

@ -1,104 +1,4 @@
{{-- <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>Google-Form-Clone</title>
<link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet" />
<link rel="stylesheet" href={{ asset('css/app.css') }} />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,300..800;1,300..800&display=swap"
rel="stylesheet" />
</head>
<body>
<nav class="bg-white p-4 shadow-lg">
<div class="container mx-auto flex justify-between items-center">
<a href="{{ url('/') }}" style="color: rgb(103,58,183)"
class="text-3xl font-bold font-sans">LaraForms</a>
<div class="relative dropdown">
<button id="profileMenuButton" class="flex items-center focus:outline-none">
<img src="{{ asset('images/user.png') }}" alt="Profile"
class="w-10 h-10 rounded-full border-2 border-white">
</button>
<div id="profileMenu"
class="dropdown-menu hidden absolute right-0 mt-2 w-48 bg-white rounded-md shadow-lg py-2">
<form method="POST" action="{{ route('logout') }}">
@csrf
<button type="submit" class="block px-4 py-2 text-gray-700 hover:bg-gray-200 w-full text-left">
Logout
</button>
</form>
</div>
</div>
</div>
</nav>
<div style="background-color: #f0ebf8; max-width: 100%" class="question_form p-4 rounded">
<div class="section">
<div class="question_title_section mb-1">
<div class="question_form_top">
<input type="text" id="form-title" name="title" class="form-control form-control-lg p-2 mb-2" placeholder="Untitled Form" />
<input type="text" name="description" id="form-description" class="form-control form-control-sm" placeholder="Form Description" />
</div>
</div>
</div>
<div class="section" id="questions_section">
<div class="question mb-4 p-3 border rounded bg-white">
<select class="form-control question_type mb-1" onchange="changeQuestionType(this)">
<option value="">Select Question Type</option>
<option value="multiple_choice">Multiple Choice</option>
<option value="checkbox">Checkbox</option>
<option value="dropdown">Dropdown</option>
</select>
<input type="text" name="question" class="form-control question-input mb-3" placeholder="Type your question here" />
<div class="options-container mb-3">
<div class="option d-flex align-items-center">
<input type="text" name="option" class="form-control option-input" placeholder="Option 1" />
<span class="delete-option ml-2 text-danger" onclick="deleteOption(this)" style="cursor: pointer;">&#10005;</span>
</div>
</div>
<button class="btn btn-secondary" onclick="addOption(this)">
Add Option
</button>
<button class="btn btn-md" id="moveUpButton" onclick="deleteQuestion(this);">
<img src="{{ asset('images/bin.png') }}" alt="" width="20px" height="20px" />
</button>
</div>
<div class="sidebar">
<div id="moveableDiv">
<button class="btn btn-light shadow-sm" onclick="addNewQuestion();">
<img src="{{ asset('images/add.png') }}" alt="" width="20px" height="20px" />
</button>
</div>
</div>
</div>
</div>
<div style="background-color: #f0ebf8"class="btnsub">
<span>
<button type="submit" name="save" value="save" onclick="saveForm()"
class="btnsave btn btn-secondary">
Save
</button>
</span>
&nbsp;
&nbsp;
&nbsp;
<span>
<button type="submit" name="publish" value="publish" onclick="saveForm()"
class="btnsave btn btn-secondary">
Publish
</button>
</span>
</div>
<script src={{ asset('js/script.js') }}></script>
</body>
</html> --}}
@ -122,7 +22,7 @@
</head>
<body style="background-color: #f4f4f9;" >
<nav class="bg-white p-4 shadow-sm">
<nav class="bg-white p-4 shadow-md">
<div class="mx-auto flex justify-between items-center">
<a href="{{ url('/') }}" style="color: rgb(103,58,183)"
class="text-3xl font-bold font-sans">LaraForms</a>
@ -146,7 +46,7 @@
<br><br>
<div style="background-color: #f4f4f9; max-width: 100%" class="question_form p-4 rounded">
<div class="section">
<div class="question_title_section mb-1">
<div class="question_title_section mb-4">
<div class="question_form_top">
<input type="text" id="form-title" name="title" class="form-control form-control-lg p-2 mb-2" placeholder="Untitled Form" />
<input type="text" name="description" id="form-description" class="form-control form-control-sm" placeholder="Form Description" />
@ -164,7 +64,7 @@
</select>
<input type="text" name="question" class="form-control question-input mb-3" placeholder="Type your question here" />
<div class="options-container mb-3">
<!-- Options or text input will be dynamically added here -->
</div>
<button class="btn btn-secondary add-option-btn" onclick="addOption(this)">
Add Option
@ -188,7 +88,7 @@
<div style="background-color: #f4f4f9;" class="btnsub">
<span>
<button type="submit" name="save" value="save" onclick="saveForm()"
<button type="submit" name="save" data-action:"save" value="save" onclick="saveForm()"
class="btnsave btn btn-secondary">
Save
</button>
@ -197,7 +97,7 @@
&nbsp;
&nbsp;
<span>
<button type="submit" name="publish" value="publish" onclick="saveForm()"
<button type="submit" name="publish" data-action:"publish" value="publish" onclick="saveForm()"
class="btnsave btn btn-secondary">
Publish
</button>

View File

@ -20,7 +20,7 @@
</style>
</head>
<body class="bg-light">
<body class="bg-purple-100">
<nav class="bg-white p-1 shadow-md">
<div class="container mx-auto flex justify-between items-center">
<span style="color: rgb(103,58,183)" class="text-3xl font-bold font-sans"><a href="{{ url('/') }}"

View File

@ -6,6 +6,8 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Forms</title>
<link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
<link href="//cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/css/toastr.min.css" rel="stylesheet" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/sweetalert2@11/dist/sweetalert2.min.css">
<style>
.dropdown:hover .dropdown-menu {
display: block;
@ -17,7 +19,7 @@
</style>
</head>
<body style="bg-gray-100">
<body class="bg-gray-100">
<nav class="bg-white p-4 shadow-lg">
<div class="container mx-auto flex justify-between items-center">
<a href="{{ url('/') }}" style="color: rgb(103,58,183)"
@ -49,16 +51,31 @@
<span class="block sm:inline">{{ session('delete') }}</span>
</div>
@endif
<div class="container mx-auto mt-10">
<div class="flex justify-between mb-6 items-center">
<div class="container mx-auto mt-10 ">
<div class="flex justify-between mb-6 items-center grid grid-cols-4 gap-20">
<a href="{{ route('forms.create') }}"
class="inline-block px-6 py-3 text-white font-semibold rounded-md shadow bg-purple-700 hover:bg-purple-900 transition duration-200">Start
a new form</a>
<a style="color: rgb(103,58,183)" class="block max-w-md p-5 bg-white border border-gray-200 rounded-lg shadow">
<h5 class="mb-2 text-gray-800 text-2xl font-bold tracking-tight text-gray-900 dark:text-white">Total Forms Created</h5>
<p class="font-normal text-gray-700 dark:text-gray-400">{{ $totalForms }}</p>
</a>
<a class="block max-w-md p-5 bg-white border border-gray-200 rounded-lg shadow">
<h5 class="mb-2 text-gray-800 text-2xl font-bold tracking-tight text-gray-900 dark:text-white">Total Forms Published</h5>
<p class="font-normal text-gray-700 dark:text-gray-400">{{ $publishedForms }}</p>
</a>
<a class="block max-w-md p-5 bg-white border border-gray-200 rounded-lg shadow">
<h5 class="mb-2 text-gray-800 text-2xl font-bold tracking-tight text-gray-900 dark:text-white">Total Responses Received</h5>
<p class="font-normal text-gray-700 dark:text-gray-400">{{ $totalResponses }}</p>
</a>
</div>
<h2 class="text-3xl font-semibold text-gray-800 font-sans">Recent Forms</h2>
<h2 class="text-3xl font-semibold text-gray-800 font-sans">Created Forms</h2>
<br>
<div class="bg-white shadow-custom rounded-lg p-6">
<div class="shadow-custom rounded-lg p-6 bg-gray-100">
@if ($forms->isEmpty())
<p class="text-gray-600 text-center">No forms available.</p>
@else
@ -76,8 +93,8 @@
Responses</th>
<th class="py-4 px-6 border-b border-gray-200 text-left text-sm font-semibold text-gray-600">
Status</th>
<th></th>
<th>
<th class="py-4 px-6 border-b border-gray-200 text-left text-sm font-semibold text-gray-600"></th>
<th class="py-4 px-6 border-b border-gray-200 text-left text-sm font-semibold text-gray-600">
</th>
</tr>
</thead>
@ -104,9 +121,11 @@
</td>
<td class="py-8 px-6 border-b border-gray-200 flex items-center space-x-10">
@if (!$form->is_published)
<a href="{{ route('forms.edit', $form) }}"
class="text-green-500 hover:underline">Edit</a>
<a href="{{ route('forms.edit', $form) }}" class="text-green-500 hover:underline">Edit</a>
@else
<a href="#" class="text-gray-500" id="formd" onclick="handle()">Edit</a>
@endif
</td>
<td>
<form action="{{ route('forms.destroy', $form) }}" method="POST"
@ -125,9 +144,13 @@
</div>
<script>
document.getElementById('profileMenuButton').addEventListener('click', function() {
document.getElementById('profileMenu').classList.toggle('hidden');
function handle() {
Swal.fire({
title: 'You cannot edit a published form',
icon: 'info',
confirmButtonText: 'OK'
});
}
setTimeout(function() {
var successMessage = document.getElementById('successMessage');
if (successMessage) {
@ -135,6 +158,8 @@
}
}, 3000);
</script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js" ></script>
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/js/toastr.min.js"></script>
</body>
</html>

View File

@ -13,29 +13,29 @@
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,300..800;1,300..800&display=swap" rel="stylesheet">
</head>
<body>
<nav class="bg-white p-4 shadow-sm">
<body class="bg-gray-100">
<nav class="bg-white p-2 shadow-gray-lg">
<div class="mx-auto flex justify-between items-center">
<a href="{{ url('/') }}" style="color: rgb(103,58,183)"
class="text-3xl font-bold font-sans">LaraForms</a>
<div class="relative dropdown">
<button id="profileMenuButton" class="flex items-center focus:outline-none">
<img src="{{ asset('images/user.png') }}" alt="Profile"
class="w-10 h-10 rounded-full border-2 border-white">
</button>
<div id="profileMenu"
class="dropdown-menu hidden absolute right-0 mt-2 w-48 bg-white rounded-md shadow-lg py-2">
<form method="POST" action="{{ route('logout') }}">
<div class="btnsub text-center mt-4">
<form action="{{ route('forms.publish', $form->id) }}" method="POST">
@csrf
<button type="submit" class="block px-4 py-2 text-gray-700 hover:bg-gray-200 w-full text-left">
Logout
</button>
@method('PATCH')
<span><button type="submit" name="publish" value="publish" class="btnsave btn btn-secondary">
{{ $form->is_published ? 'Unpublish' : 'Publish' }}
</button></span>
</form>
&nbsp;
&nbsp;
<div><button type="submit" name="publish" value="publish" class="btnsave btn btn-secondary">Edit</button></div>
</div>
</div>
</div>
</nav>
<div class="question_form bg-light p-4 rounded shadow-sm">
<div class="question_form bg-gray-100 p-4 rounded shadow-sm">
<div class="section">
<div class="question_title_section mb-4">
<div class="question_form_top">
@ -46,7 +46,7 @@
</div>
<div class="section" id="questions_section">
@foreach ($form->questions as $index => $question)
<div class="question mb-4 p-3 border rounded bg-white">
<div class="question mb-4 p-4 border rounded bg-white">
<select class="form-control question_type mb-3" name="questions[{{ $index }}][type]" onchange="changeQuestionType(this)" disabled>
<option value="multiple_choice" {{ $question->type === 'multiple_choice' ? 'selected' : '' }}>Multiple Choice</option>
<option value="checkbox" {{ $question->type === 'checkbox' ? 'selected' : '' }}>Checkbox</option>

View File

@ -11,19 +11,30 @@
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
</head>
<body style="background-color: rgb(253, 251, 251)" class="font-roboto text-gray-800">
<body class="font-roboto text-gray-800 bg-white">
<!-- Header -->
<div class="bg-white shadow-md px-6 py-4 flex justify-between items-center">
<div class="flex items-center">
<h1 class="text-2xl font-semibold text-purple-900">{{ $form->title }} - Responses</h1>
</div>
<div class="flex items-center">
<img src="{{ asset('images/menu.png') }}" alt="Menu" class="h-8 w-8 mr-4">
<img src="{{ asset('images/user.png') }}" alt="User" class="h-8 w-8">
<div class="relative dropdown">
<button id="profileMenuButton" class="flex items-center focus:outline-none">
<img src="{{ asset('images/user.png') }}" alt="Profile"
class="w-10 h-10 rounded-full border-2 border-white">
</button>
<div id="profileMenu"
class="dropdown-menu hidden absolute right-0 mt-2 w-48 bg-white rounded-md shadow-lg py-2">
<form method="POST" action="{{ route('logout') }}">
@csrf
<button type="submit" class="block px-4 py-2 text-gray-700 hover:bg-gray-200 w-full text-left">
Logout
</button>
</form>
</div>
</div>
</div>
<div class="text-sm font-medium text-center text-purple-700 border-b border-black-700 dark:text-gray-400 dark:border-gray-700 hover: border-b-2">
{{-- <div class="text-sm font-medium text-center text-purple-700 border-b border-black-700 dark:text-gray-400 dark:border-gray-700 hover: border-b-2">
<ul class="flex flex-wrap -mb-px">
<li class="mr-2">
<a href="javascript:void(0);" onclick="showTab('responses_tab')" class="tab-link text-black-600 font-bold inline-block p-4 border-b-2 border-transparent rounded-t-lg hover:text-purple-700 ">Responses</a>
@ -32,7 +43,7 @@
<a href="javascript:void(0);" onclick="showTab('statistics_tab')" class="tab-link text-black-600 font-bold inline-block p-4 border-b-2 border-transparent rounded-t-lg hover:text-purple-700 ">Statistics</a>
</li>
</ul>
</div>
</div> --}}
<!-- Main Content -->
<div class="mx-auto max-w-7xl px-6 py-8">
@ -42,7 +53,7 @@
<!-- Share Link -->
<div class="flex items-center mb-6">
<h2 class="text-xl font-semibold mr-4">Responses</h2>
<div class="flex items-center">
<input type="text" value="{{ route('responses.showForm', $form) }}" id="shareLink"
class="bg-white border border-gray-300 px-3 py-1 rounded-l sm:w-auto focus:outline-none"
@ -59,7 +70,9 @@
</div>
</div>
</div>
<br>
<h2 class="text-xl font-semibold mr-4">Responses</h2>
<br>
<!-- Responses Table -->
@if ($responses->isEmpty())
<p class="text-gray-600">No responses available.</p>
@ -100,7 +113,7 @@
</div>
<!-- Statistics Tab -->
<div id="statistics_tab" class="tab-content hidden w-3/6">
{{-- <div id="statistics_tab" class="tab-content hidden w-3/6">
<h2 class="text-xl font-semibold mb-6">Statistics</h2>
@foreach ($statistics as $questionId => $stat)
@ -109,7 +122,7 @@
<canvas id="chart-{{ $questionId }}"></canvas>
</div>
@endforeach
</div>
</div> --}}
</div>
<!-- Script for Copy Link Functionality -->
@ -140,7 +153,6 @@
document.querySelector(`[onclick="showTab('${tabId}')"]`).classList.add('border-purple-600', 'text-purple-600');
}
// Generate Charts
document.addEventListener('DOMContentLoaded', function () {
const statistics = @json($statistics);
console.log(statistics); // Log statistics for debugging
@ -178,28 +190,61 @@
backgroundColors = labels.map((_, index) => `rgba(${Math.floor(Math.random() * 255)}, ${Math.floor(Math.random() * 255)}, ${Math.floor(Math.random() * 255)}, 0.5)`);
}
new Chart(ctx, {
type: 'bar',
data: {
labels: labels,
datasets: [{
label: 'Responses',
data: data,
backgroundColor: backgroundColors,
borderColor: backgroundColors.map(color => color.replace('0.5', '1')),
borderWidth: 1
}]
},
options: {
scales: {
y: {
if (stat.type === 'multiple_choice' || stat.type === 'dropdown') {
new Chart(ctx, {
type: 'pie',
data: {
labels: labels,
datasets: [{
label: 'Responses',
data: data,
backgroundColor: backgroundColors,
borderColor: backgroundColors.map(color => color.replace('0.5', '1')),
borderWidth: 1
}]
},
options: {
scales: {
y: {
beginAtZero: true
}
}
responsive: true,
plugins: {
legend: {
position: 'top',
},
tooltip: {
enabled: true
}
}
}
}
});
});
} else if (stat.type === 'checkbox') {
new Chart(ctx, {
type: 'bar',
data: {
labels: labels,
datasets: [{
label: 'Responses',
data: data,
backgroundColor: backgroundColors,
borderColor: backgroundColors.map(color => color.replace('0.5', '1')),
borderWidth: 1
}]
},
options: {
scales: {
y: {
beginAtZero: true
}
}
}
});
}
});
});
</script>
<!-- Custom Scripts -->