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
|
<?php
|
||||||
|
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use App\Models\Form;
|
use App\Models\Form;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
|
@ -9,13 +10,23 @@ use App\Models\Response;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
use Illuminate\Support\Facades\Session;
|
use Illuminate\Support\Facades\Session;
|
||||||
|
use Illuminate\Validation\Rules\Unique;
|
||||||
|
|
||||||
class FormController extends Controller
|
class FormController extends Controller
|
||||||
{
|
{
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
// Get forms belonging to the authenticated user
|
$totalForms = Form::count();
|
||||||
$forms = Form::where('user_id', Auth::id())->get();
|
$publishedForms = Form::where('is_published', true)->count();
|
||||||
return view('forms.index', compact('forms'));
|
$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()
|
public function create()
|
||||||
|
@ -23,35 +34,92 @@ class FormController extends Controller
|
||||||
return view('forms.create');
|
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)
|
public function edit(Form $form)
|
||||||
{
|
{
|
||||||
// Questions are already fetched with their options cast to array due to the casts property
|
|
||||||
$questions = $form->questions;
|
$questions = $form->questions;
|
||||||
foreach ($questions as $question) {
|
foreach ($questions as $question) {
|
||||||
$question->options = json_decode($question->options, true);
|
$question->options = json_decode($question->options, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pass the questions to the view
|
|
||||||
return view('forms.edit', compact('form', 'questions'));
|
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)
|
public function store(Request $request)
|
||||||
{
|
{
|
||||||
|
try {
|
||||||
$validatedData = $request->validate([
|
$validatedData = $request->validate([
|
||||||
'title' => 'required|string|max:255',
|
'title' => 'required|string|max:255',
|
||||||
'description' => 'nullable|string',
|
'description' => 'nullable|string',
|
||||||
'questions' => 'required|array',
|
'questions' => 'required|array',
|
||||||
'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', // This should match the key used in the JavaScript
|
'questions.*.text' => 'required|string',
|
||||||
'questions.*.options' => 'nullable|array',
|
'questions.*.options' => 'nullable|array',
|
||||||
|
'questions.*.required' => 'nullable|boolean',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
||||||
$form = new Form();
|
$form = new Form();
|
||||||
$form->title = $validatedData['title'];
|
$form->title = $validatedData['title'];
|
||||||
$form->description = $validatedData['description'];
|
$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->user_id = Auth::id();
|
||||||
$form->save();
|
$form->save();
|
||||||
|
|
||||||
|
@ -59,20 +127,24 @@ return view('forms.edit', compact('form', 'questions'));
|
||||||
$question = new Question();
|
$question = new Question();
|
||||||
$question->form_id = $form->id;
|
$question->form_id = $form->id;
|
||||||
$question->type = $questionData['type'];
|
$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->options = isset($questionData['options']) ? json_encode($questionData['options']) : null;
|
||||||
|
$question->required = isset($questionData['required']) ? $questionData['required'] : false;
|
||||||
$question->save();
|
$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)
|
public function show(Form $form)
|
||||||
{
|
{
|
||||||
$form->load('questions.responses');
|
$form->load('questions.responses');
|
||||||
|
|
||||||
return view('forms.show', compact('form'));
|
return view('forms.show', compact('form'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,7 +170,7 @@ return view('forms.edit', compact('form', 'questions'));
|
||||||
'description' => 'nullable|string|max:255',
|
'description' => 'nullable|string|max:255',
|
||||||
'questions' => 'required|array',
|
'questions' => 'required|array',
|
||||||
'questions.*.id' => 'nullable|exists:questions,id',
|
'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.*.text' => 'required|string|max:255',
|
||||||
'questions.*.options' => 'nullable|array',
|
'questions.*.options' => 'nullable|array',
|
||||||
'questions.*.options.*' => 'nullable|string|max:255',
|
'questions.*.options.*' => 'nullable|string|max:255',
|
||||||
|
@ -130,7 +202,6 @@ return view('forms.edit', compact('form', 'questions'));
|
||||||
$existingQuestionIds[] = $question->id;
|
$existingQuestionIds[] = $question->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete questions that were removed
|
|
||||||
$form->questions()->whereNotIn('id', $existingQuestionIds)->delete();
|
$form->questions()->whereNotIn('id', $existingQuestionIds)->delete();
|
||||||
|
|
||||||
Log::info('Remaining questions: ', $form->questions()->get()->toArray());
|
Log::info('Remaining questions: ', $form->questions()->get()->toArray());
|
||||||
|
@ -148,6 +219,8 @@ return view('forms.edit', compact('form', 'questions'));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public function destroy(Form $form)
|
public function destroy(Form $form)
|
||||||
{
|
{
|
||||||
// This will also delete all related questions and responses due to foreign key constraints
|
// 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
|
class HomeController extends Controller
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* Create a new controller instance.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->middleware('auth');
|
$this->middleware('auth');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Show the application dashboard.
|
|
||||||
*
|
|
||||||
* @return \Illuminate\Contracts\Support\Renderable
|
|
||||||
*/
|
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
return view('forms.index');
|
return view('forms.index');
|
||||||
|
|
|
@ -17,14 +17,14 @@ class QuestionController extends Controller
|
||||||
|
|
||||||
public function store(Form $form, Request $request)
|
public function store(Form $form, Request $request)
|
||||||
{
|
{
|
||||||
// Validate question data
|
|
||||||
$validatedData = $request->validate([
|
$validatedData = $request->validate([
|
||||||
'type' => 'required|string|in:multiple_choice,checkbox,dropdown,short_answer,long_answer',
|
'type' => 'required|string|in:multiple_choice,checkbox,dropdown,short_answer,long_answer',
|
||||||
'question_text' => 'required|string',
|
'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 = new Question();
|
||||||
$question->form_id = $form->id;
|
$question->form_id = $form->id;
|
||||||
$question->type = $validatedData['type'];
|
$question->type = $validatedData['type'];
|
||||||
|
@ -42,14 +42,14 @@ class QuestionController extends Controller
|
||||||
|
|
||||||
public function update(Form $form, Question $question, Request $request)
|
public function update(Form $form, Question $question, Request $request)
|
||||||
{
|
{
|
||||||
// Validate updated question data
|
|
||||||
$validatedData = $request->validate([
|
$validatedData = $request->validate([
|
||||||
'type' => 'required|string|in:multiple_choice,checkbox,dropdown,short_answer,long_answer',
|
'type' => 'required|string|in:multiple_choice,checkbox,dropdown,short_answer,long_answer',
|
||||||
'question_text' => 'required|string',
|
'question_text' => 'required|string',
|
||||||
'options' => 'nullable|array', // If needed based on question type
|
'options' => 'nullable|array',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Update question details
|
|
||||||
$question->type = $validatedData['type'];
|
$question->type = $validatedData['type'];
|
||||||
$question->question_text = $validatedData['question_text'];
|
$question->question_text = $validatedData['question_text'];
|
||||||
$question->options = $validatedData['options'] ?? null;
|
$question->options = $validatedData['options'] ?? null;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
use Ramsey\Uuid\Uuid;
|
use Ramsey\Uuid\Uuid;
|
||||||
use App\Models\Form;
|
use App\Models\Form;
|
||||||
|
@ -21,30 +22,79 @@ class ResponseController extends Controller
|
||||||
return view('responses.index', compact('form', 'responses'));
|
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)
|
public function viewResponse(Form $form, $responseId)
|
||||||
{
|
{
|
||||||
// Get all responses with the same response_id
|
|
||||||
$responses = Response::where('response_id', $responseId)
|
$responses = Response::where('response_id', $responseId)
|
||||||
->where('form_id', $form->id)
|
->where('form_id', $form->id)
|
||||||
->get();
|
->get();
|
||||||
|
|
||||||
// Get all questions for the form
|
|
||||||
$questions = Question::where('form_id', $form->id)->get()->keyBy('id');
|
$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)
|
public function viewResponses(Form $form)
|
||||||
{
|
{
|
||||||
// Get all responses for the form, grouped by response_id
|
|
||||||
$responses = Response::where('form_id', $form->id)
|
$responses = Response::where('form_id', $form->id)
|
||||||
->orderBy('submitted_at', 'desc')
|
->orderBy('submitted_at', 'desc')
|
||||||
->get()
|
->get()
|
||||||
->groupBy('response_id');
|
->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)
|
public function showForm(Form $form)
|
||||||
{
|
{
|
||||||
|
@ -58,23 +108,38 @@ public function viewResponses(Form $form)
|
||||||
|
|
||||||
public function submitForm(Request $request, 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([
|
$validatedData = $request->validate([
|
||||||
'answers' => 'required|array',
|
'answers' => 'required|array',
|
||||||
'answers.*' => 'required',
|
'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();
|
$responseId = Uuid::uuid4()->toString();
|
||||||
|
|
||||||
// Save each question's response
|
|
||||||
foreach ($validatedData['answers'] as $questionId => $answer) {
|
foreach ($validatedData['answers'] as $questionId => $answer) {
|
||||||
$response = new Response();
|
$response = new Response();
|
||||||
$response->response_id = $responseId; // Assign the generated UUID
|
$response->response_id = $responseId;
|
||||||
$response->question_id = $questionId;
|
$response->question_id = $questionId;
|
||||||
$response->form_id = $form->id;
|
$response->form_id = $form->id;
|
||||||
$response->user_id = auth()->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) {
|
Schema::create('questions', function (Blueprint $table) {
|
||||||
$table->id();
|
$table->id();
|
||||||
$table->foreignId('form_id')->constrained()->onDelete('cascade');
|
$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->text('question_text');
|
||||||
|
$table->boolean('required')->default(false);
|
||||||
$table->json('options')->nullable(); // Store options as JSON if applicable
|
$table->json('options')->nullable(); // Store options as JSON if applicable
|
||||||
$table->timestamps();
|
$table->timestamps();
|
||||||
});
|
});
|
||||||
|
|
|
@ -5,7 +5,8 @@
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"sweetalert": "^2.1.2"
|
"sweetalert": "^2.1.2",
|
||||||
|
"toastr": "^2.1.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@popperjs/core": "^2.11.6",
|
"@popperjs/core": "^2.11.6",
|
||||||
|
@ -889,6 +890,11 @@
|
||||||
"node": ">=0.12.0"
|
"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": {
|
"node_modules/laravel-vite-plugin": {
|
||||||
"version": "1.0.5",
|
"version": "1.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/laravel-vite-plugin/-/laravel-vite-plugin-1.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/laravel-vite-plugin/-/laravel-vite-plugin-1.0.5.tgz",
|
||||||
|
@ -1107,6 +1113,14 @@
|
||||||
"node": ">=8.0"
|
"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": {
|
"node_modules/vite": {
|
||||||
"version": "5.3.3",
|
"version": "5.3.3",
|
||||||
"resolved": "https://registry.npmjs.org/vite/-/vite-5.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/vite/-/vite-5.3.3.tgz",
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
"vite": "^5.0.0"
|
"vite": "^5.0.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"sweetalert": "^2.1.2"
|
"sweetalert": "^2.1.2",
|
||||||
|
"toastr": "^2.1.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,10 @@
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input:focus, textarea:focus, select:focus{
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
#moveableDiv {
|
#moveableDiv {
|
||||||
transition: transform 1s ease;
|
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 () {
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
const questionsSection = document.getElementById("questions_section");
|
const questionsSection = document.getElementById("questions_section");
|
||||||
|
|
||||||
|
@ -233,40 +20,62 @@ document.addEventListener("DOMContentLoaded", function () {
|
||||||
updateAddButtonPosition();
|
updateAddButtonPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeQuestionType(select) {
|
function changeQuestionType(selectElement) {
|
||||||
const questionInput = select.nextElementSibling;
|
const questionContainer = selectElement.closest(".question");
|
||||||
questionInput.style.display = "block";
|
const optionsContainer =
|
||||||
const optionsContainer = select.nextElementSibling.nextElementSibling;
|
questionContainer.querySelector(".options-container");
|
||||||
optionsContainer.innerHTML =
|
const addOptionButton =
|
||||||
'<input type="text" class="form-control option-input" placeholder="Option 1">';
|
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;
|
let questionCount = document.querySelectorAll(".question").length;
|
||||||
|
|
||||||
function addNewQuestion() {
|
function addNewQuestion() {
|
||||||
const newQuestionDiv = document.createElement("div");
|
const newQuestionDiv = document.createElement("div");
|
||||||
newQuestionDiv.className = "question";
|
// newQuestionDiv.className = "question";
|
||||||
newQuestionDiv.innerHTML = `
|
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)">
|
<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="multiple_choice">Multiple Choice</option>
|
||||||
<option value="checkbox">Checkbox</option>
|
<option value="checkbox">Checkbox</option>
|
||||||
<option value="dropdown">Dropdown</option>
|
<option value="dropdown">Dropdown</option>
|
||||||
|
<option value="text">Text</option>
|
||||||
</select>
|
</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="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>
|
||||||
</div>
|
<button class="btn btn-secondary add-option-btn" onclick="addOption(this)">
|
||||||
<button class="btn btn-secondary" onclick="addOption(this)">
|
|
||||||
Add Option
|
Add Option
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-md" id="moveUpButton" onclick="deleteQuestion(this);">
|
<button class="btn btn-md" id="moveUpButton" onclick="deleteQuestion(this);">
|
||||||
<img src="/images/bin.png" alt="" width="20px" height="20px" />
|
<img src="/images/bin.png" alt="" width="20px" height="20px" />
|
||||||
</button>
|
</button>
|
||||||
|
<label class="ml-3">
|
||||||
|
<input type="checkbox" class="required-checkbox"> Required
|
||||||
|
</label>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
questionsSection.appendChild(newQuestionDiv);
|
questionsSection.appendChild(newQuestionDiv);
|
||||||
|
@ -301,7 +110,9 @@ document.addEventListener("DOMContentLoaded", function () {
|
||||||
sidebar.style.transform = `translateY(${newPosition}px)`;
|
sidebar.style.transform = `translateY(${newPosition}px)`;
|
||||||
console.log(`Moving sidebar to: ${newPosition}px`);
|
console.log(`Moving sidebar to: ${newPosition}px`);
|
||||||
} else {
|
} else {
|
||||||
sidebar.style.transform = `translateY(${containerHeight - sidebarHeight}px)`;
|
sidebar.style.transform = `translateY(${
|
||||||
|
containerHeight - sidebarHeight
|
||||||
|
}px)`;
|
||||||
console.log(`Moving sidebar to bottom of container`);
|
console.log(`Moving sidebar to bottom of container`);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -312,18 +123,43 @@ document.addEventListener("DOMContentLoaded", function () {
|
||||||
|
|
||||||
function saveForm() {
|
function saveForm() {
|
||||||
const formTitle = document.getElementById("form-title").value;
|
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");
|
const questions = document.querySelectorAll(".question");
|
||||||
let formData = [];
|
let formData = [];
|
||||||
|
|
||||||
questions.forEach((question, index) => {
|
console.log(questions);
|
||||||
|
|
||||||
|
questions.forEach((question) => {
|
||||||
const questionType = question.querySelector("select").value;
|
const questionType = question.querySelector("select").value;
|
||||||
const questionText = question.querySelector(".question-input").value;
|
const questionText =
|
||||||
const options = Array.from(question.querySelectorAll(".option-input")).map((input) => input.value);
|
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({
|
formData.push({
|
||||||
type: questionType,
|
type: questionType,
|
||||||
text: questionText,
|
text: questionText,
|
||||||
options: options,
|
options: options,
|
||||||
|
required: isRequired,
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log({
|
||||||
|
type: questionType,
|
||||||
|
text: questionText,
|
||||||
|
options: options,
|
||||||
|
required: isRequired,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -342,8 +178,7 @@ document.addEventListener("DOMContentLoaded", function () {
|
||||||
questions: formData,
|
questions: formData,
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log("Form Data:", data);
|
console.log(data);
|
||||||
console.log("CSRF Token:", csrfToken);
|
|
||||||
|
|
||||||
fetch("/forms", {
|
fetch("/forms", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
|
@ -353,19 +188,26 @@ document.addEventListener("DOMContentLoaded", function () {
|
||||||
},
|
},
|
||||||
body: JSON.stringify(data),
|
body: JSON.stringify(data),
|
||||||
})
|
})
|
||||||
.then((response) => {
|
.then((response) => response.json())
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error("Network response was not ok");
|
|
||||||
}
|
|
||||||
return response.json();
|
|
||||||
})
|
|
||||||
.then((result) => {
|
.then((result) => {
|
||||||
console.log("Server Response:", result);
|
|
||||||
if (result.success) {
|
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";
|
window.location.href = "/forms";
|
||||||
|
}
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
alert("Failed to save form.");
|
Swal.fire({
|
||||||
|
title: "Error!",
|
||||||
|
text: "Failed to save form.",
|
||||||
|
icon: "error",
|
||||||
|
confirmButtonText: "OK",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
|
@ -381,36 +223,12 @@ document.addEventListener("DOMContentLoaded", function () {
|
||||||
window.changeQuestionType = changeQuestionType;
|
window.changeQuestionType = changeQuestionType;
|
||||||
window.saveForm = saveForm;
|
window.saveForm = saveForm;
|
||||||
|
|
||||||
window.previewForm = function (formId) {
|
// document.getElementById("add-question-button").addEventListener("click", addNewQuestion);
|
||||||
const formTitle = document.getElementById("form-title").value;
|
|
||||||
const formDescription = document.getElementById("form-description").value;
|
|
||||||
const questions = document.querySelectorAll(".question");
|
|
||||||
let formData = [];
|
|
||||||
|
|
||||||
questions.forEach((question) => {
|
document
|
||||||
const questionType = question.querySelector("select").value;
|
.getElementById("questions_section")
|
||||||
const questionText = question.querySelector(".question-input").value;
|
.addEventListener("DOMNodeInserted", updateAddButtonPosition);
|
||||||
const options = Array.from(question.querySelectorAll(".option-input")).map((input) => input.value);
|
document
|
||||||
formData.push({
|
.getElementById("questions_section")
|
||||||
type: questionType,
|
.addEventListener("DOMNodeRemoved", updateAddButtonPosition);
|
||||||
text: questionText,
|
|
||||||
options: options,
|
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
const formParams = new URLSearchParams({
|
|
||||||
title: formTitle,
|
|
||||||
description: formDescription,
|
|
||||||
data: JSON.stringify(formData),
|
|
||||||
});
|
|
||||||
|
|
||||||
window.location.href = '/forms/' + formId + '/preview';
|
|
||||||
};
|
|
||||||
|
|
||||||
// Assuming there's a button with id "add-question-button"
|
|
||||||
document.getElementById("add-question-button").addEventListener("click", addNewQuestion);
|
|
||||||
|
|
||||||
document.getElementById("questions_section").addEventListener("DOMNodeInserted", updateAddButtonPosition);
|
|
||||||
document.getElementById("questions_section").addEventListener("DOMNodeRemoved", updateAddButtonPosition);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|