Compare commits
10 Commits
d203dcaaba
...
d391440e2a
Author | SHA1 | Date |
---|---|---|
yash | d391440e2a | |
yash | 9f113236c5 | |
yash | 128fac86ac | |
yash | 0d8c522732 | |
Yash | e747614bd3 | |
yash | 2f7529ce2e | |
Yash | eedc2668da | |
Yash | 22bf15864e | |
yash | 7ad8d86e7f | |
yash | 00f5ec6cf9 |
|
@ -1,6 +1,7 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Models\Form;
|
||||
use App\Models\User;
|
||||
|
@ -9,13 +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
|
||||
$forms = Form::where('user_id', Auth::id())->get();
|
||||
return view('forms.index', compact('forms'));
|
||||
$totalForms = Form::count();
|
||||
$publishedForms = Form::where('is_published', true)->count();
|
||||
$totalResponses = Response::count();
|
||||
|
||||
$forms = Form::where('user_id', Auth::id())->orderBy('created_at', 'desc')->get();
|
||||
return view('forms.index', [
|
||||
'forms' => $forms,
|
||||
'totalForms' => $totalForms,
|
||||
'publishedForms' => $publishedForms,
|
||||
'totalResponses' => $totalResponses,
|
||||
]);
|
||||
}
|
||||
|
||||
public function create()
|
||||
|
@ -23,35 +34,92 @@ class FormController extends Controller
|
|||
return view('forms.create');
|
||||
}
|
||||
|
||||
public function togglePublish(Form $form)
|
||||
{
|
||||
$form->is_published = !$form->is_published;
|
||||
$form->save();
|
||||
|
||||
return redirect()->route('forms.show', $form->id)->with('success', 'Form publish status updated.');
|
||||
}
|
||||
|
||||
|
||||
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'));
|
||||
}
|
||||
|
||||
|
||||
public function createWithTemplate($template)
|
||||
{
|
||||
$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;
|
||||
|
||||
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'],
|
||||
],
|
||||
];
|
||||
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]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
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,short_answer,long_answer',
|
||||
'questions.*.text' => 'required|string', // This should match the key used in the JavaScript
|
||||
'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); // Default to false if not provided
|
||||
$form->is_published = $request->input('is_published', false);
|
||||
$form->user_id = Auth::id();
|
||||
$form->save();
|
||||
|
||||
|
@ -59,20 +127,24 @@ return view('forms.edit', compact('form', 'questions'));
|
|||
$question = new Question();
|
||||
$question->form_id = $form->id;
|
||||
$question->type = $questionData['type'];
|
||||
$question->question_text = $questionData['text']; // Ensure this matches the key in the validated data
|
||||
$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();
|
||||
}
|
||||
Session::flash('success', 'Form created successfully!');
|
||||
return response()->json(['success' => true, 'form_id' => $form->id]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
$form->load('questions.responses');
|
||||
|
||||
return view('forms.show', compact('form'));
|
||||
}
|
||||
|
||||
|
@ -98,7 +170,7 @@ return view('forms.edit', compact('form', 'questions'));
|
|||
'description' => 'nullable|string|max:255',
|
||||
'questions' => 'required|array',
|
||||
'questions.*.id' => 'nullable|exists:questions,id',
|
||||
'questions.*.type' => 'required|string|in:multiple_choice,checkbox,dropdown,short_answer,long_answer',
|
||||
'questions.*.type' => 'required|string|in:multiple_choice,checkbox,dropdown,text',
|
||||
'questions.*.text' => 'required|string|max:255',
|
||||
'questions.*.options' => 'nullable|array',
|
||||
'questions.*.options.*' => 'nullable|string|max:255',
|
||||
|
@ -130,7 +202,6 @@ return view('forms.edit', compact('form', 'questions'));
|
|||
$existingQuestionIds[] = $question->id;
|
||||
}
|
||||
|
||||
// Delete questions that were removed
|
||||
$form->questions()->whereNotIn('id', $existingQuestionIds)->delete();
|
||||
|
||||
Log::info('Remaining questions: ', $form->questions()->get()->toArray());
|
||||
|
@ -148,6 +219,8 @@ return view('forms.edit', compact('form', 'questions'));
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
public function destroy(Form $form)
|
||||
{
|
||||
// This will also delete all related questions and responses due to foreign key constraints
|
||||
|
|
|
@ -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;
|
||||
|
@ -21,30 +22,79 @@ class ResponseController extends Controller
|
|||
return view('responses.index', compact('form', 'responses'));
|
||||
}
|
||||
|
||||
// Display a specific response
|
||||
public function showSuccess(Form $form)
|
||||
{
|
||||
return view('responses.success', compact('form'));
|
||||
}
|
||||
|
||||
|
||||
|
||||
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');
|
||||
|
||||
return view('responses.viewResponse', compact('form', 'responses', 'questions'));
|
||||
|
||||
$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'));
|
||||
}
|
||||
|
||||
|
||||
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');
|
||||
|
||||
return view('responses.viewResponses', compact('form', 'responses'));
|
||||
|
||||
$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)
|
||||
{
|
||||
|
@ -58,23 +108,38 @@ 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());
|
||||
|
||||
|
||||
$questions = $form->questions;
|
||||
|
||||
|
||||
$requiredQuestionIds = $questions->where('required', true)->pluck('id')->toArray();
|
||||
|
||||
|
||||
// Validate and process form submission
|
||||
$validatedData = $request->validate([
|
||||
'answers' => 'required|array',
|
||||
'answers.*' => 'required',
|
||||
]);
|
||||
|
||||
Log::info($validatedData); // Log the validated data for debugging
|
||||
|
||||
// Generate a UUID for response_id
|
||||
foreach ($requiredQuestionIds as $requiredQuestionId) {
|
||||
if (!isset($validatedData['answers'][$requiredQuestionId]) || empty($validatedData['answers'][$requiredQuestionId])) {
|
||||
return redirect()->back()
|
||||
->withErrors(['errors' => 'Please answer all required questions.'])
|
||||
->withInput();
|
||||
}
|
||||
}
|
||||
|
||||
Log::info($validatedData);
|
||||
|
||||
|
||||
$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->response_id = $responseId;
|
||||
$response->question_id = $questionId;
|
||||
$response->form_id = $form->id;
|
||||
$response->user_id = auth()->id();
|
||||
|
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
0
database/migrations/2014_10_12_100000_create_password_reset_tokens_table.php
Normal file → Executable file
0
database/migrations/2014_10_12_100000_create_password_resets_table.php
Normal file → Executable file
0
database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php
Normal file → Executable file
|
@ -14,8 +14,9 @@ return new class extends Migration
|
|||
Schema::create('questions', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('form_id')->constrained()->onDelete('cascade');
|
||||
$table->enum('type', ['multiple_choice', 'checkbox', 'dropdown', 'short_answer', 'long_answer']);
|
||||
$table->enum('type', ['multiple_choice', 'checkbox', 'dropdown', 'text']);
|
||||
$table->text('question_text');
|
||||
$table->boolean('required')->default(false);
|
||||
$table->json('options')->nullable(); // Store options as JSON if applicable
|
||||
$table->timestamps();
|
||||
});
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
"vite": "^5.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"sweetalert": "^2.1.2"
|
||||
"sweetalert": "^2.1.2",
|
||||
"toastr": "^2.1.4"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,10 @@
|
|||
background-color: #fff;
|
||||
}
|
||||
|
||||
input:focus, textarea:focus, select:focus{
|
||||
outline: none;
|
||||
}
|
||||
|
||||
#moveableDiv {
|
||||
transition: transform 1s ease;
|
||||
}
|
||||
|
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 959 B |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 5.9 KiB |
Before Width: | Height: | Size: 8.5 KiB After Width: | Height: | Size: 8.5 KiB |
Before Width: | Height: | Size: 6.7 KiB After Width: | Height: | Size: 6.7 KiB |
Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 6.3 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 623 B After Width: | Height: | Size: 623 B |
Before Width: | Height: | Size: 8.5 KiB After Width: | Height: | Size: 8.5 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
|
@ -1,216 +1,3 @@
|
|||
// document.addEventListener("DOMContentLoaded", function () {
|
||||
// const questionsSection = document.getElementById("questions_section");
|
||||
|
||||
// function addOption(button) {
|
||||
// const optionContainer = button.previousElementSibling;
|
||||
// const optionDiv = document.createElement("div");
|
||||
// optionDiv.className = "option";
|
||||
// optionDiv.innerHTML = `
|
||||
// <input type="text" class="form-control option-input" placeholder="New Option" />
|
||||
// <span class="delete-option" onclick="deleteOption(this)">✕</span>
|
||||
// `;
|
||||
// optionContainer.appendChild(optionDiv);
|
||||
// updateAddButtonPosition();
|
||||
// }
|
||||
|
||||
// function deleteOption(span) {
|
||||
// const optionDiv = span.parentElement;
|
||||
// optionDiv.remove();
|
||||
// updateAddButtonPosition();
|
||||
// }
|
||||
|
||||
// function changeQuestionType(select) {
|
||||
// const questionInput = select.nextElementSibling;
|
||||
// questionInput.style.display = "block";
|
||||
// const optionsContainer = select.nextElementSibling.nextElementSibling;
|
||||
// optionsContainer.innerHTML =
|
||||
// '<input type="text" class="form-control option-input" placeholder="Option 1">';
|
||||
// }
|
||||
|
||||
// let questionCount = document.querySelectorAll(".question").length;
|
||||
|
||||
// function addNewQuestion() {
|
||||
// const newQuestionDiv = document.createElement("div");
|
||||
// newQuestionDiv.className = "question";
|
||||
// newQuestionDiv.innerHTML = `
|
||||
// <select class="form-control question_type" 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" class="form-control question-input" placeholder="Type your question here" />
|
||||
// <div class="options-container">
|
||||
// <div class="option">
|
||||
// <input type="text" class="form-control option-input" placeholder="Option 1" />
|
||||
// <span class="delete-option" onclick="deleteOption(this)">✕</span>
|
||||
// </div>
|
||||
// </div>
|
||||
// <button class="btn btn-secondary" onclick="addOption(this)">Add Option</button>
|
||||
// <button class="btnn" onclick="deleteQuestion(this)">
|
||||
// <img src="public/images/bin.png" alt="" width="20px" height="20px" />
|
||||
// </button>
|
||||
// `;
|
||||
// questionsSection.appendChild(newQuestionDiv);
|
||||
// questionCount++;
|
||||
// updateAddButtonPosition();
|
||||
// }
|
||||
|
||||
// function saveForm() {
|
||||
// const formTitle = document.getElementById("form-title").value;
|
||||
// const formDescription =
|
||||
// document.getElementById("form-description").value;
|
||||
// const questions = document.querySelectorAll(".question");
|
||||
// let formData = [];
|
||||
|
||||
// questions.forEach((question, index) => {
|
||||
// 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, // Ensure this matches the key in the PHP validation
|
||||
// options: options,
|
||||
// });
|
||||
// });
|
||||
|
||||
// // Get CSRF token
|
||||
// const csrfTokenMeta = document.querySelector('meta[name="csrf-token"]');
|
||||
// let csrfToken = "";
|
||||
// if (csrfTokenMeta) {
|
||||
// csrfToken = csrfTokenMeta.getAttribute("content");
|
||||
// } else {
|
||||
// console.error("CSRF token meta tag not found.");
|
||||
// // Handle the error condition gracefully or abort further execution
|
||||
// return;
|
||||
// }
|
||||
|
||||
// const data = {
|
||||
// title: formTitle,
|
||||
// description: formDescription,
|
||||
// questions: formData,
|
||||
// };
|
||||
|
||||
// console.log("Form Data:", data); // Log form data
|
||||
// console.log("CSRF Token:", csrfToken); // Log CSRF token
|
||||
|
||||
// // Send AJAX request to save the form data
|
||||
// fetch("/forms", {
|
||||
// method: "POST",
|
||||
// headers: {
|
||||
// "Content-Type": "application/json",
|
||||
// "X-CSRF-TOKEN": csrfToken,
|
||||
// },
|
||||
// body: JSON.stringify(data),
|
||||
// })
|
||||
// .then((response) => {
|
||||
// if (!response.ok) {
|
||||
// throw new Error("Network response was not ok");
|
||||
// }
|
||||
// return response.json();
|
||||
// })
|
||||
// .then((result) => {
|
||||
// console.log("Server Response:", result); // Log server response
|
||||
// if (result.success) {
|
||||
// alert("Form saved successfully!");
|
||||
// window.location.href = "/forms"; // Redirect to forms index page
|
||||
// } else {
|
||||
// alert("Failed to save form.");
|
||||
// }
|
||||
// })
|
||||
// .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;
|
||||
// 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, index) => {
|
||||
// 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';
|
||||
// };
|
||||
|
||||
// window.addNewQuestion = addNewQuestion;
|
||||
// window.deleteQuestion = deleteQuestion;
|
||||
// window.addOption = addOption;
|
||||
// window.changeQuestionType = changeQuestionType;
|
||||
// });
|
||||
|
||||
// function deleteQuestion(element) {
|
||||
// let questionContainer = element.closest(".question");
|
||||
// if (questionContainer) {
|
||||
// questionContainer.remove();
|
||||
// updateAddButtonPosition();
|
||||
// }
|
||||
// }
|
||||
|
||||
// function deleteOption(span) {
|
||||
// const optionDiv = span.parentElement;
|
||||
// optionDiv.remove();
|
||||
// updateAddButtonPosition();
|
||||
// }
|
||||
|
||||
// function updateAddButtonPosition() {
|
||||
// const questionsSection = document.getElementById("questions_section");
|
||||
// const lastQuestion = questionsSection.lastElementChild;
|
||||
|
||||
// // Check if lastQuestion exists before accessing its properties
|
||||
// if (lastQuestion) {
|
||||
// const selectQuestionType = lastQuestion.querySelector(".question_type");
|
||||
|
||||
// // Ensure selectQuestionType is not null before accessing offsetTop
|
||||
// if (selectQuestionType) {
|
||||
// const sidebar = document.getElementById("moveableDiv");
|
||||
// const offset = selectQuestionType.offsetTop - sidebar.offsetHeight;
|
||||
// sidebar.style.transform = `translateY(${offset}px)`;
|
||||
// console.log(`Moving sidebar to: ${offset}px`);
|
||||
// } else {
|
||||
// console.warn("No .question_type found in last question.");
|
||||
// }
|
||||
// } else {
|
||||
// const sidebar = document.getElementById("moveableDiv");
|
||||
// sidebar.style.transform = `translateY(0px)`;
|
||||
// console.log(`Moving sidebar to: 0px`);
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
const questionsSection = document.getElementById("questions_section");
|
||||
|
||||
|
@ -233,40 +20,62 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||
updateAddButtonPosition();
|
||||
}
|
||||
|
||||
function changeQuestionType(select) {
|
||||
const questionInput = select.nextElementSibling;
|
||||
questionInput.style.display = "block";
|
||||
const optionsContainer = select.nextElementSibling.nextElementSibling;
|
||||
optionsContainer.innerHTML =
|
||||
'<input type="text" class="form-control option-input" placeholder="Option 1">';
|
||||
function changeQuestionType(selectElement) {
|
||||
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 = "";
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
let questionCount = document.querySelectorAll(".question").length;
|
||||
|
||||
function addNewQuestion() {
|
||||
const newQuestionDiv = document.createElement("div");
|
||||
newQuestionDiv.className = "question";
|
||||
// newQuestionDiv.className = "question";
|
||||
newQuestionDiv.innerHTML = `
|
||||
<div class="question mb-4 p-3 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 style="border:1px solid rgb(103,58,183);" value="">Select Question Type</option>
|
||||
<option value="multiple_choice">Multiple Choice</option>
|
||||
<option value="checkbox">Checkbox</option>
|
||||
<option value="dropdown">Dropdown</option>
|
||||
<option value="text">Text</option>
|
||||
</select>
|
||||
<input type="text" name="question" class="form-control question-input mb-3" placeholder="Type your question here" />
|
||||
<input style="border:none; border-bottom: 2px solid rgb(103,58,183); border-radius:0" 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;">✕</span>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<button class="btn btn-secondary" onclick="addOption(this)">
|
||||
<button class="btn btn-secondary add-option-btn" onclick="addOption(this)">
|
||||
Add Option
|
||||
</button>
|
||||
<button class="btn btn-md" id="moveUpButton" onclick="deleteQuestion(this);">
|
||||
<img src="/images/bin.png" alt="" width="20px" height="20px" />
|
||||
</button>
|
||||
<label class="ml-3">
|
||||
<input type="checkbox" class="required-checkbox"> Required
|
||||
</label>
|
||||
</div>
|
||||
`;
|
||||
questionsSection.appendChild(newQuestionDiv);
|
||||
|
@ -301,7 +110,9 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||
sidebar.style.transform = `translateY(${newPosition}px)`;
|
||||
console.log(`Moving sidebar to: ${newPosition}px`);
|
||||
} else {
|
||||
sidebar.style.transform = `translateY(${containerHeight - sidebarHeight}px)`;
|
||||
sidebar.style.transform = `translateY(${
|
||||
containerHeight - sidebarHeight
|
||||
}px)`;
|
||||
console.log(`Moving sidebar to bottom of container`);
|
||||
}
|
||||
} else {
|
||||
|
@ -312,18 +123,43 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||
|
||||
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 = [];
|
||||
|
||||
questions.forEach((question, index) => {
|
||||
console.log(questions);
|
||||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
formData.push({
|
||||
type: questionType,
|
||||
text: questionText,
|
||||
options: options,
|
||||
required: isRequired,
|
||||
});
|
||||
|
||||
console.log({
|
||||
type: questionType,
|
||||
text: questionText,
|
||||
options: options,
|
||||
required: isRequired,
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -342,8 +178,7 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||
questions: formData,
|
||||
};
|
||||
|
||||
console.log("Form Data:", data);
|
||||
console.log("CSRF Token:", csrfToken);
|
||||
console.log(data);
|
||||
|
||||
fetch("/forms", {
|
||||
method: "POST",
|
||||
|
@ -353,19 +188,26 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||
},
|
||||
body: JSON.stringify(data),
|
||||
})
|
||||
.then((response) => {
|
||||
if (!response.ok) {
|
||||
throw new Error("Network response was not ok");
|
||||
}
|
||||
return response.json();
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then((result) => {
|
||||
console.log("Server Response:", result);
|
||||
if (result.success) {
|
||||
alert("Form saved successfully!");
|
||||
Swal.fire({
|
||||
title: "Success!",
|
||||
text: "Form saved successfully.",
|
||||
icon: "success",
|
||||
confirmButtonText: "OK",
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
window.location.href = "/forms";
|
||||
}
|
||||
});
|
||||
} else {
|
||||
alert("Failed to save form.");
|
||||
Swal.fire({
|
||||
title: "Error!",
|
||||
text: "Failed to save form.",
|
||||
icon: "error",
|
||||
confirmButtonText: "OK",
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
|
@ -381,36 +223,12 @@ 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 = [];
|
||||
// document.getElementById("add-question-button").addEventListener("click", addNewQuestion);
|
||||
|
||||
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,
|
||||
document
|
||||
.getElementById("questions_section")
|
||||
.addEventListener("DOMNodeInserted", updateAddButtonPosition);
|
||||
document
|
||||
.getElementById("questions_section")
|
||||
.addEventListener("DOMNodeRemoved", updateAddButtonPosition);
|
||||
});
|
||||
});
|
||||
|
||||
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("questions_section").addEventListener("DOMNodeInserted", updateAddButtonPosition);
|
||||
document.getElementById("questions_section").addEventListener("DOMNodeRemoved", updateAddButtonPosition);
|
||||
});
|
||||
|
||||
|
|