Code and bug fixes
This commit is contained in:
parent
e747614bd3
commit
0d8c522732
|
@ -55,94 +55,92 @@ class FormController extends Controller
|
|||
|
||||
|
||||
public function createWithTemplate($template)
|
||||
{
|
||||
$data = [];
|
||||
{
|
||||
$data = [];
|
||||
|
||||
switch ($template) {
|
||||
case 'contact':
|
||||
$data = [
|
||||
'title' => 'Contact Information',
|
||||
'description' => 'Template for collecting contact information.',
|
||||
'questions' => [
|
||||
['type' => 'text', 'question_text' => 'Name'],
|
||||
['type' => 'text', 'question_text' => 'Email'],
|
||||
// Add more questions as needed
|
||||
],
|
||||
];
|
||||
break;
|
||||
switch ($template) {
|
||||
case 'contact':
|
||||
$data = [
|
||||
'title' => 'Contact Information',
|
||||
'description' => 'Template for collecting contact information.',
|
||||
'questions' => [
|
||||
['type' => 'text', 'question_text' => 'Name'],
|
||||
['type' => 'text', 'question_text' => 'Email'],
|
||||
// Add more questions as needed
|
||||
],
|
||||
];
|
||||
break;
|
||||
|
||||
case 'rsvp':
|
||||
$data = [
|
||||
'title' => 'RSVP',
|
||||
'description' => 'Event Address: 123 Your Street Your City, ST 12345
|
||||
case 'rsvp':
|
||||
$data = [
|
||||
'title' => 'RSVP',
|
||||
'description' => 'Event Address: 123 Your Street Your City, ST 12345
|
||||
Contact us at (123) 456-7890 or no_reply@example.com
|
||||
',
|
||||
'questions' => [
|
||||
['type' => 'text', 'question_text' => 'Can you attend?'],
|
||||
['type' => 'text', 'question_text' => 'Number of Guests'],
|
||||
// Add more questions as needed
|
||||
],
|
||||
];
|
||||
break;
|
||||
'questions' => [
|
||||
['type' => 'text', 'question_text' => 'Can you attend?'],
|
||||
['type' => 'text', 'question_text' => 'Number of Guests'],
|
||||
],
|
||||
];
|
||||
break;
|
||||
|
||||
case 'party':
|
||||
$data = [
|
||||
'title' => 'Party Invite',
|
||||
'description' => 'Template for party invitations.',
|
||||
'questions' => [
|
||||
['type' => 'text', 'question_text' => 'Name'],
|
||||
['type' => 'text', 'question_text' => 'RSVP Status'],
|
||||
// Add more questions as needed
|
||||
],
|
||||
];
|
||||
break;
|
||||
case 'party':
|
||||
$data = [
|
||||
'title' => 'Party Invite',
|
||||
'description' => 'Template for party invitations.',
|
||||
'questions' => [
|
||||
['type' => 'text', 'question_text' => 'Name'],
|
||||
['type' => 'text', 'question_text' => 'RSVP Status'],
|
||||
],
|
||||
];
|
||||
break;
|
||||
}
|
||||
|
||||
return view('forms.create', ['data' => $data]);
|
||||
}
|
||||
|
||||
return view('forms.create', ['data' => $data]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public function store(Request $request)
|
||||
{
|
||||
try {
|
||||
$validatedData = $request->validate([
|
||||
'title' => 'required|string|max:255',
|
||||
'description' => 'nullable|string',
|
||||
'questions' => 'required|array',
|
||||
'questions.*.type' => 'required|string|in:multiple_choice,checkbox,dropdown,text',
|
||||
'questions.*.text' => 'required|string',
|
||||
'questions.*.options' => 'nullable|array',
|
||||
'questions.*.required' => 'nullable|boolean',
|
||||
]);
|
||||
{
|
||||
try {
|
||||
$validatedData = $request->validate([
|
||||
'title' => 'required|string|max:255',
|
||||
'description' => 'nullable|string',
|
||||
'questions' => 'required|array',
|
||||
'questions.*.type' => 'required|string|in:multiple_choice,checkbox,dropdown,text',
|
||||
'questions.*.text' => 'required|string',
|
||||
'questions.*.options' => 'nullable|array',
|
||||
'questions.*.required' => 'nullable|boolean',
|
||||
]);
|
||||
|
||||
|
||||
$form = new Form();
|
||||
$form->title = $validatedData['title'];
|
||||
$form->description = $validatedData['description'];
|
||||
$form->is_published = $request->input('is_published', false);
|
||||
$form->user_id = Auth::id();
|
||||
$form->save();
|
||||
$form = new Form();
|
||||
$form->title = $validatedData['title'];
|
||||
$form->description = $validatedData['description'];
|
||||
$form->is_published = $request->input('is_published', false);
|
||||
$form->user_id = Auth::id();
|
||||
$form->save();
|
||||
|
||||
foreach ($validatedData['questions'] as $questionData) {
|
||||
$question = new Question();
|
||||
$question->form_id = $form->id;
|
||||
$question->type = $questionData['type'];
|
||||
$question->question_text = $questionData['text'];
|
||||
$question->options = isset($questionData['options']) ? json_encode($questionData['options']) : null;
|
||||
$question->required = isset($questionData['required']) ? $questionData['required'] : false;
|
||||
$question->save();
|
||||
foreach ($validatedData['questions'] as $questionData) {
|
||||
$question = new Question();
|
||||
$question->form_id = $form->id;
|
||||
$question->type = $questionData['type'];
|
||||
$question->question_text = $questionData['text'];
|
||||
$question->options = isset($questionData['options']) ? json_encode($questionData['options']) : null;
|
||||
$question->required = isset($questionData['required']) ? $questionData['required'] : false;
|
||||
$question->save();
|
||||
}
|
||||
|
||||
|
||||
|
||||
return response()->json(['success' => true, 'form_id' => $form->id]);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Error saving form: ' . $e->getMessage(), ['exception' => $e]);
|
||||
return response()->json(['success' => false, 'message' => 'Error saving form'], 500);
|
||||
}
|
||||
|
||||
|
||||
|
||||
return response()->json(['success' => true, 'form_id' => $form->id]);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Error saving form: ' . $e->getMessage(), ['exception' => $e]);
|
||||
return response()->json(['success' => false, 'message' => 'Error saving form'], 500);
|
||||
}
|
||||
}
|
||||
|
||||
public function show(Form $form)
|
||||
{
|
||||
|
|
|
@ -6,21 +6,13 @@ use Illuminate\Http\Request;
|
|||
|
||||
class HomeController extends Controller
|
||||
{
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('auth');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the application dashboard.
|
||||
*
|
||||
* @return \Illuminate\Contracts\Support\Renderable
|
||||
*/
|
||||
|
||||
public function index()
|
||||
{
|
||||
return view('forms.index');
|
||||
|
|
|
@ -17,14 +17,14 @@ class QuestionController extends Controller
|
|||
|
||||
public function store(Form $form, Request $request)
|
||||
{
|
||||
// Validate question data
|
||||
|
||||
$validatedData = $request->validate([
|
||||
'type' => 'required|string|in:multiple_choice,checkbox,dropdown,short_answer,long_answer',
|
||||
'question_text' => 'required|string',
|
||||
'options' => 'nullable|array', // If needed based on question type
|
||||
'options' => 'nullable|array',
|
||||
]);
|
||||
|
||||
// Create new question for the form
|
||||
|
||||
$question = new Question();
|
||||
$question->form_id = $form->id;
|
||||
$question->type = $validatedData['type'];
|
||||
|
@ -42,14 +42,14 @@ class QuestionController extends Controller
|
|||
|
||||
public function update(Form $form, Question $question, Request $request)
|
||||
{
|
||||
// Validate updated question data
|
||||
|
||||
$validatedData = $request->validate([
|
||||
'type' => 'required|string|in:multiple_choice,checkbox,dropdown,short_answer,long_answer',
|
||||
'question_text' => 'required|string',
|
||||
'options' => 'nullable|array', // If needed based on question type
|
||||
'options' => 'nullable|array',
|
||||
]);
|
||||
|
||||
// Update question details
|
||||
|
||||
$question->type = $validatedData['type'];
|
||||
$question->question_text = $validatedData['question_text'];
|
||||
$question->options = $validatedData['options'] ?? null;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Ramsey\Uuid\Uuid;
|
||||
use App\Models\Form;
|
||||
|
@ -22,77 +23,77 @@ class ResponseController extends Controller
|
|||
}
|
||||
|
||||
public function showSuccess(Form $form)
|
||||
{
|
||||
return view('responses.success', compact('form'));
|
||||
}
|
||||
|
||||
|
||||
// Display a specific response
|
||||
public function viewResponse(Form $form, $responseId)
|
||||
{
|
||||
// Get all responses with the same response_id
|
||||
$responses = Response::where('response_id', $responseId)
|
||||
->where('form_id', $form->id)
|
||||
->get();
|
||||
|
||||
// Get all questions for the form
|
||||
$questions = Question::where('form_id', $form->id)->get()->keyBy('id');
|
||||
|
||||
// Aggregate data for statistics
|
||||
$statistics = [];
|
||||
foreach ($questions as $question) {
|
||||
$statistics[$question->id] = [
|
||||
'question_text' => $question->question_text,
|
||||
'type' => $question->type,
|
||||
'options' => json_decode($question->options),
|
||||
'responses' => []
|
||||
];
|
||||
|
||||
foreach ($responses as $response) {
|
||||
$decodedAnswers = json_decode($response->answers, true);
|
||||
if (isset($decodedAnswers[$question->id])) {
|
||||
$statistics[$question->id]['responses'][] = $decodedAnswers[$question->id];
|
||||
}
|
||||
}
|
||||
{
|
||||
return view('responses.success', compact('form'));
|
||||
}
|
||||
|
||||
return view('responses.viewResponse', compact('form', 'responses', 'questions', 'statistics'));
|
||||
}
|
||||
|
||||
|
||||
public function viewResponses(Form $form)
|
||||
{
|
||||
// Get all responses for the form, grouped by response_id
|
||||
$responses = Response::where('form_id', $form->id)
|
||||
->orderBy('submitted_at', 'desc')
|
||||
->get()
|
||||
->groupBy('response_id');
|
||||
public function viewResponse(Form $form, $responseId)
|
||||
{
|
||||
|
||||
// Get all questions for the form
|
||||
$questions = Question::where('form_id', $form->id)->get()->keyBy('id');
|
||||
$responses = Response::where('response_id', $responseId)
|
||||
->where('form_id', $form->id)
|
||||
->get();
|
||||
|
||||
// Aggregate data for statistics
|
||||
$statistics = [];
|
||||
foreach ($questions as $question) {
|
||||
$statistics[$question->id] = [
|
||||
'question_text' => $question->question_text,
|
||||
'type' => $question->type,
|
||||
'options' => json_decode($question->options, true),
|
||||
'responses' => [],
|
||||
];
|
||||
|
||||
foreach ($responses as $responseGroup) {
|
||||
foreach ($responseGroup as $response) {
|
||||
$questions = Question::where('form_id', $form->id)->get()->keyBy('id');
|
||||
|
||||
|
||||
$statistics = [];
|
||||
foreach ($questions as $question) {
|
||||
$statistics[$question->id] = [
|
||||
'question_text' => $question->question_text,
|
||||
'type' => $question->type,
|
||||
'options' => json_decode($question->options),
|
||||
'responses' => []
|
||||
];
|
||||
|
||||
foreach ($responses as $response) {
|
||||
$decodedAnswers = json_decode($response->answers, true);
|
||||
if (isset($decodedAnswers[$question->id])) {
|
||||
$statistics[$question->id]['responses'][] = $decodedAnswers[$question->id];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return view('responses.viewResponse', compact('form', 'responses', 'questions', 'statistics'));
|
||||
}
|
||||
|
||||
return view('responses.viewResponses', compact('form', 'responses', 'statistics', 'questions'));
|
||||
}
|
||||
|
||||
public function viewResponses(Form $form)
|
||||
{
|
||||
|
||||
$responses = Response::where('form_id', $form->id)
|
||||
->orderBy('submitted_at', 'desc')
|
||||
->get()
|
||||
->groupBy('response_id');
|
||||
|
||||
|
||||
$questions = Question::where('form_id', $form->id)->get()->keyBy('id');
|
||||
|
||||
|
||||
$statistics = [];
|
||||
foreach ($questions as $question) {
|
||||
$statistics[$question->id] = [
|
||||
'question_text' => $question->question_text,
|
||||
'type' => $question->type,
|
||||
'options' => json_decode($question->options, true),
|
||||
'responses' => [],
|
||||
];
|
||||
|
||||
foreach ($responses as $responseGroup) {
|
||||
foreach ($responseGroup as $response) {
|
||||
$decodedAnswers = json_decode($response->answers, true);
|
||||
if (isset($decodedAnswers[$question->id])) {
|
||||
$statistics[$question->id]['responses'][] = $decodedAnswers[$question->id];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return view('responses.viewResponses', compact('form', 'responses', 'statistics', 'questions'));
|
||||
}
|
||||
|
||||
|
||||
public function showForm(Form $form)
|
||||
|
@ -106,53 +107,48 @@ public function viewResponses(Form $form)
|
|||
}
|
||||
|
||||
public function submitForm(Request $request, Form $form)
|
||||
{
|
||||
Log::info($request->all()); // Log the entire request data for debugging
|
||||
{
|
||||
Log::info($request->all());
|
||||
|
||||
// Fetch all questions for the form
|
||||
$questions = $form->questions;
|
||||
|
||||
// Extract IDs of required questions
|
||||
$requiredQuestionIds = $questions->where('required', true)->pluck('id')->toArray();
|
||||
$questions = $form->questions;
|
||||
|
||||
// Validate and process form submission
|
||||
$validatedData = $request->validate([
|
||||
'answers' => 'required|array',
|
||||
'answers.*' => 'required', // Ensure all answers are provided
|
||||
]);
|
||||
|
||||
// Ensure all required questions are answered
|
||||
foreach ($requiredQuestionIds as $requiredQuestionId) {
|
||||
if (!array_key_exists($requiredQuestionId, $validatedData['answers'])) {
|
||||
return redirect()->back()
|
||||
->withErrors(['errors' => 'Please answer all required questions.'])
|
||||
->withInput();
|
||||
$requiredQuestionIds = $questions->where('required', true)->pluck('id')->toArray();
|
||||
|
||||
|
||||
$validatedData = $request->validate([
|
||||
'answers' => 'required|array',
|
||||
'answers.*' => 'required',
|
||||
]);
|
||||
|
||||
|
||||
foreach ($requiredQuestionIds as $requiredQuestionId) {
|
||||
if (!array_key_exists($requiredQuestionId, $validatedData['answers'])) {
|
||||
return redirect()->back()
|
||||
->withErrors(['errors' => 'Please answer all required questions.'])
|
||||
->withInput();
|
||||
}
|
||||
}
|
||||
|
||||
Log::info($validatedData);
|
||||
|
||||
|
||||
$responseId = Uuid::uuid4()->toString();
|
||||
|
||||
|
||||
foreach ($validatedData['answers'] as $questionId => $answer) {
|
||||
$response = new Response();
|
||||
$response->response_id = $responseId;
|
||||
$response->question_id = $questionId;
|
||||
$response->form_id = $form->id;
|
||||
$response->user_id = auth()->id();
|
||||
$response->answers = json_encode($answer);
|
||||
$response->submitted_at = now();
|
||||
$response->save();
|
||||
}
|
||||
|
||||
return redirect()->route('responses.showForm', $form)
|
||||
->with('success', 'Response submitted successfully.');
|
||||
}
|
||||
|
||||
Log::info($validatedData); // Log the validated data for debugging
|
||||
|
||||
// Generate a UUID for response_id
|
||||
$responseId = Uuid::uuid4()->toString();
|
||||
|
||||
// Save each question's response
|
||||
foreach ($validatedData['answers'] as $questionId => $answer) {
|
||||
$response = new Response();
|
||||
$response->response_id = $responseId; // Assign the generated UUID
|
||||
$response->question_id = $questionId;
|
||||
$response->form_id = $form->id;
|
||||
$response->user_id = auth()->id();
|
||||
$response->answers = json_encode($answer);
|
||||
$response->submitted_at = now();
|
||||
$response->save();
|
||||
}
|
||||
|
||||
return redirect()->route('responses.showForm', $form)
|
||||
->with('success', 'Response submitted successfully.');
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -21,25 +21,31 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||
}
|
||||
|
||||
function changeQuestionType(selectElement) {
|
||||
const questionContainer = selectElement.closest('.question');
|
||||
const optionsContainer = questionContainer.querySelector('.options-container');
|
||||
const addOptionButton = questionContainer.querySelector('.btn-secondary');
|
||||
const questionContainer = selectElement.closest(".question");
|
||||
const optionsContainer =
|
||||
questionContainer.querySelector(".options-container");
|
||||
const addOptionButton =
|
||||
questionContainer.querySelector(".btn-secondary");
|
||||
const questionType = selectElement.value;
|
||||
|
||||
// Clear the options container
|
||||
optionsContainer.innerHTML = '';
|
||||
optionsContainer.innerHTML = "";
|
||||
|
||||
if (questionType === 'multiple_choice' || questionType === 'checkbox' || questionType === 'dropdown') {
|
||||
const optionDiv = document.createElement('div');
|
||||
optionDiv.className = 'option d-flex align-items-center mb-2';
|
||||
if (
|
||||
questionType === "multiple_choice" ||
|
||||
questionType === "checkbox" ||
|
||||
questionType === "dropdown"
|
||||
) {
|
||||
const optionDiv = document.createElement("div");
|
||||
optionDiv.className = "option d-flex align-items-center mb-2";
|
||||
optionDiv.innerHTML = `
|
||||
<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;">✕</span>
|
||||
`;
|
||||
optionsContainer.appendChild(optionDiv);
|
||||
addOptionButton.style.display = 'inline-block'; // Show the "Add Option" button
|
||||
} else if (questionType === 'text') {
|
||||
addOptionButton.style.display = 'none'; // Hide the "Add Option" button
|
||||
addOptionButton.style.display = "inline-block"; // Show the "Add Option" button
|
||||
} else if (questionType === "text") {
|
||||
addOptionButton.style.display = "none"; // Hide the "Add Option" button
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -88,34 +94,37 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||
|
||||
function updateAddButtonPosition() {
|
||||
const questions = questionsSection.querySelectorAll(".question");
|
||||
const sidebar = document.getElementById("moveableDiv");
|
||||
const sidebar = document.getElementById("moveableDiv");
|
||||
|
||||
if (questions.length > 0) {
|
||||
const lastQuestion = questions[questions.length - 1];
|
||||
const offsetTop = lastQuestion.offsetTop;
|
||||
const sidebarHeight = sidebar.offsetHeight;
|
||||
const containerHeight = questionsSection.offsetHeight;
|
||||
if (questions.length > 0) {
|
||||
const lastQuestion = questions[questions.length - 1];
|
||||
const offsetTop = lastQuestion.offsetTop;
|
||||
const sidebarHeight = sidebar.offsetHeight;
|
||||
const containerHeight = questionsSection.offsetHeight;
|
||||
|
||||
// Calculate the position of the last question relative to the top of the container
|
||||
const newPosition = offsetTop + lastQuestion.offsetHeight;
|
||||
// Calculate the position of the last question relative to the top of the container
|
||||
const newPosition = offsetTop + lastQuestion.offsetHeight;
|
||||
|
||||
// Ensure the sidebar stays within the bounds of the container
|
||||
if (newPosition + sidebarHeight <= containerHeight) {
|
||||
sidebar.style.transform = `translateY(${newPosition}px)`;
|
||||
console.log(`Moving sidebar to: ${newPosition}px`);
|
||||
// Ensure the sidebar stays within the bounds of the container
|
||||
if (newPosition + sidebarHeight <= containerHeight) {
|
||||
sidebar.style.transform = `translateY(${newPosition}px)`;
|
||||
console.log(`Moving sidebar to: ${newPosition}px`);
|
||||
} else {
|
||||
sidebar.style.transform = `translateY(${
|
||||
containerHeight - sidebarHeight
|
||||
}px)`;
|
||||
console.log(`Moving sidebar to bottom of container`);
|
||||
}
|
||||
} else {
|
||||
sidebar.style.transform = `translateY(${containerHeight - sidebarHeight}px)`;
|
||||
console.log(`Moving sidebar to bottom of container`);
|
||||
sidebar.style.transform = `translateY(0px)`;
|
||||
console.log("No questions, moving sidebar to top");
|
||||
}
|
||||
} else {
|
||||
sidebar.style.transform = `translateY(0px)`;
|
||||
console.log("No questions, moving sidebar to top");
|
||||
}
|
||||
}
|
||||
|
||||
function saveForm() {
|
||||
const formTitle = document.getElementById("form-title").value;
|
||||
const formDescription = document.getElementById("form-description").value;
|
||||
const formDescription =
|
||||
document.getElementById("form-description").value;
|
||||
const questions = document.querySelectorAll(".question");
|
||||
let formData = [];
|
||||
|
||||
|
@ -123,26 +132,34 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||
|
||||
questions.forEach((question) => {
|
||||
const questionType = question.querySelector("select").value;
|
||||
const questionText = question.querySelector(".question-input").value;
|
||||
const isRequired = question.querySelector(".required-checkbox").checked;
|
||||
const questionText =
|
||||
question.querySelector(".question-input").value;
|
||||
const isRequired =
|
||||
question.querySelector(".required-checkbox").checked;
|
||||
let options = [];
|
||||
|
||||
if (questionType === 'multiple_choice' || questionType === 'checkbox' || questionType === 'dropdown') {
|
||||
options = Array.from(question.querySelectorAll(".option-input")).map((input) => input.value);
|
||||
if (
|
||||
questionType === "multiple_choice" ||
|
||||
questionType === "checkbox" ||
|
||||
questionType === "dropdown"
|
||||
) {
|
||||
options = Array.from(
|
||||
question.querySelectorAll(".option-input")
|
||||
).map((input) => input.value);
|
||||
}
|
||||
|
||||
formData.push({
|
||||
type: questionType,
|
||||
text: questionText,
|
||||
options: options,
|
||||
required: isRequired
|
||||
required: isRequired,
|
||||
});
|
||||
|
||||
console.log({
|
||||
type: questionType,
|
||||
text: questionText,
|
||||
options: options,
|
||||
required: isRequired
|
||||
required: isRequired,
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -158,56 +175,47 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||
const data = {
|
||||
title: formTitle,
|
||||
description: formDescription,
|
||||
questions: formData
|
||||
questions: formData,
|
||||
};
|
||||
|
||||
console.log(data);
|
||||
|
||||
|
||||
fetch("/forms", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"X-CSRF-TOKEN": csrfToken
|
||||
"X-CSRF-TOKEN": csrfToken,
|
||||
},
|
||||
body: JSON.stringify(data),
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then((result) => {
|
||||
if (result.success) {
|
||||
Swal.fire({
|
||||
title: 'Success!',
|
||||
text: 'Form saved successfully.',
|
||||
icon: 'success',
|
||||
confirmButtonText: 'OK'
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
window.location.href = "/forms";
|
||||
}
|
||||
});
|
||||
} else {
|
||||
Swal.fire({
|
||||
title: 'Error!',
|
||||
text: 'Failed to save form.',
|
||||
icon: 'error',
|
||||
confirmButtonText: 'OK'
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Error saving form:", error);
|
||||
alert("An error occurred while saving the form.");
|
||||
});
|
||||
.then((response) => response.json())
|
||||
.then((result) => {
|
||||
if (result.success) {
|
||||
Swal.fire({
|
||||
title: "Success!",
|
||||
text: "Form saved successfully.",
|
||||
icon: "success",
|
||||
confirmButtonText: "OK",
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
window.location.href = "/forms";
|
||||
}
|
||||
});
|
||||
} else {
|
||||
Swal.fire({
|
||||
title: "Error!",
|
||||
text: "Failed to save form.",
|
||||
icon: "error",
|
||||
confirmButtonText: "OK",
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Error saving form:", error);
|
||||
alert("An error occurred while saving the form.");
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
window.addNewQuestion = addNewQuestion;
|
||||
window.deleteQuestion = deleteQuestion;
|
||||
window.addOption = addOption;
|
||||
|
@ -217,7 +225,10 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||
|
||||
// document.getElementById("add-question-button").addEventListener("click", addNewQuestion);
|
||||
|
||||
document.getElementById("questions_section").addEventListener("DOMNodeInserted", updateAddButtonPosition);
|
||||
document.getElementById("questions_section").addEventListener("DOMNodeRemoved", updateAddButtonPosition);
|
||||
document
|
||||
.getElementById("questions_section")
|
||||
.addEventListener("DOMNodeInserted", updateAddButtonPosition);
|
||||
document
|
||||
.getElementById("questions_section")
|
||||
.addEventListener("DOMNodeRemoved", updateAddButtonPosition);
|
||||
});
|
||||
|
||||
|
|
|
@ -1,129 +0,0 @@
|
|||
// statistics.js
|
||||
|
||||
// Function to fetch responses from backend
|
||||
function fetchResponses() {
|
||||
return fetch('/api/responses') // Replace with your actual API endpoint
|
||||
.then(response => response.json())
|
||||
.catch(error => console.error('Error fetching responses:', error));
|
||||
}
|
||||
|
||||
// Function to process fetched responses data
|
||||
function processDataForCharts(responses, questions) {
|
||||
const pieData = {};
|
||||
const barData = {};
|
||||
|
||||
responses.forEach(response => {
|
||||
const question = questions[response.question_id];
|
||||
const decodedAnswers = JSON.parse(response.answers);
|
||||
|
||||
// Process data for pie chart
|
||||
if (!pieData[question.question_text]) {
|
||||
pieData[question.question_text] = {};
|
||||
}
|
||||
if (question.type === 'multiple_choice' || question.type === 'checkbox') {
|
||||
JSON.parse(question.options).forEach(option => {
|
||||
pieData[question.question_text][option] = (pieData[question.question_text][option] || 0) +
|
||||
(decodedAnswers.includes(option) ? 1 : 0);
|
||||
});
|
||||
}
|
||||
|
||||
// Process data for bar graph (assuming numerical responses)
|
||||
if (question.type === 'short_answer' || question.type === 'long_answer') {
|
||||
if (!barData[question.question_text]) {
|
||||
barData[question.question_text] = { total: 0, count: 0 };
|
||||
}
|
||||
barData[question.question_text].total += parseFloat(response.answers);
|
||||
barData[question.question_text].count++;
|
||||
}
|
||||
});
|
||||
|
||||
// Calculate averages for bar graph
|
||||
Object.keys(barData).forEach(key => {
|
||||
barData[key].average = barData[key].total / barData[key].count;
|
||||
});
|
||||
|
||||
return { pieData, barData };
|
||||
}
|
||||
|
||||
// Function to render charts using Chart.js
|
||||
function renderCharts(pieData, barData) {
|
||||
// Render Pie Chart
|
||||
const pieChartCanvas = document.getElementById('pieChart');
|
||||
new Chart(pieChartCanvas.getContext('2d'), {
|
||||
type: 'pie',
|
||||
data: {
|
||||
labels: Object.keys(pieData),
|
||||
datasets: Object.keys(pieData).map(question => ({
|
||||
label: question,
|
||||
data: Object.values(pieData[question]),
|
||||
backgroundColor: getRandomColors(Object.values(pieData[question]).length),
|
||||
})),
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
plugins: {
|
||||
legend: {
|
||||
position: 'top',
|
||||
},
|
||||
tooltip: {
|
||||
callbacks: {
|
||||
label: function(context) {
|
||||
let label = context.label || '';
|
||||
if (context.parsed.y !== null) {
|
||||
label += ': ' + context.parsed.y;
|
||||
}
|
||||
return label;
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// Render Bar Graph
|
||||
const barGraphCanvas = document.getElementById('barGraph');
|
||||
new Chart(barGraphCanvas.getContext('2d'), {
|
||||
type: 'bar',
|
||||
data: {
|
||||
labels: Object.keys(barData),
|
||||
datasets: [{
|
||||
label: 'Average Response',
|
||||
data: Object.values(barData).map(item => item.average.toFixed(2)),
|
||||
backgroundColor: getRandomColors(Object.keys(barData).length),
|
||||
}],
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
scales: {
|
||||
y: {
|
||||
beginAtZero: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// Function to generate random colors
|
||||
function getRandomColors(count) {
|
||||
const colors = [];
|
||||
for (let i = 0; i < count; i++) {
|
||||
colors.push(`rgba(${Math.floor(Math.random() * 256)}, ${Math.floor(Math.random() * 256)}, ${Math.floor(Math.random() * 256)}, 0.2)`);
|
||||
}
|
||||
return colors;
|
||||
}
|
||||
|
||||
// Main function to fetch data and render charts
|
||||
async function main() {
|
||||
try {
|
||||
const responses = await fetchResponses();
|
||||
const questions = {!! json_encode($questions) !!}; // This assumes $questions is passed to the Blade view from Laravel
|
||||
|
||||
const { pieData, barData } = processDataForCharts(responses, questions);
|
||||
renderCharts(pieData, barData);
|
||||
} catch (error) {
|
||||
console.error('Error processing or rendering charts:', error);
|
||||
}
|
||||
}
|
||||
|
||||
// Run main function on page load
|
||||
window.addEventListener('DOMContentLoaded', main);
|
|
@ -47,14 +47,14 @@
|
|||
<div style="background-color: #f4f4f9; max-width: 100%" class="question_form p-4 rounded">
|
||||
<div class="section">
|
||||
<div class="question_title_section mb-4">
|
||||
<div class="question_form_top">
|
||||
<div style="border-bottom:5px; border-radius:5px;" class="question_form_top shadow-sm">
|
||||
<input type="text" id="form-title" name="title" value="{{ $data['title'] ?? '' }}" class="form-control form-control-lg p-2 mb-2" placeholder="Untitled Form" />
|
||||
<input type="text" name="description" id="form-description" value="{{ $data['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-4 border rounded bg-white">
|
||||
<div class="question mb-4 p-4 border rounded bg-white shadow-sm">
|
||||
<select class="form-control question_type mb-1" onchange="changeQuestionType(this)">
|
||||
<option value="">Select Question Type</option>
|
||||
<option value="multiple_choice">Multiple Choice</option>
|
||||
|
|
|
@ -6,181 +6,263 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="csrf-token" content="{{ csrf_token() }}">
|
||||
<title>Edit Form - {{ $form->title }}</title>
|
||||
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="https:
|
||||
<link rel="stylesheet" href="{{ asset('css/app.css') }}">
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/sweetalert2@11/dist/sweetalert2.min.css">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,300..800;1,300..800&display=swap"
|
||||
rel="stylesheet">
|
||||
<style>
|
||||
.shadow-custom {
|
||||
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<link rel="preconnect" href="https:
|
||||
<link href="https: <link rel="preconnect" href="https:
|
||||
<script src="https:
|
||||
<link rel=" stylesheet" href="https:
|
||||
<link href=" https: rel="stylesheet">
|
||||
< style >
|
||||
.shadow - custom {
|
||||
box - shadow: 0 10 px 15 px - 3 px rgba(0, 0, 0, 0.1), 0 4 px 6 px - 2 px rgba(0, 0, 0, 0.05);
|
||||
} <
|
||||
/style> < /
|
||||
head >
|
||||
|
||||
<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('/') }}"
|
||||
style="color: rgb(103,58,183)" class="text-3xl font-bold font-sans">LaraForms</a> - Edit</span>
|
||||
<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>
|
||||
<
|
||||
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('/') }}"
|
||||
style = "color: rgb(103,58,183)"
|
||||
class = "text-3xl font-bold font-sans" > LaraForms < /a> - Edit</span >
|
||||
<
|
||||
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="max-width: 700px" class="container">
|
||||
<form id="edit-form" method="POST" action="{{ route('forms.update', $form) }}"
|
||||
class="bg-white p-4 rounded shadow-sm">
|
||||
@csrf
|
||||
@method('PUT')
|
||||
<div class="form-group">
|
||||
<input type="text" id="form-title" name="title" class="form-control form-control-lg text-black"
|
||||
placeholder="Untitled Form" value="{{ $form->title }}" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input type="text" name="description" id="form-description"
|
||||
class="form-control form-control-sm text-black" placeholder="Form Description"
|
||||
value="{{ $form->description }}" />
|
||||
</div>
|
||||
<div id="questions-section">
|
||||
@foreach ($questions as $index => $question)
|
||||
<div class="question mb-4 p-3 border rounded bg-light" data-index="{{ $index }}">
|
||||
<div class="form-group">
|
||||
<select class="form-control question-type" id="question-type-{{ $index }}" name="questions[{{ $index }}][type]">
|
||||
<option value="multiple_choice" {{ $question->type === 'multiple_choice' ? 'selected' : '' }}>Multiple Choice</option>
|
||||
<option value="checkbox" {{ $question->type === 'checkbox' ? 'selected' : '' }}>Checkbox</option>
|
||||
<option value="dropdown" {{ $question->type === 'dropdown' ? 'selected' : '' }}>Dropdown</option>
|
||||
<option value="text" {{ $question->type === 'text' ? 'selected' : '' }}>Text</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input type="text" id="question-text-{{ $index }}"
|
||||
name="questions[{{ $index }}][text]" class="form-control question-input"
|
||||
value="{{ $question->question_text }}" required>
|
||||
</div>
|
||||
<div class="form-group form-check">
|
||||
<input type="checkbox" id="question-required-{{ $index }}"
|
||||
name="questions[{{ $index }}][required]" class="form-check-input"
|
||||
{{ $question->required ? 'checked' : '' }}>
|
||||
<label for="question-required-{{ $index }}" class="form-check-label">Required</label>
|
||||
</div>
|
||||
<div class="form-group options-container" style="{{ $question->type === 'text' ? 'display:none;' : '' }}">
|
||||
<label>Options</label>
|
||||
@if (is_array($question->options))
|
||||
@foreach ($question->options as $optionIndex => $option)
|
||||
<div class="option d-flex align-items-center mb-2">
|
||||
<input type="text" name="questions[{{ $index }}][options][{{ $optionIndex }}]" class="form-control option-input" value="{{ $option }}">
|
||||
<span class="delete-option ml-2 text-danger" onclick="deleteOption(this)" style="cursor: pointer;">✕</span>
|
||||
</div>
|
||||
@endforeach
|
||||
@endif
|
||||
<button type="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>
|
||||
@endforeach
|
||||
<div class="sidebar">
|
||||
<div id="moveableDiv">
|
||||
<button class="btn btn-light shadow-sm" type="button" onclick="addNewQuestion();">
|
||||
<img src="{{ asset('images/add.png') }}" alt="ADD" width="20px" height="20px" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-success mb-4">Save</button>
|
||||
</form>
|
||||
</div>
|
||||
<
|
||||
div style = "max-width: 700px"
|
||||
class = "container" >
|
||||
<
|
||||
form id = "edit-form"
|
||||
method = "POST"
|
||||
action = "{{ route('forms.update', $form) }}"
|
||||
class = "bg-white p-4 rounded shadow-sm" >
|
||||
@csrf
|
||||
@method('PUT')
|
||||
<
|
||||
div class = "form-group" >
|
||||
<
|
||||
input type = "text"
|
||||
id = "form-title"
|
||||
name = "title"
|
||||
class = "form-control form-control-lg text-black"
|
||||
placeholder = "Untitled Form"
|
||||
value = "{{ $form->title }}" / >
|
||||
<
|
||||
/div> <
|
||||
div class = "form-group" >
|
||||
<
|
||||
input type = "text"
|
||||
name = "description"
|
||||
id = "form-description"
|
||||
class = "form-control form-control-sm text-black"
|
||||
placeholder = "Form Description"
|
||||
value = "{{ $form->description }}" / >
|
||||
<
|
||||
/div> <
|
||||
div id = "questions-section" >
|
||||
@foreach ($questions as $index => $question)
|
||||
<
|
||||
div class = "question mb-4 p-3 border rounded bg-light"
|
||||
data - index = "{{ $index }}" >
|
||||
<
|
||||
div class = "form-group" >
|
||||
<
|
||||
select class = "form-control question-type"
|
||||
id = "question-type-{{ $index }}"
|
||||
name = "questions[{{ $index }}][type]" >
|
||||
<
|
||||
option value = "multiple_choice"
|
||||
{{ $question->type === 'multiple_choice' ? 'selected' : '' }} > Multiple Choice < /option> <
|
||||
option value = "checkbox"
|
||||
{{ $question->type === 'checkbox' ? 'selected' : '' }} > Checkbox < /option> <
|
||||
option value = "dropdown"
|
||||
{{ $question->type === 'dropdown' ? 'selected' : '' }} > Dropdown < /option> <
|
||||
option value = "text"
|
||||
{{ $question->type === 'text' ? 'selected' : '' }} > Text < /option> < /
|
||||
select > <
|
||||
/div> <
|
||||
div class = "form-group" >
|
||||
<
|
||||
input type = "text"
|
||||
id = "question-text-{{ $index }}"
|
||||
name = "questions[{{ $index }}][text]"
|
||||
class = "form-control question-input"
|
||||
value = "{{ $question->question_text }}"
|
||||
required >
|
||||
<
|
||||
/div> <
|
||||
div class = "form-group form-check" >
|
||||
<
|
||||
input type = "checkbox"
|
||||
id = "question-required-{{ $index }}"
|
||||
name = "questions[{{ $index }}][required]"
|
||||
class = "form-check-input"
|
||||
{{ $question->required ? 'checked' : '' }} >
|
||||
<
|
||||
label
|
||||
for = "question-required-{{ $index }}"
|
||||
class = "form-check-label" > Required < /label> < /
|
||||
div > <
|
||||
div class = "form-group options-container"
|
||||
style = "{{ $question->type === 'text' ? 'display:none;' : '' }}" >
|
||||
<
|
||||
label > Options < /label>
|
||||
@if (is_array($question->options))
|
||||
@foreach ($question->options as $optionIndex => $option)
|
||||
<
|
||||
div class = "option d-flex align-items-center mb-2" >
|
||||
<
|
||||
input type = "text"
|
||||
name = "questions[{{ $index }}][options][{{ $optionIndex }}]"
|
||||
class = "form-control option-input"
|
||||
value = "{{ $option }}" >
|
||||
<
|
||||
span class = "delete-option ml-2 text-danger"
|
||||
onclick = "deleteOption(this)"
|
||||
style = "cursor: pointer;" > & #10005;</span>
|
||||
</div>
|
||||
@endforeach
|
||||
@endif
|
||||
<button type= "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>
|
||||
@endforeach <
|
||||
div class = "sidebar" >
|
||||
<
|
||||
div id = "moveableDiv" >
|
||||
<
|
||||
button class = "btn btn-light shadow-sm"
|
||||
type = "button"
|
||||
onclick = "addNewQuestion();" >
|
||||
<
|
||||
img src = "{{ asset('images/add.png') }}"
|
||||
alt = "ADD"
|
||||
width = "20px"
|
||||
height = "20px" / >
|
||||
<
|
||||
/button> < /
|
||||
div > <
|
||||
/div> < /
|
||||
div > <
|
||||
button type = "submit"
|
||||
class = "btn btn-success mb-4" > Save < /button> < /
|
||||
form > <
|
||||
/div>
|
||||
|
||||
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
|
||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
|
||||
<script>
|
||||
<
|
||||
script src = "https: <
|
||||
script src = "https: <
|
||||
script >
|
||||
|
||||
|
||||
$(document).ready(function () {
|
||||
$('#edit-form').on('submit', function (e) {
|
||||
e.preventDefault(); // Prevent the default form submission
|
||||
$(document).ready(function() {
|
||||
$('#edit-form').on('submit', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
// Get the form action and data
|
||||
var form = $(this);
|
||||
var url = form.attr('action');
|
||||
var formData = form.serialize();
|
||||
|
||||
// Send an AJAX request to submit the form data
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: url,
|
||||
data: formData,
|
||||
success: function (response) {
|
||||
// Show SweetAlert on success
|
||||
Swal.fire({
|
||||
title: 'Success!',
|
||||
text: 'Form edited successfully.',
|
||||
icon: 'success',
|
||||
confirmButtonText: 'OK'
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
// Redirect to the show page
|
||||
window.location.href = "{{ route('forms.show', $form) }}";
|
||||
}
|
||||
});
|
||||
},
|
||||
error: function (xhr, status, error) {
|
||||
// Handle any errors
|
||||
Swal.fire({
|
||||
title: 'Error!',
|
||||
text: 'An error occurred while editing the form. Please try again.',
|
||||
icon: 'error',
|
||||
confirmButtonText: 'OK'
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
var form = $(this);
|
||||
var url = form.attr('action');
|
||||
var formData = form.serialize();
|
||||
|
||||
function addOption(button) {
|
||||
const optionsContainer = $(button).closest('.options-container');
|
||||
const optionIndex = optionsContainer.find('.option').length;
|
||||
const questionIndex = optionsContainer.closest('.question').data('index');
|
||||
|
||||
const optionHtml = `
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: url,
|
||||
data: formData,
|
||||
success: function(response) {
|
||||
|
||||
Swal.fire({
|
||||
title: 'Success!',
|
||||
text: 'Form edited successfully.',
|
||||
icon: 'success',
|
||||
confirmButtonText: 'OK'
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
|
||||
window.location.href =
|
||||
"{{ route('forms.show', $form) }}";
|
||||
}
|
||||
});
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
|
||||
Swal.fire({
|
||||
title: 'Error!',
|
||||
text: 'An error occurred while editing the form. Please try again.',
|
||||
icon: 'error',
|
||||
confirmButtonText: 'OK'
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function addOption(button) {
|
||||
const optionsContainer = $(button).closest('.options-container');
|
||||
const optionIndex = optionsContainer.find('.option').length;
|
||||
const questionIndex = optionsContainer.closest('.question').data('index');
|
||||
|
||||
const optionHtml = `
|
||||
<div class="option d-flex align-items-center mb-2">
|
||||
<input type="text" name="questions[${questionIndex}][options][${optionIndex}]" class="form-control option-input" placeholder="Option">
|
||||
<span class="delete-option ml-2 text-danger" onclick="deleteOption(this)" style="cursor: pointer;">✕</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
optionsContainer.append(optionHtml);
|
||||
updateAddButtonPosition();
|
||||
}
|
||||
optionsContainer.append(optionHtml);
|
||||
updateAddButtonPosition();
|
||||
}
|
||||
|
||||
function deleteOption(button) {
|
||||
$(button).closest('.option').remove();
|
||||
updateAddButtonPosition();
|
||||
}
|
||||
function deleteOption(button) {
|
||||
$(button).closest('.option').remove();
|
||||
updateAddButtonPosition();
|
||||
}
|
||||
|
||||
function addNewQuestion() {
|
||||
const questionsSection = $('#questions-section');
|
||||
const questionIndex = questionsSection.find('.question').length;
|
||||
function addNewQuestion() {
|
||||
const questionsSection = $('#questions-section');
|
||||
const questionIndex = questionsSection.find('.question').length;
|
||||
|
||||
const questionHtml = `
|
||||
const questionHtml = `
|
||||
<div class="question mb-4 p-3 border rounded bg-light" data-index="${questionIndex}">
|
||||
<div class="form-group">
|
||||
<select class="form-control question-type" id="question-type-${questionIndex}" name="questions[${questionIndex}][type]" onchange="handleQuestionTypeChange(this)">
|
||||
|
@ -209,91 +291,85 @@ $(document).ready(function () {
|
|||
</div>
|
||||
`;
|
||||
|
||||
questionsSection.append(questionHtml);
|
||||
updateAddButtonPosition();
|
||||
}
|
||||
questionsSection.append(questionHtml);
|
||||
updateAddButtonPosition();
|
||||
}
|
||||
|
||||
function deleteQuestion(button) {
|
||||
$(button).closest('.question').remove();
|
||||
updateQuestionIndices();
|
||||
updateAddButtonPosition();
|
||||
}
|
||||
function deleteQuestion(button) {
|
||||
$(button).closest('.question').remove();
|
||||
updateQuestionIndices();
|
||||
updateAddButtonPosition();
|
||||
}
|
||||
|
||||
function updateQuestionIndices() {
|
||||
$('#questions-section .question').each((index, element) => {
|
||||
$(element).attr('data-index', index);
|
||||
$(element).find('.question-type').attr('name', `questions[${index}][type]`);
|
||||
$(element).find('.question-input').attr('name', `questions[${index}][text]`);
|
||||
$(element).find('.question-input').attr('id', `question-text-${index}`);
|
||||
$(element).find('.form-check-input').attr('name', `questions[${index}][required]`);
|
||||
$(element).find('.form-check-input').attr('id', `question-required-${index}`);
|
||||
$(element).find('.options-container').find('.option-input').each((optionIndex, optionElement) => {
|
||||
$(optionElement).attr('name', `questions[${index}][options][${optionIndex}]`);
|
||||
});
|
||||
});
|
||||
}
|
||||
function updateQuestionIndices() {
|
||||
$('#questions-section .question').each((index, element) => {
|
||||
$(element).attr('data-index', index);
|
||||
$(element).find('.question-type').attr('name', `questions[${index}][type]`);
|
||||
$(element).find('.question-input').attr('name', `questions[${index}][text]`);
|
||||
$(element).find('.question-input').attr('id', `question-text-${index}`);
|
||||
$(element).find('.form-check-input').attr('name', `questions[${index}][required]`);
|
||||
$(element).find('.form-check-input').attr('id', `question-required-${index}`);
|
||||
$(element).find('.options-container').find('.option-input').each((optionIndex,
|
||||
optionElement) => {
|
||||
$(optionElement).attr('name',
|
||||
`questions[${index}][options][${optionIndex}]`);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function handleQuestionTypeChange(selectElement) {
|
||||
const selectedType = $(selectElement).val();
|
||||
const optionsContainer = $(selectElement).closest('.question').find('.options-container');
|
||||
function handleQuestionTypeChange(selectElement) {
|
||||
const selectedType = $(selectElement).val();
|
||||
const optionsContainer = $(selectElement).closest('.question').find('.options-container');
|
||||
|
||||
if (selectedType === 'text') {
|
||||
optionsContainer.hide();
|
||||
} else {
|
||||
optionsContainer.show();
|
||||
}
|
||||
}
|
||||
if (selectedType === 'text') {
|
||||
optionsContainer.hide();
|
||||
} else {
|
||||
optionsContainer.show();
|
||||
}
|
||||
}
|
||||
|
||||
function updateAddButtonPosition() {
|
||||
const questions = document.querySelectorAll("#questions-section .question");
|
||||
const sidebar = document.getElementById("moveableDiv");
|
||||
function updateAddButtonPosition() {
|
||||
const questions = document.querySelectorAll("#questions-section .question");
|
||||
const sidebar = document.getElementById("moveableDiv");
|
||||
|
||||
if (questions.length > 0) {
|
||||
const lastQuestion = questions[questions.length - 1];
|
||||
const offsetTop = lastQuestion.offsetTop;
|
||||
const sidebarHeight = sidebar.offsetHeight;
|
||||
const containerHeight = document.getElementById("questions-section").offsetHeight;
|
||||
if (questions.length > 0) {
|
||||
const lastQuestion = questions[questions.length - 1];
|
||||
const offsetTop = lastQuestion.offsetTop;
|
||||
const sidebarHeight = sidebar.offsetHeight;
|
||||
const containerHeight = document.getElementById("questions-section").offsetHeight;
|
||||
|
||||
const newPosition = offsetTop + lastQuestion.offsetHeight;
|
||||
if (newPosition + sidebarHeight <= containerHeight) {
|
||||
sidebar.style.transform = `translateY(${newPosition + 75}px)`;
|
||||
console.log(`Moving sidebar to: ${newPosition + 75}px`);
|
||||
} else {
|
||||
sidebar.style.transform = `translateY(${containerHeight - sidebarHeight + 75}px)`;
|
||||
console.log(`Moving sidebar to bottom of container`);
|
||||
}
|
||||
} else {
|
||||
sidebar.style.transform = `translateY(0px)`;
|
||||
console.log("No questions, moving sidebar to top");
|
||||
}
|
||||
}
|
||||
const newPosition = offsetTop + lastQuestion.offsetHeight;
|
||||
if (newPosition + sidebarHeight <= containerHeight) {
|
||||
sidebar.style.transform = `translateY(${newPosition + 75}px)`;
|
||||
console.log(`Moving sidebar to: ${newPosition + 75}px`);
|
||||
} else {
|
||||
sidebar.style.transform = `translateY(${containerHeight - sidebarHeight + 75}px)`;
|
||||
console.log(`Moving sidebar to bottom of container`);
|
||||
}
|
||||
} else {
|
||||
sidebar.style.transform = `translateY(0px)`;
|
||||
console.log("No questions, moving sidebar to top");
|
||||
}
|
||||
}
|
||||
|
||||
$(document).ready(function () {
|
||||
$('#profileMenuButton').click(function () {
|
||||
$('#profileMenu').toggleClass('hidden');
|
||||
});
|
||||
$(document).ready(function() {
|
||||
$('#profileMenuButton').click(function() {
|
||||
$('#profileMenu').toggleClass('hidden');
|
||||
});
|
||||
|
||||
$(document).click(function (event) {
|
||||
if (!$(event.target).closest('#profileMenuButton, #profileMenu').length) {
|
||||
$('#profileMenu').addClass('hidden');
|
||||
}
|
||||
});
|
||||
$(document).click(function(event) {
|
||||
if (!$(event.target).closest('#profileMenuButton, #profileMenu').length) {
|
||||
$('#profileMenu').addClass('hidden');
|
||||
}
|
||||
});
|
||||
|
||||
$('.question-type').each((index, element) => {
|
||||
handleQuestionTypeChange(element);
|
||||
});
|
||||
$('.question-type').each((index, element) => {
|
||||
handleQuestionTypeChange(element);
|
||||
});
|
||||
|
||||
updateAddButtonPosition();
|
||||
});
|
||||
updateAddButtonPosition();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,176 +1,4 @@
|
|||
{{-- <!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-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;
|
||||
}
|
||||
|
||||
.shadow-custom {
|
||||
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<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)"
|
||||
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>
|
||||
@if (session('success'))
|
||||
<div class="bg-green-100 border border-green-400 text-green-700 px-4 py-2 rounded relative mt-4" role="alert">
|
||||
<span class="block sm:inline">{{ session('success') }}</span>
|
||||
</div>
|
||||
@endif
|
||||
@if (session('delete'))
|
||||
<div class="bg-red-100 border border-red-400 text-red-700 px-4 py-2 rounded relative mt-4" role="alert">
|
||||
<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 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>
|
||||
<br>
|
||||
<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
|
||||
<table class="min-w-full bg-white rounded-md overflow-hidden">
|
||||
<thead class="bg-gray-100">
|
||||
<tr>
|
||||
<th
|
||||
class="py-4 px-6 border-b border-gray-200 text-left text-sm font-semibold text-gray-600">
|
||||
Form Title</th>
|
||||
<th
|
||||
class="py-4 px-6 border-b border-gray-200 text-left text-sm font-semibold text-gray-600">
|
||||
Created At</th>
|
||||
<th
|
||||
class="py-4 px-6 border-b border-gray-200 text-left text-sm font-semibold text-gray-600">
|
||||
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 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>
|
||||
<tbody>
|
||||
@foreach ($forms as $form)
|
||||
<tr class="hover:bg-gray-50 transition duration-150">
|
||||
<td class="py-4 px-6 border-b border-gray-200">
|
||||
<a href="{{ route('forms.show', $form) }}"
|
||||
class="text-blue-600 font-semibold hover:underline">{{ $form->title }}</a>
|
||||
<p class="text-gray-600">{{ $form->description }}</p>
|
||||
</td>
|
||||
<td class="py-4 px-6 border-b border-gray-200">{{ $form->created_at->format('M d, Y') }}
|
||||
</td>
|
||||
<td class="py-4 px-6 border-b border-gray-200">
|
||||
<a href="{{ route('responses.viewResponses', $form) }}"
|
||||
class="text-blue-500 hover:underline">View Responses</a>
|
||||
</td>
|
||||
<td class="py-4 px-6 border-b border-gray-200">
|
||||
@if ($form->is_published)
|
||||
Published
|
||||
@else
|
||||
Unpublished
|
||||
@endif
|
||||
</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>
|
||||
@else
|
||||
<a href="#" class="text-gray-500" id="formd" onclick="handle()">Edit</a>
|
||||
@endif
|
||||
|
||||
</td>
|
||||
<td>
|
||||
<form action="{{ route('forms.destroy', $form) }}" method="POST"
|
||||
class="inline-block">
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
<button type="submit" class="text-red-500 hover:underline">Delete</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function handle() {
|
||||
Swal.fire({
|
||||
title: 'You cannot edit a published form',
|
||||
icon: 'info',
|
||||
confirmButtonText: 'OK'
|
||||
});
|
||||
}
|
||||
setTimeout(function() {
|
||||
var successMessage = document.getElementById('successMessage');
|
||||
if (successMessage) {
|
||||
successMessage.remove();
|
||||
}
|
||||
}, 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>
|
||||
|
||||
|
||||
--}}
|
||||
|
||||
|
||||
|
||||
|
||||
<!DOCTYPE html>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
|
@ -230,21 +58,24 @@
|
|||
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 href="{{ route('forms.template', 'contact') }}" style="color: rgb(103,58,183)"
|
||||
class="block max-w-md p-5 bg-white border border-gray-200 rounded-lg shadow hover:bg-gray-50 transition duration-200">
|
||||
<h5 class="mb-2 text-gray-800 text-2xl font-bold tracking-tight text-gray-900 dark:text-white">Contact Information</h5>
|
||||
<p class="font-normal text-gray-700 dark:text-gray-400">Use this template to create a contact information form.</p>
|
||||
</a>
|
||||
<a href="{{ route('forms.template', 'rsvp') }}" class="block max-w-md p-5 bg-white border border-gray-200 rounded-lg shadow hover:bg-gray-50 transition duration-200">
|
||||
<h5 class="mb-2 text-gray-800 text-2xl font-bold tracking-tight text-gray-900 dark:text-white">RSVP</h5>
|
||||
<p class="font-normal text-gray-700 dark:text-gray-400">Use this template to create an RSVP form for events.</p>
|
||||
</a>
|
||||
<a href="{{ route('forms.template', 'party') }}" class="block max-w-md p-5 bg-white border border-gray-200 rounded-lg shadow hover:bg-gray-50 transition duration-200">
|
||||
<h5 class="mb-2 text-gray-800 text-2xl font-bold tracking-tight text-gray-900 dark:text-white">Party Invite</h5>
|
||||
<p class="font-normal text-gray-700 dark:text-gray-400">Use this template to create a party invite form.</p>
|
||||
</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>
|
||||
<hr style="height:30px">
|
||||
<hr>
|
||||
<br>
|
||||
<h2 class="text-3xl font-semibold text-gray-800 font-sans">Recent Forms</h2>
|
||||
<br>
|
||||
<div class="shadow-custom rounded-lg p-6 bg-gray-100">
|
||||
|
|
|
@ -1,42 +1,3 @@
|
|||
{{-- <!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<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=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900&display=swap" rel="stylesheet">
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<title>Responses</title>
|
||||
<link rel="stylesheet" href="{{ asset('css/index.css') }}">
|
||||
</head>
|
||||
<body>
|
||||
<div class="form_header roboto-light">
|
||||
<div class="form_header_left">
|
||||
<a href="/forms"><img src="{{ asset('images/google-form.png') }}" class="form_header_icon" height="45px" width="40px" /></a>
|
||||
<h1 class="form_name">{{ $form->title }} - Responses</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="responses_list">
|
||||
@if ($responses->isEmpty())
|
||||
<p>No responses available.</p>
|
||||
@else
|
||||
<ul>
|
||||
@foreach ($responses as $response)
|
||||
<li>
|
||||
<a href="{{ route('forms.responses.show', [$form, $response]) }}">Response from {{ $response->user->name ?? 'Anonymous' }} - {{ $response->submitted_at }}</a>
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
<script src="{{ asset('js/script.js') }}"></script>
|
||||
</body>
|
||||
</html> --}}
|
||||
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
|
|
|
@ -1,108 +1,3 @@
|
|||
{{-- @extends('layouts.app')
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/sweetalert2@11/dist/sweetalert2.min.css">
|
||||
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
|
||||
|
||||
@section('content')
|
||||
<div class="container mx-auto py-8 px-4 md:px-0">
|
||||
<div class="bg-white shadow-md rounded-lg p-6">
|
||||
<h1 class="text-3xl font-semibold text-gray-900">{{ $form->title }}</h1>
|
||||
<p class="text-gray-600 mt-2">{{ $form->description }}</p>
|
||||
|
||||
<form id="responseForm" action="{{ route('responses.submitForm', $form) }}" method="POST" class="mt-8">
|
||||
@csrf
|
||||
@foreach ($questions as $question)
|
||||
<div class="mt-6">
|
||||
<label class="block font-medium text-base text-gray-800 mb-2">{{ $question->question_text }}</label>
|
||||
@if ($question->type == 'multiple_choice')
|
||||
@foreach (json_decode($question->options) as $option)
|
||||
<label class="flex items-center mt-2">
|
||||
<input class="form-radio text-base text-purple-600 h-4 w-4" type="radio" name="answers[{{ $question->id }}]" value="{{ $option }}">
|
||||
<span class="ml-2 text-gray-700">{{ $option }}</span>
|
||||
</label>
|
||||
@endforeach
|
||||
@elseif($question->type == 'checkbox')
|
||||
@foreach (json_decode($question->options) as $option)
|
||||
<label class="flex items-center mt-2">
|
||||
<input class="form-checkbox text-purple-600 h-4 w-4" type="checkbox" name="answers[{{ $question->id }}][]" value="{{ $option }}">
|
||||
<span class="ml-2 text-gray-700">{{ $option }}</span>
|
||||
</label>
|
||||
@endforeach
|
||||
@elseif($question->type == 'dropdown')
|
||||
<select class="form-select mt-2 block w-full p-2 border border-gray-300 rounded-md bg-white shadow-sm focus:outline-none focus:ring-purple-500 focus:border-purple-500 sm:text-sm" name="answers[{{ $question->id }}]">
|
||||
@foreach (json_decode($question->options) as $option)
|
||||
<option value="{{ $option }}">{{ $option }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
@elseif($question->type == 'text')
|
||||
<textarea name="answers[{{ $question->id }}]" class="form-textarea mt-2 block w-full p-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-purple-500 focus:border-purple-500 sm:text-sm"></textarea>
|
||||
@endif
|
||||
</div>
|
||||
@endforeach
|
||||
|
||||
<button type="submit" class="mt-8 w-full md:w-auto inline-flex justify-center items-center px-6 py-3 bg-purple-700 border border-transparent rounded-md font-semibold text-white text-lg uppercase tracking-widest hover:bg-purple-800 focus:outline-none focus:ring-2 focus:ring-purple-500 focus:ring-offset-2">
|
||||
Submit
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.getElementById('responseForm').addEventListener('submit', function(event) {
|
||||
event.preventDefault();
|
||||
|
||||
const form = event.target;
|
||||
const formData = new FormData(form);
|
||||
|
||||
fetch(form.action, {
|
||||
method: form.method,
|
||||
headers: {
|
||||
'X-CSRF-TOKEN': '{{ csrf_token() }}'
|
||||
},
|
||||
body: formData
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
Swal.fire({
|
||||
title: 'Success!',
|
||||
text: 'Form submitted successfully.',
|
||||
icon: 'success',
|
||||
confirmButtonText: 'OK'
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
window.location.href = '/forms';
|
||||
}
|
||||
});
|
||||
} else {
|
||||
Swal.fire({
|
||||
title: 'Error!',
|
||||
text: 'Failed to submit form.',
|
||||
icon: 'error',
|
||||
confirmButtonText: 'OK'
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error:', error);
|
||||
Swal.fire({
|
||||
title: 'Success!',
|
||||
text: 'Form Submitted Successfully',
|
||||
icon: 'success',
|
||||
confirmButtonText: 'OK'
|
||||
}).then()=>{
|
||||
window.location.href
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@endsection --}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@extends('layouts.app')
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/sweetalert2@11/dist/sweetalert2.min.css">
|
||||
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
<a href="/forms" class="d-flex align-items-center">
|
||||
<img src="{{ asset('images/google-form.png') }}" alt="Google Form Icon" height="40px" width="40px" />
|
||||
</a>
|
||||
<h2 style="color: rgb(103,58,183)" class="ml-3">{{ $form->title }} - Response Detail</h2>
|
||||
<h4 style="color: rgb(103,58,183)" class="ml-3">{{ $form->title }} - Response Detail</h4>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
|
|
Loading…
Reference in New Issue